From e9e7135639a17a1e03efffdecc743854e9c47f88 Mon Sep 17 00:00:00 2001 From: wvengen Date: Mon, 8 Jul 2013 14:32:24 +0200 Subject: [PATCH 01/79] run bundle update and make it work again --- Gemfile | 27 ++-- Gemfile.lock | 126 ++++++++++-------- app/assets/javascripts/application.js | 14 +- .../bootstrap_and_overrides.css.less | 15 +-- .../initializers/client_side_validations.rb | 7 +- 5 files changed, 103 insertions(+), 86 deletions(-) diff --git a/Gemfile b/Gemfile index 9bec3431..1372c1cc 100644 --- a/Gemfile +++ b/Gemfile @@ -4,28 +4,29 @@ ruby "1.9.3" gem "rails", '~> 3.2.9' -# Gems used only for assets and not required -# in production environments by default. -group :assets do - gem 'sass-rails', '~> 3.2.3' - gem 'coffee-rails', '~> 3.2.1' - - # See https://github.com/sstephenson/execjs#readme for more supported runtimes - gem 'therubyracer', platforms: :ruby - - gem 'uglifier', '>= 1.0.3' -end - gem 'jquery-rails' gem 'bootstrap-datepicker-rails' +# Gems used only for assets and not required +# in production environments by default. +group :assets do + # See https://github.com/sstephenson/execjs#readme for more supported runtimes + gem 'therubyracer', platforms: :ruby + + gem 'sass-rails', '~> 3.2.3' + gem 'coffee-rails', '~> 3.2.1' + gem 'less-rails-bootstrap' + + gem 'uglifier', '>= 1.0.3' +end gem 'mysql2' gem 'prawn' gem 'haml-rails' gem 'kaminari' -gem 'client_side_validations' gem 'simple_form' +gem 'client_side_validations' +gem 'client_side_validations-simple_form' gem 'inherited_resources' gem 'localize_input', git: "git://github.com/bennibu/localize_input.git" gem 'wikicloth' diff --git a/Gemfile.lock b/Gemfile.lock index c10e145e..df5d8313 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -49,17 +49,19 @@ GEM activesupport (3.2.13) i18n (= 0.6.1) multi_json (~> 1.0) - acts_as_tree (1.2.0) + acts_as_tree (1.4.0) activerecord (>= 3.0.0) + afm (0.2.0) arel (3.0.2) - better_errors (0.2.0) + better_errors (0.9.0) coderay (>= 1.0.0) - erubis (>= 2.7.0) - binding_of_caller (0.6.8) + erubis (>= 2.6.6) + binding_of_caller (0.7.2) + debug_inspector (>= 0.0.1) bootstrap-datepicker-rails (1.1.1.1) railties (>= 3.0) builder (3.0.4) - bullet (4.3.0) + bullet (4.6.0) uniform_notifier capistrano (2.13.5) highline @@ -69,58 +71,65 @@ GEM net-ssh-gateway (>= 1.1.0) capistrano-ext (1.2.1) capistrano (>= 1.0.0) - chronic (0.9.0) - client_side_validations (3.1.4) - coderay (1.0.8) + chronic (0.9.1) + client_side_validations (3.2.5) + client_side_validations-simple_form (2.1.0) + client_side_validations (~> 3.2.5) + simple_form (~> 2.1.0) + coderay (1.0.9) coffee-rails (3.2.2) coffee-script (>= 2.2.0) railties (~> 3.2.0) coffee-script (2.2.0) coffee-script-source execjs - coffee-script-source (1.3.3) + coffee-script-source (1.6.3) commonjs (0.2.6) daemons (1.1.9) + debug_inspector (0.0.2) erubis (2.7.0) eventmachine (1.0.3) - exception_notification (2.6.1) + exception_notification (4.0.0) actionmailer (>= 3.0.4) + activesupport (>= 3.0.4) execjs (1.4.0) multi_json (~> 1.0) expression_parser (0.9.0) - haml (3.1.7) - haml-rails (0.3.5) + haml (4.0.3) + tilt + haml-rails (0.4) actionpack (>= 3.1, < 4.1) activesupport (>= 3.1, < 4.1) - haml (~> 3.1) + haml (>= 3.1, < 4.1) railties (>= 3.1, < 4.1) has_scope (0.5.1) - hashery (2.0.1) + hashery (2.1.0) highline (1.6.19) - hike (1.2.1) + hike (1.2.3) i18n (0.6.1) - inherited_resources (1.3.1) + inherited_resources (1.4.0) has_scope (~> 0.5.0) - responders (~> 0.6) + responders (~> 0.9) journey (1.0.4) - jquery-rails (2.1.3) - railties (>= 3.1.0, < 5.0) - thor (~> 0.14) - json (1.7.7) + jquery-rails (3.0.2) + railties (>= 3.0, < 5.0) + thor (>= 0.14, < 2.0) + json (1.8.0) kaminari (0.14.1) actionpack (>= 3.0.0) activesupport (>= 3.0.0) - less (2.2.2) + less (2.3.2) commonjs (~> 0.2.6) - less-rails (2.2.3) + less-rails (2.3.3) actionpack (>= 3.1) - less (~> 2.2.0) - libv8 (3.3.10.4) - mail (2.5.3) - i18n (>= 0.4.0) + less (~> 2.3.1) + less-rails-bootstrap (2.3.3) + less-rails (~> 2.3.1) + libv8 (3.11.8.17) + mail (2.5.4) mime-types (~> 1.16) treetop (~> 1.4.8) - mailcatcher (0.5.11) + mailcatcher (0.5.12) activesupport (~> 3.0) eventmachine (~> 1.0.0) haml (>= 3.1, < 5) @@ -134,21 +143,23 @@ GEM activerecord (~> 3.1) activesupport (~> 3.1) polyamorous (~> 0.5.0) - mime-types (1.21) + mime-types (1.23) mono_logger (1.1.0) - multi_json (1.7.3) + multi_json (1.7.7) mysql2 (0.3.11) - net-scp (1.1.1) + net-scp (1.1.2) net-ssh (>= 2.6.5) net-sftp (2.1.2) net-ssh (>= 2.6.5) - net-ssh (2.6.7) + net-ssh (2.6.8) net-ssh-gateway (1.2.0) net-ssh (>= 2.6.5) - pdf-reader (1.2.0) + pdf-reader (1.3.3) Ascii85 (~> 1.0.0) + afm (~> 0.2.0) hashery (~> 2.0) ruby-rc4 + ttfunk polyamorous (0.5.0) activerecord (~> 3.0) polyglot (0.3.3) @@ -181,12 +192,13 @@ GEM rake (>= 0.8.7) rdoc (~> 3.4) thor (>= 0.14.6, < 2.0) - rake (10.0.3) + rake (10.1.0) rdoc (3.12.2) json (~> 1.4) redis (3.0.4) redis-namespace (1.3.0) redis (~> 3.0.0) + ref (1.0.5) responders (0.9.3) railties (~> 3.1) resque (1.24.1) @@ -195,24 +207,25 @@ GEM redis-namespace (~> 1.2) sinatra (>= 0.9.2) vegas (~> 0.1.2) - ruby-prof (0.11.2) + ruby-prof (0.13.0) ruby-rc4 (0.1.5) - sass (3.2.1) - sass-rails (3.2.5) + sass (3.2.9) + sass-rails (3.2.6) railties (~> 3.2.0) sass (>= 3.1.10) tilt (~> 1.3) - simple-navigation (3.9.0) + simple-navigation (3.11.0) activesupport (>= 2.3.2) - simple-navigation-bootstrap (0.0.4) + simple-navigation-bootstrap (1.0.0) + railties (>= 3.1) simple-navigation (>= 3.7.0) - simple_form (2.0.3) + simple_form (2.1.0) actionpack (~> 3.0) activemodel (~> 3.0) - sinatra (1.3.6) + sinatra (1.4.3) rack (~> 1.4) - rack-protection (~> 1.3) - tilt (~> 1.3, >= 1.3.3) + rack-protection (~> 1.4) + tilt (~> 1.3, >= 1.3.4) skinny (0.2.3) eventmachine (~> 1.0.0) thin (~> 1.5.0) @@ -221,33 +234,34 @@ GEM multi_json (~> 1.0) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) - sqlite3 (1.3.6) - test-unit (2.5.3) - therubyracer (0.10.2) - libv8 (~> 3.3.10) + sqlite3 (1.3.7) + test-unit (2.5.5) + therubyracer (0.11.4) + libv8 (~> 3.11.8.12) + ref thin (1.5.1) daemons (>= 1.0.9) eventmachine (>= 0.12.6) rack (>= 1.0.0) - thor (0.17.0) + thor (0.18.1) tilt (1.4.1) - treetop (1.4.12) + treetop (1.4.14) polyglot polyglot (>= 0.3.1) ttfunk (1.0.3) - twitter-bootstrap-rails (2.1.3) + twitter-bootstrap-rails (2.2.7) actionpack (>= 3.1) - less-rails (~> 2.2.3) + execjs + rails (>= 3.1) railties (>= 3.1) - therubyracer (~> 0.10.2) tzinfo (0.3.37) - uglifier (1.3.0) + uglifier (2.1.1) execjs (>= 0.3.0) multi_json (~> 1.0, >= 1.0.2) - uniform_notifier (1.1.1) + uniform_notifier (1.2.0) vegas (0.1.11) rack (>= 1.0.0) - whenever (0.8.1) + whenever (0.8.2) activesupport (>= 2.3.4) chronic (>= 0.6.3) wikicloth (0.8.0) @@ -268,6 +282,7 @@ DEPENDENCIES capistrano (= 2.13.5) capistrano-ext client_side_validations + client_side_validations-simple_form coffee-rails (~> 3.2.1) daemons exception_notification @@ -275,6 +290,7 @@ DEPENDENCIES inherited_resources jquery-rails kaminari + less-rails-bootstrap localize_input! mailcatcher meta_search diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index cf650243..f0645ea1 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -1,5 +1,4 @@ //= require jquery -//= require jquery-ui //= require jquery_ujs //= require twitter/bootstrap //= require jquery.tokeninput @@ -8,6 +7,7 @@ //= require bootstrap-datepicker/locales/bootstrap-datepicker.nl //= require jquery.observe_field //= require rails.validations +//= require rails.validations.simple_form //= require_self //= require ordering @@ -28,19 +28,19 @@ $.fn.extend({ $(function() { // Show/Hide a specific DOM element - $('a[data-toggle-this]').live('click', function() { + $('a[data-toggle-this]').on('click', function() { $($(this).data('toggle-this')).toggle(); return false; }); // Remove this item from DOM - $('a[data-remove-this]').live('click', function() { + $('a[data-remove-this]').on('click', function() { $($(this).data('remove-this')).remove(); return false; }); // Check/Uncheck a single checkbox - $('[data-check-this]').live('click', function() { + $('[data-check-this]').on('click', function() { var checkbox = $($(this).data('check-this')); checkbox.attr('checked', !checkbox.is(':checked')); highlightRow(checkbox); @@ -48,7 +48,7 @@ $(function() { }); // Check/Uncheck all checkboxes for a specific form - $('input[data-check-all]').live('click', function() { + $('input[data-check-all]').on('click', function() { var status = $(this).is(':checked'); var context = $(this).data('check-all'); var elms = $('input[type="checkbox"]', context); @@ -60,7 +60,7 @@ $(function() { }); // Submit form when changing a select menu. - $('form[data-submit-onchange] select').live('change', function() { + $('form[data-submit-onchange] select').on('change', function() { var confirmMessage = $(this).children(':selected').data('confirm'); if (confirmMessage) { if (confirm(confirmMessage)) { @@ -93,7 +93,7 @@ $(function() { }); // Remote paginations - $('div.pagination[data-remote] a').live('click', function() { + $('div.pagination[data-remote] a').on('click', function() { $.getScript($(this).attr('href')); return false; }); diff --git a/app/assets/stylesheets/bootstrap_and_overrides.css.less b/app/assets/stylesheets/bootstrap_and_overrides.css.less index 58ac2122..b568fb71 100644 --- a/app/assets/stylesheets/bootstrap_and_overrides.css.less +++ b/app/assets/stylesheets/bootstrap_and_overrides.css.less @@ -10,15 +10,12 @@ body { @iconWhiteSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings-white.png'); // Set the Font Awesome (Font Awesome is default. You can disable by commenting below lines) -// Note: If you use asset_path() here, your compiled boostrap_and_overrides.css will not -// have the proper paths. So for now we use the absolute path. -@fontAwesomeEotPath: '/assets/fontawesome-webfont.eot'; -@fontAwesomeWoffPath: '/assets/fontawesome-webfont.woff'; -@fontAwesomeTtfPath: '/assets/fontawesome-webfont.ttf'; -@fontAwesomeSvgPath: '/assets/fontawesome-webfont.svg'; - -// Font Awesome -@import "fontawesome"; +@fontAwesomeEotPath: asset-url('fontawesome-webfont.eot'); +@fontAwesomeEotPath_iefix: asset-url('fontawesome-webfont.eot?#iefix'); +@fontAwesomeWoffPath: asset-url('fontawesome-webfont.woff'); +@fontAwesomeTtfPath: asset-url('fontawesome-webfont.ttf'); +@fontAwesomeSvgPath: asset-url('fontawesome-webfont.svg#fontawesomeregular'); +@import 'fontawesome/font-awesome'; // Your custom LESS stylesheets goes here // diff --git a/config/initializers/client_side_validations.rb b/config/initializers/client_side_validations.rb index caf18378..30e21d0d 100644 --- a/config/initializers/client_side_validations.rb +++ b/config/initializers/client_side_validations.rb @@ -1,7 +1,10 @@ # ClientSideValidations Initializer -require 'client_side_validations/simple_form' if defined?(::SimpleForm) -require 'client_side_validations/formtastic' if defined?(::Formtastic) +# Uncomment to disable uniqueness validator, possible security issue +# ClientSideValidations::Config.disabled_validators = [:uniqueness] + +# Uncomment to validate number format with current I18n locale +# ClientSideValidations::Config.number_format_with_locale = true # Uncomment the following block if you want each input field to have the validation messages attached. # ActionView::Base.field_error_proc = Proc.new do |html_tag, instance| From 33b27d2fa70abbab3476eb70071ed374622279f3 Mon Sep 17 00:00:00 2001 From: wvengen Date: Mon, 8 Jul 2013 22:41:06 +0200 Subject: [PATCH 02/79] proper usage of jQuery.on(), and update javascript in views as well --- app/assets/javascripts/application.js | 12 ++++++------ app/views/deliveries/_form.html.haml | 6 +++--- .../financial_transactions/new_collection.html.haml | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index f0645ea1..c5228350 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -28,19 +28,19 @@ $.fn.extend({ $(function() { // Show/Hide a specific DOM element - $('a[data-toggle-this]').on('click', function() { + $(document).on('click', 'a[data-toggle-this]', function() { $($(this).data('toggle-this')).toggle(); return false; }); // Remove this item from DOM - $('a[data-remove-this]').on('click', function() { + $(document).on('click', 'a[data-remove-this]', function() { $($(this).data('remove-this')).remove(); return false; }); // Check/Uncheck a single checkbox - $('[data-check-this]').on('click', function() { + $(document).on('click', '[data-check-this]', function() { var checkbox = $($(this).data('check-this')); checkbox.attr('checked', !checkbox.is(':checked')); highlightRow(checkbox); @@ -48,7 +48,7 @@ $(function() { }); // Check/Uncheck all checkboxes for a specific form - $('input[data-check-all]').on('click', function() { + $(document).on('click', 'input[data-check-all]', function() { var status = $(this).is(':checked'); var context = $(this).data('check-all'); var elms = $('input[type="checkbox"]', context); @@ -60,7 +60,7 @@ $(function() { }); // Submit form when changing a select menu. - $('form[data-submit-onchange] select').on('change', function() { + $(document).on('change', 'form[data-submit-onchange] select', function() { var confirmMessage = $(this).children(':selected').data('confirm'); if (confirmMessage) { if (confirm(confirmMessage)) { @@ -93,7 +93,7 @@ $(function() { }); // Remote paginations - $('div.pagination[data-remote] a').on('click', function() { + $(document).on('click', 'div.pagination[data-remote] a', function() { $.getScript($(this).attr('href')); return false; }); diff --git a/app/views/deliveries/_form.html.haml b/app/views/deliveries/_form.html.haml index 5eff702d..ba85b482 100644 --- a/app/views/deliveries/_form.html.haml +++ b/app/views/deliveries/_form.html.haml @@ -1,15 +1,15 @@ - content_for :javascript do :javascript $(function() { - $('.destroy_stock_change').live('click', function() { + $(document).on('click', '.destroy_stock_change', function() { $(this).prev('input').val('1').parent().hide(); return false; }); - $('.remove_new_stock_change').live('click', function() { + $(document).on('click', '.remove_new_stock_change', function() { $(this).parent().remove(); return false; - }) + }); }); = simple_form_for [@supplier, @delivery], validate: true do |f| diff --git a/app/views/finance/financial_transactions/new_collection.html.haml b/app/views/finance/financial_transactions/new_collection.html.haml index 324b118b..aaa67129 100644 --- a/app/views/finance/financial_transactions/new_collection.html.haml +++ b/app/views/finance/financial_transactions/new_collection.html.haml @@ -5,12 +5,12 @@ var ordergroup = "#{escape_javascript(render('ordergroup'))}" $(function() { - $('a[data-remove-transaction]').live('click', function() { + $(document).on('click', 'a[data-remove-transaction]', function() { $(this).parents('tr').remove(); return false; }); - $('a[data-add-transaction]').click(function() { + $(document).on('click', 'a[data-add-transaction]', function() { $('#ordergroups').append(ordergroup); return false; }); From cfae2791961c7b436cb0cff91f3c14e829c83ba3 Mon Sep 17 00:00:00 2001 From: wvengen Date: Fri, 12 Jul 2013 23:35:31 +0200 Subject: [PATCH 03/79] bundle update --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index df5d8313..a9f7a177 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -111,7 +111,7 @@ GEM has_scope (~> 0.5.0) responders (~> 0.9) journey (1.0.4) - jquery-rails (3.0.2) + jquery-rails (3.0.4) railties (>= 3.0, < 5.0) thor (>= 0.14, < 2.0) json (1.8.0) @@ -261,7 +261,7 @@ GEM uniform_notifier (1.2.0) vegas (0.1.11) rack (>= 1.0.0) - whenever (0.8.2) + whenever (0.8.3) activesupport (>= 2.3.4) chronic (>= 0.6.3) wikicloth (0.8.0) From fc6fbdaa95ecb9971ba71853b52efb40a8e669ed Mon Sep 17 00:00:00 2001 From: wvengen Date: Sat, 13 Jul 2013 23:06:30 +0200 Subject: [PATCH 04/79] use less-rails, and make exception_notifier work again --- Gemfile | 16 +++++++--------- Gemfile.lock | 4 +--- config/initializers/load_app_config.rb | 12 +++++++----- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/Gemfile b/Gemfile index 1372c1cc..04fa25f5 100644 --- a/Gemfile +++ b/Gemfile @@ -4,22 +4,20 @@ ruby "1.9.3" gem "rails", '~> 3.2.9' -gem 'jquery-rails' -gem 'bootstrap-datepicker-rails' - # Gems used only for assets and not required # in production environments by default. group :assets do - # See https://github.com/sstephenson/execjs#readme for more supported runtimes - gem 'therubyracer', platforms: :ruby - gem 'sass-rails', '~> 3.2.3' gem 'coffee-rails', '~> 3.2.1' - gem 'less-rails-bootstrap' - + gem 'less-rails' gem 'uglifier', '>= 1.0.3' + # See https://github.com/sstephenson/execjs#readme for more supported runtimes + gem 'therubyracer', platforms: :ruby end +gem 'jquery-rails' +gem 'bootstrap-datepicker-rails' + gem 'mysql2' gem 'prawn' gem 'haml-rails' @@ -42,7 +40,7 @@ gem 'resque' gem 'whenever', require: false # For defining cronjobs, see config/schedule.rb group :production do - gem 'exception_notification', require: 'exception_notifier' + gem 'exception_notification' end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index a9f7a177..8095b8e8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -123,8 +123,6 @@ GEM less-rails (2.3.3) actionpack (>= 3.1) less (~> 2.3.1) - less-rails-bootstrap (2.3.3) - less-rails (~> 2.3.1) libv8 (3.11.8.17) mail (2.5.4) mime-types (~> 1.16) @@ -290,7 +288,7 @@ DEPENDENCIES inherited_resources jquery-rails kaminari - less-rails-bootstrap + less-rails localize_input! mailcatcher meta_search diff --git a/config/initializers/load_app_config.rb b/config/initializers/load_app_config.rb index 1509536e..9501a48a 100644 --- a/config/initializers/load_app_config.rb +++ b/config/initializers/load_app_config.rb @@ -14,13 +14,15 @@ url_options.merge!({:port => FoodsoftConfig[:port]}) if FoodsoftConfig[:port] Foodsoft::Application.configure do config.action_mailer.default_url_options = url_options - if Rails.env !~ /development|test/ + if %w(production).include? Rails.env # Configuration of the exception_notification plugin # Mailadresses are set in config/app_config.yml - config.middleware.use ExceptionNotifier, - :email_prefix => FoodsoftConfig[:notification]['email_prefix'], - :sender_address => FoodsoftConfig[:notification]['sender_address'], - :exception_recipients => FoodsoftConfig[:notification]['error_recipients'] + config.middleware.use ExceptionNotification::Rack, + :email => { + :email_prefix => FoodsoftConfig[:notification]['email_prefix'], + :sender_address => FoodsoftConfig[:notification]['sender_address'], + :exception_recipients => FoodsoftConfig[:notification]['error_recipients'] + } end end From e5448603a4f00a93d2640eaf455229a3aa9209dc Mon Sep 17 00:00:00 2001 From: wvengen Date: Mon, 15 Jul 2013 23:45:09 +0200 Subject: [PATCH 05/79] update uglifier --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8095b8e8..693964f7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -253,7 +253,7 @@ GEM rails (>= 3.1) railties (>= 3.1) tzinfo (0.3.37) - uglifier (2.1.1) + uglifier (2.1.2) execjs (>= 0.3.0) multi_json (~> 1.0, >= 1.0.2) uniform_notifier (1.2.0) From ea399b2c7248babc8234270cbccbcecb5053933e Mon Sep 17 00:00:00 2001 From: wvengen Date: Tue, 16 Jul 2013 00:39:11 +0200 Subject: [PATCH 06/79] client_side_validations config --- config/initializers/client_side_validations.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/config/initializers/client_side_validations.rb b/config/initializers/client_side_validations.rb index 30e21d0d..95ff1644 100644 --- a/config/initializers/client_side_validations.rb +++ b/config/initializers/client_side_validations.rb @@ -1,9 +1,14 @@ # ClientSideValidations Initializer # Uncomment to disable uniqueness validator, possible security issue -# ClientSideValidations::Config.disabled_validators = [:uniqueness] +# Disabled because of possible security issue and because of bug +# https://github.com/bcardarella/client_side_validations/pull/532 +ClientSideValidations::Config.disabled_validators = [:uniqueness] # Uncomment to validate number format with current I18n locale +# Foodsoft is currently using localize_input which is activated on certain +# fields only, meaning we can't globally turn this on. The non-i18n number +# format is still supported - so for now keep false. # ClientSideValidations::Config.number_format_with_locale = true # Uncomment the following block if you want each input field to have the validation messages attached. From ccea97c2b37e9c596fd35675380c95d0cb673fa9 Mon Sep 17 00:00:00 2001 From: wvengen Date: Wed, 17 Jul 2013 11:31:12 +0200 Subject: [PATCH 07/79] update bootstrap assets --- app/assets/javascripts/bootstrap.js.coffee | 5 ++--- .../stylesheets/bootstrap_and_overrides.css.less | 12 +++++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/app/assets/javascripts/bootstrap.js.coffee b/app/assets/javascripts/bootstrap.js.coffee index c9404a8e..94406798 100644 --- a/app/assets/javascripts/bootstrap.js.coffee +++ b/app/assets/javascripts/bootstrap.js.coffee @@ -1,4 +1,3 @@ jQuery -> - $("a[rel=popover]").popover() - $(".tooltip").tooltip() - $("a[rel=tooltip]").tooltip() \ No newline at end of file + $("a[rel~=popover], .has-popover").popover() + $("a[rel~=tooltip], .has-tooltip").tooltip() diff --git a/app/assets/stylesheets/bootstrap_and_overrides.css.less b/app/assets/stylesheets/bootstrap_and_overrides.css.less index 29364538..2cdb337e 100644 --- a/app/assets/stylesheets/bootstrap_and_overrides.css.less +++ b/app/assets/stylesheets/bootstrap_and_overrides.css.less @@ -1,13 +1,12 @@ @import "twitter/bootstrap/bootstrap"; +@import "twitter/bootstrap/responsive"; body { padding-top: 10px; } -@import "twitter/bootstrap/responsive"; - // Set the correct sprite paths -@iconSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings.png'); -@iconWhiteSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings-white.png'); +@iconSpritePath: image-url('twitter/bootstrap/glyphicons-halflings.png'); +@iconWhiteSpritePath: image-url('twitter/bootstrap/glyphicons-halflings-white.png'); // Set the Font Awesome (Font Awesome is default. You can disable by commenting below lines) @fontAwesomeEotPath: asset-url('fontawesome-webfont.eot'); @@ -17,13 +16,16 @@ body { @fontAwesomeSvgPath: asset-url('fontawesome-webfont.svg#fontawesomeregular'); @import 'fontawesome/font-awesome'; +// Glyphicons +//@import "twitter/bootstrap/sprites.less"; + // Your custom LESS stylesheets goes here // // Since bootstrap was imported above you have access to its mixins which // you may use and inherit here // // If you'd like to override bootstrap's own variables, you can do so here as well -// See http://twitter.github.com/bootstrap/less.html for their names and documentation +// See http://twitter.github.com/bootstrap/customize.html#variables for their names and documentation // // Example: // @linkColor: #ff0000; From 1fed9834b35dbee8b329305b2a62ac1ddf8e0eb7 Mon Sep 17 00:00:00 2001 From: wvengen Date: Wed, 17 Jul 2013 11:31:27 +0200 Subject: [PATCH 08/79] fix tooltip after bootstrap update --- app/views/deliveries/_form.html.haml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/deliveries/_form.html.haml b/app/views/deliveries/_form.html.haml index c1702708..c9bd8fcd 100644 --- a/app/views/deliveries/_form.html.haml +++ b/app/views/deliveries/_form.html.haml @@ -84,7 +84,8 @@ $('[data-toggle~="tooltip"]', context).tooltip({ animation: false, html: true, - placement: 'left' + placement: 'left', + container: 'body' // or they become a cell in the table }); } From dbb0bb4506892ff681fb4ef25fdc9ec353f4f534 Mon Sep 17 00:00:00 2001 From: Robert Waltemath Date: Wed, 18 Sep 2013 10:07:50 +0200 Subject: [PATCH 09/79] Added hint when changing total delivered amount. --- config/locales/de.yml | 2 +- config/locales/en.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/locales/de.yml b/config/locales/de.yml index c0000036..a74f95b5 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -1525,7 +1525,7 @@ de: message: private: Nachricht erscheint nicht im Foodsoft Posteingang order_article: - units_to_order: Anzahl gelieferter Gebinde + units_to_order: Wenn Du die Gesamtanzahl gelieferter Gebinde änderst, musst Du auch die individuelle Anzahl der einzelnen Bestellgruppen anpassen, indem Du auf den Artikelnamen klickst. Sie werden nicht automatisch neuberechnet und andernfalls werden den Bestellgruppen Artikel in Rechnung gestellt, die nicht geliefert wurden! update_current_price: Ändert auch den Preis für aktuelle Bestellungen stock_article: copy_stock_article: diff --git a/config/locales/en.yml b/config/locales/en.yml index 2fa64013..d33f02cd 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1530,7 +1530,7 @@ en: message: private: Message doesn’t show in Foodsoft mail inbox order_article: - units_to_order: Amount of delivered units + units_to_order: If you change the total amount of delivered units, you also have to change individual group amounts by clicking on the article name. They will not be automatically recalculated and otherwise ordergroups will be accounted for undelivered articles! update_current_price: Also update the price of the current order stock_article: copy_stock_article: From 19a61a6c427eece90b0986fc162e314ec4bb5537 Mon Sep 17 00:00:00 2001 From: wvengen Date: Wed, 18 Sep 2013 16:53:49 +0200 Subject: [PATCH 10/79] update gems --- Gemfile.lock | 137 ++++++++++++++++++++++++++------------------------- 1 file changed, 69 insertions(+), 68 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 3ced3672..059ef232 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -15,12 +15,12 @@ GEM remote: https://rubygems.org/ specs: Ascii85 (1.0.2) - actionmailer (3.2.13) - actionpack (= 3.2.13) - mail (~> 2.5.3) - actionpack (3.2.13) - activemodel (= 3.2.13) - activesupport (= 3.2.13) + actionmailer (3.2.14) + actionpack (= 3.2.14) + mail (~> 2.5.4) + actionpack (3.2.14) + activemodel (= 3.2.14) + activesupport (= 3.2.14) builder (~> 3.0.0) erubis (~> 2.7.0) journey (~> 1.0.4) @@ -28,30 +28,30 @@ GEM rack-cache (~> 1.2) rack-test (~> 0.6.1) sprockets (~> 2.2.1) - activemodel (3.2.13) - activesupport (= 3.2.13) + activemodel (3.2.14) + activesupport (= 3.2.14) builder (~> 3.0.0) - activerecord (3.2.13) - activemodel (= 3.2.13) - activesupport (= 3.2.13) + activerecord (3.2.14) + activemodel (= 3.2.14) + activesupport (= 3.2.14) arel (~> 3.0.2) tzinfo (~> 0.3.29) - activeresource (3.2.13) - activemodel (= 3.2.13) - activesupport (= 3.2.13) - activesupport (3.2.13) - i18n (= 0.6.1) + activeresource (3.2.14) + activemodel (= 3.2.14) + activesupport (= 3.2.14) + activesupport (3.2.14) + i18n (~> 0.6, >= 0.6.4) multi_json (~> 1.0) acts_as_tree (1.4.0) activerecord (>= 3.0.0) afm (0.2.0) arel (3.0.2) - better_errors (0.9.0) + better_errors (1.0.1) coderay (>= 1.0.0) erubis (>= 2.6.6) binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) - bootstrap-datepicker-rails (1.1.1.1) + bootstrap-datepicker-rails (1.1.1.7) railties (>= 3.0) builder (3.0.4) bullet (4.6.0) @@ -72,12 +72,12 @@ GEM xpath (~> 2.0) childprocess (0.3.9) ffi (~> 1.0, >= 1.0.11) - chronic (0.9.1) - client_side_validations (3.2.5) + chronic (0.10.2) + client_side_validations (3.2.6) client_side_validations-simple_form (2.1.0) client_side_validations (~> 3.2.5) simple_form (~> 2.1.0) - coderay (1.0.9) + coderay (1.1.0) coffee-rails (3.2.2) coffee-script (>= 2.2.0) railties (~> 3.2.0) @@ -85,25 +85,24 @@ GEM coffee-script-source execjs coffee-script-source (1.6.3) - commonjs (0.2.6) + commonjs (0.2.7) daemons (1.1.9) - database_cleaner (0.7.1) + database_cleaner (1.1.1) debug_inspector (0.0.2) diff-lcs (1.2.4) erubis (2.7.0) eventmachine (1.0.3) - exception_notification (4.0.0) + exception_notification (4.0.1) actionmailer (>= 3.0.4) activesupport (>= 3.0.4) - execjs (1.4.0) - multi_json (~> 1.0) + execjs (2.0.1) expression_parser (0.9.0) factory_girl (4.2.0) activesupport (>= 3.0.0) factory_girl_rails (4.2.1) factory_girl (~> 4.2.0) railties (>= 3.0.0) - faker (1.1.2) + faker (1.2.0) i18n (~> 0.5) ffi (1.9.0) haml (4.0.3) @@ -113,16 +112,18 @@ GEM activesupport (>= 3.1, < 4.1) haml (>= 3.1, < 4.1) railties (>= 3.1, < 4.1) - has_scope (0.5.1) - hashery (2.1.0) + has_scope (0.6.0.rc) + actionpack (>= 3.2, < 5) + activesupport (>= 3.2, < 5) + hashery (2.1.1) highline (1.6.19) hike (1.2.3) - i18n (0.6.1) + i18n (0.6.5) i18n-spec (0.4.0) iso - inherited_resources (1.4.0) - has_scope (~> 0.5.0) - responders (~> 0.9) + inherited_resources (1.4.1) + has_scope (~> 0.6.0.rc) + responders (~> 1.0.0.rc) iso (0.2.0) i18n journey (1.0.4) @@ -133,12 +134,12 @@ GEM kaminari (0.14.1) actionpack (>= 3.0.0) activesupport (>= 3.0.0) - less (2.3.2) - commonjs (~> 0.2.6) - less-rails (2.3.3) + less (2.4.0) + commonjs (~> 0.2.7) + less-rails (2.4.2) actionpack (>= 3.1) - less (~> 2.3.1) - libv8 (3.11.8.17) + less (~> 2.4.0) + libv8 (3.16.14.3) mail (2.5.4) mime-types (~> 1.16) treetop (~> 1.4.8) @@ -156,16 +157,16 @@ GEM activerecord (~> 3.1) activesupport (~> 3.1) polyamorous (~> 0.5.0) - mime-types (1.23) + mime-types (1.25) mini_portile (0.5.1) mono_logger (1.1.0) - multi_json (1.7.7) - mysql2 (0.3.11) + multi_json (1.8.0) + mysql2 (0.3.13) net-scp (1.1.2) net-ssh (>= 2.6.5) net-sftp (2.1.2) net-ssh (>= 2.6.5) - net-ssh (2.6.8) + net-ssh (2.7.0) net-ssh-gateway (1.2.0) net-ssh (>= 2.6.5) nokogiri (1.6.0) @@ -193,19 +194,19 @@ GEM rack rack-test (0.6.2) rack (>= 1.0) - rails (3.2.13) - actionmailer (= 3.2.13) - actionpack (= 3.2.13) - activerecord (= 3.2.13) - activeresource (= 3.2.13) - activesupport (= 3.2.13) + rails (3.2.14) + actionmailer (= 3.2.14) + actionpack (= 3.2.14) + activerecord (= 3.2.14) + activeresource (= 3.2.14) + activesupport (= 3.2.14) bundler (~> 1.0) - railties (= 3.2.13) + railties (= 3.2.14) rails-settings-cached (0.2.4) rails (>= 3.0.0) - railties (3.2.13) - actionpack (= 3.2.13) - activesupport (= 3.2.13) + railties (3.2.14) + actionpack (= 3.2.14) + activesupport (= 3.2.14) rack-ssl (~> 1.3.2) rake (>= 0.8.7) rdoc (~> 3.4) @@ -217,18 +218,18 @@ GEM redis-namespace (1.3.1) redis (~> 3.0.0) ref (1.0.5) - responders (0.9.3) - railties (~> 3.1) - resque (1.24.1) + responders (1.0.0.rc) + railties (>= 3.2, < 5) + resque (1.25.0) mono_logger (~> 1.0) multi_json (~> 1.0) redis-namespace (~> 1.2) sinatra (>= 0.9.2) vegas (~> 0.1.2) - rspec-core (2.14.2) - rspec-expectations (2.14.0) + rspec-core (2.14.5) + rspec-expectations (2.14.2) diff-lcs (>= 1.1.3, < 2.0) - rspec-mocks (2.14.1) + rspec-mocks (2.14.3) rspec-rails (2.14.0) actionpack (>= 3.0) activesupport (>= 3.0) @@ -239,12 +240,12 @@ GEM ruby-prof (0.13.0) ruby-rc4 (0.1.5) rubyzip (0.9.9) - sass (3.2.9) + sass (3.2.10) sass-rails (3.2.6) railties (~> 3.2.0) sass (>= 3.1.10) tilt (~> 1.3) - select2-rails (3.4.3) + select2-rails (3.4.8) sass-rails thor (~> 0.14) selenium-webdriver (2.35.1) @@ -276,9 +277,9 @@ GEM multi_json (~> 1.0) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) - sqlite3 (1.3.7) - therubyracer (0.11.4) - libv8 (~> 3.11.8.12) + sqlite3 (1.3.8) + therubyracer (0.12.0) + libv8 (~> 3.16.14.0) ref thin (1.5.1) daemons (>= 1.0.9) @@ -286,24 +287,24 @@ GEM rack (>= 1.0.0) thor (0.18.1) tilt (1.4.1) - treetop (1.4.14) + treetop (1.4.15) polyglot polyglot (>= 0.3.1) ttfunk (1.0.3) - twitter-bootstrap-rails (2.2.7) + twitter-bootstrap-rails (2.2.8) actionpack (>= 3.1) execjs rails (>= 3.1) railties (>= 3.1) tzinfo (0.3.37) - uglifier (2.1.2) + uglifier (2.2.1) execjs (>= 0.3.0) multi_json (~> 1.0, >= 1.0.2) - uniform_notifier (1.2.0) + uniform_notifier (1.3.0) vegas (0.1.11) rack (>= 1.0.0) websocket (1.0.7) - whenever (0.8.3) + whenever (0.8.4) activesupport (>= 2.3.4) chronic (>= 0.6.3) wikicloth (0.8.0) From 14d4d2f12d8c5ac68eeaa4fad8f5f5b591f75f62 Mon Sep 17 00:00:00 2001 From: Julius Date: Wed, 18 Sep 2013 23:15:21 +0200 Subject: [PATCH 11/79] Add list.js for filtering articles (another try for foodcoops#143) --- app/assets/javascripts/application.js | 2 + app/assets/javascripts/list.unlist.js | 150 +++++ app/assets/stylesheets/application.css | 1 + app/assets/stylesheets/list.unlist.css | 3 + app/views/group_orders/_form.html.haml | 10 +- config/locales/de.yml | 1 + config/locales/en.yml | 1 + vendor/assets/javascripts/list.js | 775 +++++++++++++++++++++++++ 8 files changed, 941 insertions(+), 2 deletions(-) create mode 100644 app/assets/javascripts/list.unlist.js create mode 100644 app/assets/stylesheets/list.unlist.css create mode 100644 vendor/assets/javascripts/list.js diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index c6d6e36a..09771539 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -8,6 +8,8 @@ //= require bootstrap-datepicker/locales/bootstrap-datepicker.de //= require bootstrap-datepicker/locales/bootstrap-datepicker.nl //= require jquery.observe_field +//= require list +//= require list.unlist //= require rails.validations //= require_self //= require ordering diff --git a/app/assets/javascripts/list.unlist.js b/app/assets/javascripts/list.unlist.js new file mode 100644 index 00000000..f649369f --- /dev/null +++ b/app/assets/javascripts/list.unlist.js @@ -0,0 +1,150 @@ +/******************************************************************************* +******************************************************************************** + +The following code is a modification of list.js. It was created by copy-pasting +the original code with the copyright notice below. + +******************************************************************************** +*******************************************************************************/ + + + +/******************************************************************************* +Begin copyright notice of the original code +*******************************************************************************/ + +/* +ListJS Beta 0.2.0 +By Jonny Strömberg (www.jonnystromberg.com, www.listjs.com) + +OBS. The API is not frozen. It MAY change! + +License (MIT) + +Copyright (c) 2011 Jonny Strömberg http://jonnystromberg.com + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. +*/ + +/******************************************************************************* +End copyright notice of the original code +*******************************************************************************/ + + + +/******************************************************************************* +Begin copy-pasted and modified code +*******************************************************************************/ + +// * template engine which adds class 'unlisted' instead of removing from DOM +// * especially useful in case of formulars +// * uses jQuery's $ +List.prototype.templateEngines.unlist = function(list, settings) { + var listSource = ListJsHelpers.getByClass(settings.listClass, list.listContainer, true), + itemSource = getItemSource(settings.item), + templater = this; + + function getItemSource(item) { + if (item === undefined) { + var nodes = listSource.childNodes, + items = []; + + for (var i = 0, il = nodes.length; i < il; i++) { + // Only textnodes have a data attribute + if (nodes[i].data === undefined) { + return nodes[i]; + } + } + return null; + } else if (item.indexOf("<") !== -1) { // Try create html element of list, do not work for tables!! + var div = document.createElement('div'); + div.innerHTML = item; + return div.firstChild; + } else { + return document.getElementById(settings.item); + } + } + + var ensure = { + created: function(item) { + if (item.elm === undefined) { + templater.create(item); + } + } + }; + + /* Get values from element */ + this.get = function(item, valueNames) { + ensure.created(item); + var values = {}; + for(var i = 0, il = valueNames.length; i < il; i++) { + var elm = ListJsHelpers.getByClass(valueNames[i], item.elm, true); + values[valueNames[i]] = elm ? elm.innerHTML : ""; + } + return values; + }; + + /* Sets values at element */ + this.set = function(item, values) { + ensure.created(item); + for(var v in values) { + if (values.hasOwnProperty(v)) { + // TODO speed up if possible + var elm = ListJsHelpers.getByClass(v, item.elm, true); + if (elm) { + elm.innerHTML = values[v]; + } + } + } + }; + + this.create = function(item) { + if (item.elm !== undefined) { + return; + } + /* If item source does not exists, use the first item in list as + source for new items */ + var newItem = itemSource.cloneNode(true); + newItem.id = ""; + item.elm = newItem; + templater.set(item, item.values()); + }; + this.remove = function(item) { + listSource.removeChild(item.elm); + }; + this.show = function(item) { + ensure.created(item); + listSource.appendChild(item.elm); // append item (or move it to the end) + $(item.elm).removeClass('unlisted'); + }; + this.hide = function(item) { + if (item.elm !== undefined) { + $(item.elm).addClass('unlisted'); + } + }; + this.clear = function() { + $(listSource.childNodes).addClass('unlisted'); + }; +}; + +/******************************************************************************* +End copy-pasted and modified code +*******************************************************************************/ diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 24a5b6c4..674a635c 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -3,4 +3,5 @@ *= require select2 *= require token-input-bootstrappy *= require bootstrap-datepicker +*= require list.unlist */ \ No newline at end of file diff --git a/app/assets/stylesheets/list.unlist.css b/app/assets/stylesheets/list.unlist.css new file mode 100644 index 00000000..b0ed4600 --- /dev/null +++ b/app/assets/stylesheets/list.unlist.css @@ -0,0 +1,3 @@ +.list .unlisted { + display: none; +} \ No newline at end of file diff --git a/app/views/group_orders/_form.html.haml b/app/views/group_orders/_form.html.haml index 2bd2f30b..78bccce5 100644 --- a/app/views/group_orders/_form.html.haml +++ b/app/views/group_orders/_form.html.haml @@ -7,6 +7,8 @@ setMinimumBalance(#{FoodsoftConfig[:minimum_balance] or 0}); setToleranceBehaviour(#{FoodsoftConfig[:tolerance_is_costly]}); setStockit(#{@order.stockit?}); + // create List for search-feature (using list.js, http://listjs.com) + new List(document.body, { valueNames: ['name'], engine: 'unlist' }); }); - title t('.title'), false @@ -37,6 +39,10 @@ .well.pull-right = render 'switch_order', current_order: @order +.row-fluid + .well.clear + = text_field_tag :article, params[:article], placeholder: t('.search_article'), class: 'search-query input-large search' + = form_for @group_order do |f| = f.hidden_field :lock_version = f.hidden_field :order_id @@ -59,10 +65,10 @@ %th(style="width:20px")= t '.available' %th#col_required= t '.amount' %th{style: "width:15px;"}= t '.sum' - %tbody + %tbody.list - @order.articles_grouped_by_category.each do |category, order_articles| %tr.article-category - %td + %td.name = category %i.icon-tag %td{colspan: "9"} diff --git a/config/locales/de.yml b/config/locales/de.yml index 07a7f2f9..ab08d6dc 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -787,6 +787,7 @@ de: new_funds: Neuer Kontostand note: Notiz price: Preis + search_article: Artikel suchen... sum: Summe sum_amount: ! 'Gesamtbestellmenge bisher:' supplier: Lieferant diff --git a/config/locales/en.yml b/config/locales/en.yml index d21665ec..18356d73 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -791,6 +791,7 @@ en: new_funds: New account balance note: Note price: Price + search_article: Search for article... sum: Sum sum_amount: Current amount supplier: Supplier diff --git a/vendor/assets/javascripts/list.js b/vendor/assets/javascripts/list.js new file mode 100644 index 00000000..44ce6879 --- /dev/null +++ b/vendor/assets/javascripts/list.js @@ -0,0 +1,775 @@ +/* +ListJS Beta 0.2.0 +By Jonny Strömberg (www.jonnystromberg.com, www.listjs.com) + +OBS. The API is not frozen. It MAY change! + +License (MIT) + +Copyright (c) 2011 Jonny Strömberg http://jonnystromberg.com + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. +*/ +(function( window, undefined ) { +"use strict"; +var document = window.document, + h; + +var List = function(id, options, values) { + var self = this, + templater, + init, + initialItems, + Item, + Templater, + sortButtons, + events = { + 'updated': [] + }; + this.listContainer = (typeof(id) == 'string') ? document.getElementById(id) : id; + // Check if the container exists. If not return instead of breaking the javascript + if (!this.listContainer) + return; + + this.items = []; + this.visibleItems = []; // These are the items currently visible + this.matchingItems = []; // These are the items currently matching filters and search, regadlessof visible count + this.searched = false; + this.filtered = false; + + this.list = null; + this.templateEngines = {}; + + this.page = options.page || 200; + this.i = options.i || 1; + + init = { + start: function(values, options) { + options.plugins = options.plugins || {}; + this.classes(options); + templater = new Templater(self, options); + this.callbacks(options); + this.items.start(values, options); + self.update(); + this.plugins(options.plugins); + }, + classes: function(options) { + options.listClass = options.listClass || 'list'; + options.searchClass = options.searchClass || 'search'; + options.sortClass = options.sortClass || 'sort'; + }, + callbacks: function(options) { + self.list = h.getByClass(options.listClass, self.listContainer, true); + h.addEvent(h.getByClass(options.searchClass, self.listContainer), 'keyup', self.search); + sortButtons = h.getByClass(options.sortClass, self.listContainer); + h.addEvent(sortButtons, 'click', self.sort); + }, + items: { + start: function(values, options) { + if (options.valueNames) { + var itemsToIndex = this.get(), + valueNames = options.valueNames; + if (options.indexAsync) { + this.indexAsync(itemsToIndex, valueNames); + } else { + this.index(itemsToIndex, valueNames); + } + } + if (values !== undefined) { + self.add(values); + } + }, + get: function() { + // return h.getByClass('item', self.list); + var nodes = self.list.childNodes, + items = []; + for (var i = 0, il = nodes.length; i < il; i++) { + // Only textnodes have a data attribute + if (nodes[i].data === undefined) { + items.push(nodes[i]); + } + } + return items; + }, + index: function(itemElements, valueNames) { + for (var i = 0, il = itemElements.length; i < il; i++) { + self.items.push(new Item(valueNames, itemElements[i])); + } + }, + indexAsync: function(itemElements, valueNames) { + var itemsToIndex = itemElements.splice(0, 100); // TODO: If < 100 items, what happens in IE etc? + this.index(itemsToIndex, valueNames); + if (itemElements.length > 0) { + setTimeout(function() { + init.items.indexAsync(itemElements, valueNames); + }, + 10); + } else { + self.update(); + // TODO: Add indexed callback + } + } + }, + plugins: function(plugins) { + var locals = { + templater: templater, + init: init, + initialItems: initialItems, + Item: Item, + Templater: Templater, + sortButtons: sortButtons, + events: events, + reset: reset + }; + for (var i = 0; i < plugins.length; i++) { + plugins[i][1] = plugins[i][1] || {}; + var pluginName = plugins[i][1].name || plugins[i][0]; + self[pluginName] = self.plugins[plugins[i][0]].call(self, locals, plugins[i][1]); + } + } + }; + + + /* + * Add object to list + */ + this.add = function(values, callback) { + if (callback) { + addAsync(values, callback); + } + var added = [], + notCreate = false; + if (values[0] === undefined){ + values = [values]; + } + for (var i = 0, il = values.length; i < il; i++) { + var item = null; + if (values[i] instanceof Item) { + item = values[i]; + item.reload(); + } else { + notCreate = (self.items.length > self.page) ? true : false; + item = new Item(values[i], undefined, notCreate); + } + self.items.push(item); + added.push(item); + } + self.update(); + return added; + }; + + /* + * Adds items asynchronous to the list, good for adding huge amount of + * data. Defaults to add 100 items a time + */ + var addAsync = function(values, callback, items) { + var valuesToAdd = values.splice(0, 100); + items = items || []; + items = items.concat(self.add(valuesToAdd)); + if (values.length > 0) { + setTimeout(function() { + addAsync(values, callback, items); + }, 10); + } else { + self.update(); + callback(items); + } + }; + + this.show = function(i, page) { + this.i = i; + this.page = page; + self.update(); + }; + + /* Removes object from list. + * Loops through the list and removes objects where + * property "valuename" === value + */ + this.remove = function(valueName, value, options) { + var found = 0; + for (var i = 0, il = self.items.length; i < il; i++) { + if (self.items[i].values()[valueName] == value) { + templater.remove(self.items[i], options); + self.items.splice(i,1); + il--; + found++; + } + } + self.update(); + return found; + }; + + /* Gets the objects in the list which + * property "valueName" === value + */ + this.get = function(valueName, value) { + var matchedItems = []; + for (var i = 0, il = self.items.length; i < il; i++) { + var item = self.items[i]; + if (item.values()[valueName] == value) { + matchedItems.push(item); + } + } + if (matchedItems.length == 0) { + return null; + } else if (matchedItems.length == 1) { + return matchedItems[0]; + } else { + return matchedItems; + } + }; + + /* Sorts the list. + * @valueOrEvent Either a JavaScript event object or a valueName + * @sortFunction (optional) Define if natural sorting does not fullfill your needs + */ + this.sort = function(valueName, options) { + var length = self.items.length, + value = null, + target = valueName.target || valueName.srcElement, /* IE have srcElement */ + sorting = '', + isAsc = false, + asc = 'asc', + desc = 'desc', + options = options || {}; + + if (target === undefined) { + value = valueName; + isAsc = options.asc || false; + } else { + value = h.getAttribute(target, 'data-sort'); + isAsc = h.hasClass(target, asc) ? false : true; + } + for (var i = 0, il = sortButtons.length; i < il; i++) { + h.removeClass(sortButtons[i], asc); + h.removeClass(sortButtons[i], desc); + } + if (isAsc) { + if (target !== undefined) { + h.addClass(target, asc); + } + isAsc = true; + } else { + if (target !== undefined) { + h.addClass(target, desc); + } + isAsc = false; + } + + if (options.sortFunction) { + options.sortFunction = options.sortFunction; + } else { + options.sortFunction = function(a, b) { + return h.sorter.alphanum(a.values()[value].toLowerCase(), b.values()[value].toLowerCase(), isAsc); + }; + } + self.items.sort(options.sortFunction); + self.update(); + }; + + /* + * Searches the list after values with content "searchStringOrEvent". + * The columns parameter defines if all values should be included in the search, + * defaults to undefined which means "all". + */ + this.search = function(searchString, columns) { + self.i = 1; // Reset paging + var matching = [], + found, + item, + text, + values, + is, + columns = (columns === undefined) ? self.items[0].values() : columns, + searchString = (searchString === undefined) ? "" : searchString, + target = searchString.target || searchString.srcElement; /* IE have srcElement */ + + searchString = (target === undefined) ? (""+searchString).toLowerCase() : ""+target.value.toLowerCase(); + is = self.items; + // Escape regular expression characters + searchString = searchString.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); + + templater.clear(); + if (searchString === "" ) { + reset.search(); + self.searched = false; + self.update(); + } else { + self.searched = true; + + for (var k = 0, kl = is.length; k < kl; k++) { + found = false; + item = is[k]; + values = item.values(); + + for(var j in columns) { + if(values.hasOwnProperty(j) && columns[j] !== null) { + text = (values[j] != null) ? values[j].toString().toLowerCase() : ""; + if ((searchString !== "") && (text.search(searchString) > -1)) { + found = true; + } + } + } + if (found) { + item.found = true; + matching.push(item); + } else { + item.found = false; + } + } + self.update(); + } + return self.visibleItems; + }; + + /* + * Filters the list. If filterFunction() returns False hides the Item. + * if filterFunction == false are the filter removed + */ + this.filter = function(filterFunction) { + self.i = 1; // Reset paging + reset.filter(); + if (filterFunction === undefined) { + self.filtered = false; + } else { + self.filtered = true; + var is = self.items; + for (var i = 0, il = is.length; i < il; i++) { + var item = is[i]; + if (filterFunction(item)) { + item.filtered = true; + } else { + item.filtered = false; + } + } + } + self.update(); + return self.visibleItems; + }; + + /* + * Get size of the list + */ + this.size = function() { + return self.items.length; + }; + + /* + * Removes all items from the list + */ + this.clear = function() { + templater.clear(); + self.items = []; + }; + + this.on = function(event, callback) { + events[event].push(callback); + }; + + var trigger = function(event) { + var i = events[event].length; + while(i--) { + events[event][i](); + } + }; + + var reset = { + filter: function() { + var is = self.items, + il = is.length; + while (il--) { + is[il].filtered = false; + } + }, + search: function() { + var is = self.items, + il = is.length; + while (il--) { + is[il].found = false; + } + } + }; + + + this.update = function() { + var is = self.items, + il = is.length; + + self.visibleItems = []; + self.matchingItems = []; + templater.clear(); + for (var i = 0; i < il; i++) { + if (is[i].matching() && ((self.matchingItems.length+1) >= self.i && self.visibleItems.length < self.page)) { + is[i].show(); + self.visibleItems.push(is[i]); + self.matchingItems.push(is[i]); + } else if (is[i].matching()) { + self.matchingItems.push(is[i]); + is[i].hide(); + } else { + is[i].hide(); + } + } + trigger('updated'); + }; + + Item = function(initValues, element, notCreate) { + var item = this, + values = {}; + + this.found = false; // Show if list.searched == true and this.found == true + this.filtered = false;// Show if list.filtered == true and this.filtered == true + + var init = function(initValues, element, notCreate) { + if (element === undefined) { + if (notCreate) { + item.values(initValues, notCreate); + } else { + item.values(initValues); + } + } else { + item.elm = element; + var values = templater.get(item, initValues); + item.values(values); + } + }; + this.values = function(newValues, notCreate) { + if (newValues !== undefined) { + for(var name in newValues) { + values[name] = newValues[name]; + } + if (notCreate !== true) { + templater.set(item, item.values()); + } + } else { + return values; + } + }; + this.show = function() { + templater.show(item); + }; + this.hide = function() { + templater.hide(item); + }; + this.matching = function() { + return ( + (self.filtered && self.searched && item.found && item.filtered) || + (self.filtered && !self.searched && item.filtered) || + (!self.filtered && self.searched && item.found) || + (!self.filtered && !self.searched) + ); + }; + this.visible = function() { + return (item.elm.parentNode) ? true : false; + }; + init(initValues, element, notCreate); + }; + + /* Templater with different kinds of template engines. + * All engines have these methods + * - reload(item) + * - remove(item) + */ + Templater = function(list, settings) { + if (settings.engine === undefined) { + settings.engine = "standard"; + } else { + settings.engine = settings.engine.toLowerCase(); + } + return new self.constructor.prototype.templateEngines[settings.engine](list, settings); + }; + + init.start(values, options); +}; + +List.prototype.templateEngines = {}; +List.prototype.plugins = {}; + +List.prototype.templateEngines.standard = function(list, settings) { + var listSource = h.getByClass(settings.listClass, list.listContainer, true), + itemSource = getItemSource(settings.item), + templater = this; + + function getItemSource(item) { + if (item === undefined) { + var nodes = listSource.childNodes, + items = []; + + for (var i = 0, il = nodes.length; i < il; i++) { + // Only textnodes have a data attribute + if (nodes[i].data === undefined) { + return nodes[i]; + } + } + return null; + } else if (item.indexOf("<") !== -1) { // Try create html element of list, do not work for tables!! + var div = document.createElement('div'); + div.innerHTML = item; + return div.firstChild; + } else { + return document.getElementById(settings.item); + } + } + + var ensure = { + created: function(item) { + if (item.elm === undefined) { + templater.create(item); + } + } + }; + + /* Get values from element */ + this.get = function(item, valueNames) { + ensure.created(item); + var values = {}; + for(var i = 0, il = valueNames.length; i < il; i++) { + var elm = h.getByClass(valueNames[i], item.elm, true); + values[valueNames[i]] = elm ? elm.innerHTML : ""; + } + return values; + }; + + /* Sets values at element */ + this.set = function(item, values) { + ensure.created(item); + for(var v in values) { + if (values.hasOwnProperty(v)) { + // TODO speed up if possible + var elm = h.getByClass(v, item.elm, true); + if (elm) { + elm.innerHTML = values[v]; + } + } + } + }; + + this.create = function(item) { + if (item.elm !== undefined) { + return; + } + /* If item source does not exists, use the first item in list as + source for new items */ + var newItem = itemSource.cloneNode(true); + newItem.id = ""; + item.elm = newItem; + templater.set(item, item.values()); + }; + this.remove = function(item) { + listSource.removeChild(item.elm); + }; + this.show = function(item) { + ensure.created(item); + listSource.appendChild(item.elm); + }; + this.hide = function(item) { + if (item.elm !== undefined && item.elm.parentNode === listSource) { + listSource.removeChild(item.elm); + } + }; + this.clear = function() { + /* .innerHTML = ''; fucks up IE */ + if (listSource.hasChildNodes()) { + while (listSource.childNodes.length >= 1) + { + listSource.removeChild(listSource.firstChild); + } + } + }; +}; + + +/* +* These helper functions are not written by List.js author Jonny (they may have been +* adjusted, thought). +*/ +h = { + /* + * Cross browser getElementsByClassName, which uses native + * if it exists. Modified version of Dustin Diaz function: + * http://www.dustindiaz.com/getelementsbyclass + */ + getByClass: (function() { + if (document.getElementsByClassName) { + return function(searchClass,node,single) { + if (single) { + return node.getElementsByClassName(searchClass)[0]; + } else { + return node.getElementsByClassName(searchClass); + } + }; + } else { + return function(searchClass,node,single) { + var classElements = [], + tag = '*'; + if (node == null) { + node = document; + } + var els = node.getElementsByTagName(tag); + var elsLen = els.length; + var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)"); + for (var i = 0, j = 0; i < elsLen; i++) { + if ( pattern.test(els[i].className) ) { + if (single) { + return els[i]; + } else { + classElements[j] = els[i]; + j++; + } + } + } + return classElements; + }; + } + })(), + /* (elm, 'event' callback) Source: http://net.tutsplus.com/tutorials/javascript-ajax/javascript-from-null-cross-browser-event-binding/ */ + addEvent: (function( window, document ) { + if ( document.addEventListener ) { + return function( elem, type, cb ) { + if ((elem && !(elem instanceof Array) && !elem.length && !h.isNodeList(elem) && (elem.length !== 0)) || elem === window ) { + elem.addEventListener(type, cb, false ); + } else if ( elem && elem[0] !== undefined ) { + var len = elem.length; + for ( var i = 0; i < len; i++ ) { + h.addEvent(elem[i], type, cb); + } + } + }; + } + else if ( document.attachEvent ) { + return function ( elem, type, cb ) { + if ((elem && !(elem instanceof Array) && !elem.length && !h.isNodeList(elem) && (elem.length !== 0)) || elem === window ) { + elem.attachEvent( 'on' + type, function() { return cb.call(elem, window.event); } ); + } else if ( elem && elem[0] !== undefined ) { + var len = elem.length; + for ( var i = 0; i < len; i++ ) { + h.addEvent( elem[i], type, cb ); + } + } + }; + } + })(this, document), + /* (elm, attribute) Source: http://stackoverflow.com/questions/3755227/cross-browser-javascript-getattribute-method */ + getAttribute: function(ele, attr) { + var result = (ele.getAttribute && ele.getAttribute(attr)) || null; + if( !result ) { + var attrs = ele.attributes; + var length = attrs.length; + for(var i = 0; i < length; i++) { + if (attr[i] !== undefined) { + if(attr[i].nodeName === attr) { + result = attr[i].nodeValue; + } + } + } + } + return result; + }, + /* http://stackoverflow.com/questions/7238177/detect-htmlcollection-nodelist-in-javascript */ + isNodeList: function(nodes) { + var result = Object.prototype.toString.call(nodes); + if (typeof nodes === 'object' && /^\[object (HTMLCollection|NodeList|Object)\]$/.test(result) && (nodes.length == 0 || (typeof nodes[0] === "object" && nodes[0].nodeType > 0))) { + return true; + } + return false; + }, + hasClass: function(ele, classN) { + var classes = this.getAttribute(ele, 'class') || this.getAttribute(ele, 'className') || ""; + return (classes.search(classN) > -1); + }, + addClass: function(ele, classN) { + if (!this.hasClass(ele, classN)) { + var classes = this.getAttribute(ele, 'class') || this.getAttribute(ele, 'className') || ""; + classes = classes + ' ' + classN + ' '; + classes = classes.replace(/\s{2,}/g, ' '); + ele.setAttribute('class', classes); + } + }, + removeClass: function(ele, classN) { + if (this.hasClass(ele, classN)) { + var classes = this.getAttribute(ele, 'class') || this.getAttribute(ele, 'className') || ""; + classes = classes.replace(classN, ''); + ele.setAttribute('class', classes); + } + }, + /* + * The sort function. From http://my.opera.com/GreyWyvern/blog/show.dml/1671288 + */ + sorter: { + alphanum: function(a,b,asc) { + if (a === undefined || a === null) { + a = ""; + } + if (b === undefined || b === null) { + b = ""; + } + a = a.toString().replace(/&(lt|gt);/g, function (strMatch, p1){ + return (p1 == "lt")? "<" : ">"; + }); + a = a.replace(/<\/?[^>]+(>|$)/g, ""); + + b = b.toString().replace(/&(lt|gt);/g, function (strMatch, p1){ + return (p1 == "lt")? "<" : ">"; + }); + b = b.replace(/<\/?[^>]+(>|$)/g, ""); + var aa = this.chunkify(a); + var bb = this.chunkify(b); + + for (var x = 0; aa[x] && bb[x]; x++) { + if (aa[x] !== bb[x]) { + var c = Number(aa[x]), d = Number(bb[x]); + if (asc) { + if (c == aa[x] && d == bb[x]) { + return c - d; + } else { + return (aa[x] > bb[x]) ? 1 : -1; + } + } else { + if (c == aa[x] && d == bb[x]) { + return d-c;//c - d; + } else { + return (aa[x] > bb[x]) ? -1 : 1; //(aa[x] > bb[x]) ? 1 : -1; + } + } + } + } + return aa.length - bb.length; + }, + chunkify: function(t) { + var tz = [], x = 0, y = -1, n = 0, i, j; + + while (i = (j = t.charAt(x++)).charCodeAt(0)) { + var m = (i == 45 || i == 46 || (i >=48 && i <= 57)); + if (m !== n) { + tz[++y] = ""; + n = m; + } + tz[y] += j; + } + return tz; + } + } +}; + +window.List = List; +window.ListJsHelpers = h; +})(window); From 891293af8495ddd2a467aecdcc6958579c7f0f67 Mon Sep 17 00:00:00 2001 From: Julius Date: Sun, 22 Sep 2013 21:50:59 +0200 Subject: [PATCH 12/79] Add delay to list.js search --- app/assets/javascripts/application.js | 1 + app/assets/javascripts/list.customized.js | 43 +++++++++++++++++++++++ app/views/group_orders/_form.html.haml | 4 +-- 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 app/assets/javascripts/list.customized.js diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 09771539..c684cf31 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -10,6 +10,7 @@ //= require jquery.observe_field //= require list //= require list.unlist +//= require list.customized //= require rails.validations //= require_self //= require ordering diff --git a/app/assets/javascripts/list.customized.js b/app/assets/javascripts/list.customized.js new file mode 100644 index 00000000..f95a0e0c --- /dev/null +++ b/app/assets/javascripts/list.customized.js @@ -0,0 +1,43 @@ +(function(window, undefined) { + +var CustomizedList = function(id, options, values) { + var self = this; + var h = window.ListJsHelpers; + + this.searchTimeout = undefined; + + var init = { + start: function(id, options, values) { + this.defaults(options); + this.list(id, options, values); + this.callbacks(options); + }, + defaults: function(options) { + options.delayedSearchClass = options.delayedSearchClass || 'delayed-search'; + options.delayedSearchTime = options.delayedSearchTime || 500; + }, + list: function(id, options, values) { + self.list = new window.List(id, options, values); + }, + callbacks: function(options) { + h.addEvent(h.getByClass(options.delayedSearchClass, self.list.listContainer), 'keyup', self.searchDelayStart); + } + }; + + this.searchDelayStart = function(searchString, columns) { + // TODO: if keycode corresponds to 'ENTER' ? skip delay + // TODO: if search is about to be cleared (empty searchString) ? skip delay + clearTimeout(self.searchTimeout); + self.searchTimeout = window.setTimeout(function() {self.searchDelayEnd(searchString, columns)}, options.delayedSearchTime); + } + + this.searchDelayEnd = function(searchString, columns) { + self.list.search(searchString, columns); + } + + init.start(id, options, values); +} + +window.CustomizedList = CustomizedList; + +})(window); diff --git a/app/views/group_orders/_form.html.haml b/app/views/group_orders/_form.html.haml index 78bccce5..dfac473f 100644 --- a/app/views/group_orders/_form.html.haml +++ b/app/views/group_orders/_form.html.haml @@ -8,7 +8,7 @@ setToleranceBehaviour(#{FoodsoftConfig[:tolerance_is_costly]}); setStockit(#{@order.stockit?}); // create List for search-feature (using list.js, http://listjs.com) - new List(document.body, { valueNames: ['name'], engine: 'unlist' }); + new CustomizedList(document.body, { valueNames: ['name'], engine: 'unlist' }); }); - title t('.title'), false @@ -41,7 +41,7 @@ .row-fluid .well.clear - = text_field_tag :article, params[:article], placeholder: t('.search_article'), class: 'search-query input-large search' + = text_field_tag :article, params[:article], placeholder: t('.search_article'), class: 'search-query input-large delayed-search' = form_for @group_order do |f| = f.hidden_field :lock_version From 6ec81ace18ba8d72350599cb81bd38850eaa49cf Mon Sep 17 00:00:00 2001 From: Julius Date: Sun, 22 Sep 2013 22:04:29 +0200 Subject: [PATCH 13/79] Always show article category headers (do not unlist them on list.js search) --- app/assets/javascripts/list.unlist.js | 6 +++--- app/assets/stylesheets/list.unlist.css | 2 +- app/views/group_orders/_form.html.haml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/list.unlist.js b/app/assets/javascripts/list.unlist.js index f649369f..dc7101ed 100644 --- a/app/assets/javascripts/list.unlist.js +++ b/app/assets/javascripts/list.unlist.js @@ -136,9 +136,9 @@ List.prototype.templateEngines.unlist = function(list, settings) { $(item.elm).removeClass('unlisted'); }; this.hide = function(item) { - if (item.elm !== undefined) { - $(item.elm).addClass('unlisted'); - } + ensure.created(item); + $(item.elm).addClass('unlisted'); + listSource.appendChild(item.elm); }; this.clear = function() { $(listSource.childNodes).addClass('unlisted'); diff --git a/app/assets/stylesheets/list.unlist.css b/app/assets/stylesheets/list.unlist.css index b0ed4600..9fad9603 100644 --- a/app/assets/stylesheets/list.unlist.css +++ b/app/assets/stylesheets/list.unlist.css @@ -1,3 +1,3 @@ -.list .unlisted { +.list .unlisted:not(.no-unlist) { display: none; } \ No newline at end of file diff --git a/app/views/group_orders/_form.html.haml b/app/views/group_orders/_form.html.haml index dfac473f..64e88453 100644 --- a/app/views/group_orders/_form.html.haml +++ b/app/views/group_orders/_form.html.haml @@ -67,8 +67,8 @@ %th{style: "width:15px;"}= t '.sum' %tbody.list - @order.articles_grouped_by_category.each do |category, order_articles| - %tr.article-category - %td.name + %tr.no-unlist.article-category + %td = category %i.icon-tag %td{colspan: "9"} From 3c8f56b24f8c8176c2bc0d0bd509177a69e4bde3 Mon Sep 17 00:00:00 2001 From: Julius Date: Sun, 22 Sep 2013 22:07:34 +0200 Subject: [PATCH 14/79] Add dismiss button to sidebars in group_order form (idea stolen from foodcoops#143) --- app/views/group_orders/_form.html.haml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/views/group_orders/_form.html.haml b/app/views/group_orders/_form.html.haml index 64e88453..9d087687 100644 --- a/app/views/group_orders/_form.html.haml +++ b/app/views/group_orders/_form.html.haml @@ -15,6 +15,7 @@ .row-fluid .well.pull-left + %button{type: "button", class: "close", data: {dismiss: 'alert'}}= '×'.html_safe %h2= @order.name %dl.dl-horizontal - unless @order.note.blank? @@ -37,6 +38,7 @@ %dd= number_to_currency(@ordering_data[:available_funds]) .well.pull-right + %button{type: "button", class: "close", data: {dismiss: 'alert'}}= '×'.html_safe = render 'switch_order', current_order: @order .row-fluid From 9f083dd4d065ec12d38d7ade793a97514a0f92de Mon Sep 17 00:00:00 2001 From: Julius Date: Mon, 23 Sep 2013 21:31:54 +0200 Subject: [PATCH 15/79] Add button to clear article search (list.js customization) --- app/assets/javascripts/list.customized.js | 30 +++++++++++++++++-- .../bootstrap_and_overrides.css.less | 5 ++++ app/views/group_orders/_form.html.haml | 6 +++- config/locales/de.yml | 1 + config/locales/en.yml | 1 + 5 files changed, 40 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/list.customized.js b/app/assets/javascripts/list.customized.js index f95a0e0c..96ca9793 100644 --- a/app/assets/javascripts/list.customized.js +++ b/app/assets/javascripts/list.customized.js @@ -11,30 +11,56 @@ var CustomizedList = function(id, options, values) { this.defaults(options); this.list(id, options, values); this.callbacks(options); + this.onload(options); }, defaults: function(options) { options.delayedSearchClass = options.delayedSearchClass || 'delayed-search'; options.delayedSearchTime = options.delayedSearchTime || 500; + options.highlightClass = options.highlightClass || 'btn-primary'; + options.resetSearchClass = options.resetSearchClass || 'reset-search'; }, list: function(id, options, values) { self.list = new window.List(id, options, values); }, callbacks: function(options) { - h.addEvent(h.getByClass(options.delayedSearchClass, self.list.listContainer), 'keyup', self.searchDelayStart); + var resetSearchButton = h.getByClass(options.resetSearchClass, self.list.listContainer); + $(resetSearchButton).click(self.resetSearch); + self.list.on('updated', self.highlightResetButton); + + var delayedSearchInput = h.getByClass(options.delayedSearchClass, self.list.listContainer); + $(delayedSearchInput).keyup(self.searchDelayStart); + }, + onload: function(options) { + var initialSearchTerm = $('.' + options.delayedSearchClass + ', .' + options.searchClass, self.list.listContainer).val(); + if('' != initialSearchTerm) { + self.list.search(initialSearchTerm); + } } }; this.searchDelayStart = function(searchString, columns) { // TODO: if keycode corresponds to 'ENTER' ? skip delay - // TODO: if search is about to be cleared (empty searchString) ? skip delay clearTimeout(self.searchTimeout); self.searchTimeout = window.setTimeout(function() {self.searchDelayEnd(searchString, columns)}, options.delayedSearchTime); + + var resetSearchButton = h.getByClass(options.resetSearchClass, self.list.listContainer); + $(resetSearchButton).removeClass(options.highlightClass); } this.searchDelayEnd = function(searchString, columns) { self.list.search(searchString, columns); } + this.highlightResetButton = function() { + var resetSearchButton = h.getByClass(options.resetSearchClass, self.list.listContainer); + $(resetSearchButton).toggleClass(options.highlightClass, self.list.searched); + } + + this.resetSearch = function() { + $('.' + options.delayedSearchClass + ', .' + options.searchClass, self.list.listContainer).val(''); + self.list.search(''); + } + init.start(id, options, values); } diff --git a/app/assets/stylesheets/bootstrap_and_overrides.css.less b/app/assets/stylesheets/bootstrap_and_overrides.css.less index 5d595bc2..cce03029 100644 --- a/app/assets/stylesheets/bootstrap_and_overrides.css.less +++ b/app/assets/stylesheets/bootstrap_and_overrides.css.less @@ -238,3 +238,8 @@ tr.unavailable { margin-bottom: 15px } } + +// allow buttons as input add-on (with proper height) +.input-append button.add-on { + height: inherit; +} diff --git a/app/views/group_orders/_form.html.haml b/app/views/group_orders/_form.html.haml index 9d087687..bab7cad7 100644 --- a/app/views/group_orders/_form.html.haml +++ b/app/views/group_orders/_form.html.haml @@ -43,7 +43,11 @@ .row-fluid .well.clear - = text_field_tag :article, params[:article], placeholder: t('.search_article'), class: 'search-query input-large delayed-search' + .form-search + .input-append + = text_field_tag :article, params[:article], placeholder: t('.search_article'), class: 'search-query delayed-search' + %button.add-on.btn.reset-search{:type => :button, :title => t('.reset_article_search')} + %i.icon.icon-remove = form_for @group_order do |f| = f.hidden_field :lock_version diff --git a/config/locales/de.yml b/config/locales/de.yml index ab08d6dc..7e8f67bc 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -787,6 +787,7 @@ de: new_funds: Neuer Kontostand note: Notiz price: Preis + reset_article_search: Suche zurücksetzen search_article: Artikel suchen... sum: Summe sum_amount: ! 'Gesamtbestellmenge bisher:' diff --git a/config/locales/en.yml b/config/locales/en.yml index 18356d73..63d33cfd 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -791,6 +791,7 @@ en: new_funds: New account balance note: Note price: Price + reset_article_search: Reset search search_article: Search for article... sum: Sum sum_amount: Current amount From a87ced2646d2fba206cd1b6b5d5ffdd3c6235fbf Mon Sep 17 00:00:00 2001 From: Julius Date: Tue, 24 Sep 2013 21:21:08 +0200 Subject: [PATCH 16/79] Hide article category if no article matches the search --- app/assets/javascripts/list.customized.js | 8 ++++---- app/assets/javascripts/list.unlist.js | 25 +++++++++++++++++++++++ app/views/group_orders/_form.html.haml | 2 +- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/list.customized.js b/app/assets/javascripts/list.customized.js index 96ca9793..da79cbe1 100644 --- a/app/assets/javascripts/list.customized.js +++ b/app/assets/javascripts/list.customized.js @@ -45,21 +45,21 @@ var CustomizedList = function(id, options, values) { var resetSearchButton = h.getByClass(options.resetSearchClass, self.list.listContainer); $(resetSearchButton).removeClass(options.highlightClass); - } + }; this.searchDelayEnd = function(searchString, columns) { self.list.search(searchString, columns); - } + }; this.highlightResetButton = function() { var resetSearchButton = h.getByClass(options.resetSearchClass, self.list.listContainer); $(resetSearchButton).toggleClass(options.highlightClass, self.list.searched); - } + }; this.resetSearch = function() { $('.' + options.delayedSearchClass + ', .' + options.searchClass, self.list.listContainer).val(''); self.list.search(''); - } + }; init.start(id, options, values); } diff --git a/app/assets/javascripts/list.unlist.js b/app/assets/javascripts/list.unlist.js index dc7101ed..16600077 100644 --- a/app/assets/javascripts/list.unlist.js +++ b/app/assets/javascripts/list.unlist.js @@ -62,6 +62,19 @@ List.prototype.templateEngines.unlist = function(list, settings) { itemSource = getItemSource(settings.item), templater = this; + var init = { + start: function(options) { + this.defaults(options); + this.callbacks(options); + }, + defaults: function(options) { + options.listHeadingsClass = options.listHeadingsClass || 'list-heading'; + }, + callbacks: function(options) { + list.on('updated', templater.updateListHeadings); + } + }; + function getItemSource(item) { if (item === undefined) { var nodes = listSource.childNodes, @@ -143,6 +156,18 @@ List.prototype.templateEngines.unlist = function(list, settings) { this.clear = function() { $(listSource.childNodes).addClass('unlisted'); }; + + this.updateListHeadings = function() { + var headSel = '.' + settings.listHeadingsClass; + + $(headSel, listSource).each(function() { + if( $(this).nextUntil(headSel, ':not(.unlisted)').length ) { + $(this).removeClass('unlisted'); + } + }); + }; + + init.start(settings); }; /******************************************************************************* diff --git a/app/views/group_orders/_form.html.haml b/app/views/group_orders/_form.html.haml index bab7cad7..fbb4da00 100644 --- a/app/views/group_orders/_form.html.haml +++ b/app/views/group_orders/_form.html.haml @@ -73,7 +73,7 @@ %th{style: "width:15px;"}= t '.sum' %tbody.list - @order.articles_grouped_by_category.each do |category, order_articles| - %tr.no-unlist.article-category + %tr.list-heading.article-category %td = category %i.icon-tag From 975bcdec3a484960259e88c5d0b4d33c0e60da30 Mon Sep 17 00:00:00 2001 From: Benjamin Meichsner Date: Wed, 25 Sep 2013 11:57:22 +0200 Subject: [PATCH 17/79] Avoid send messages so STDOUT in rake silen mode. --- lib/tasks/foodsoft.rake | 11 ++++++++--- lib/tasks/multicoops.rake | 10 ++++++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/tasks/foodsoft.rake b/lib/tasks/foodsoft.rake index 04db66f9..df05c1fd 100644 --- a/lib/tasks/foodsoft.rake +++ b/lib/tasks/foodsoft.rake @@ -5,12 +5,12 @@ namespace :foodsoft do task :notify_upcoming_tasks => :environment do tasks = Task.where(done: false, due_date: 1.day.from_now.to_date) for task in tasks - puts "Send notifications for #{task.name} to .." + say "Send notifications for #{task.name} to .." for user in task.users begin Mailer.upcoming_tasks(user, task).deliver if user.settings.notify['upcoming_tasks'] == 1 rescue - puts "deliver aborted for #{user.email}.." + say "deliver aborted for #{user.email}.." end end end @@ -27,7 +27,7 @@ namespace :foodsoft do begin Mailer.not_enough_users_assigned(task, user).deliver rescue - puts "deliver aborted for #{user.email}" + say "deliver aborted for #{user.email}" end end end @@ -47,3 +47,8 @@ namespace :foodsoft do end end end + +# Helper +def say(message) + puts message unless Rake.application.options.silent +end diff --git a/lib/tasks/multicoops.rake b/lib/tasks/multicoops.rake index 621a0d54..130daf40 100644 --- a/lib/tasks/multicoops.rake +++ b/lib/tasks/multicoops.rake @@ -8,7 +8,7 @@ namespace :multicoops do task :run => :environment do task_to_run = ENV['TASK'] FoodsoftConfig.each_coop do |coop| - puts "Run '#{task_to_run}' for #{coop}" + say "Run '#{task_to_run}' for #{coop}" Rake::Task[task_to_run].execute end end @@ -17,8 +17,14 @@ namespace :multicoops do task :run_single => :environment do task_to_run = ENV['TASK'] FoodsoftConfig.select_foodcoop ENV['FOODCOOP'] - puts "Run '#{task_to_run}' for #{ENV['FOODCOOP']}" + say "Run '#{task_to_run}' for #{ENV['FOODCOOP']}" Rake::Task[task_to_run].execute end end + + +# Helper +def say(message) + puts message unless Rake.application.options.silent +end From c1ac95e4400b7ba2ef4eac7c75d9f770a3d21310 Mon Sep 17 00:00:00 2001 From: Julius Date: Wed, 25 Sep 2013 20:58:53 +0200 Subject: [PATCH 18/79] list.unlist.js: Use jQuery's toggleClass instead of native if-else (just for briefness) --- app/assets/javascripts/list.unlist.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/list.unlist.js b/app/assets/javascripts/list.unlist.js index 16600077..1bbc12a7 100644 --- a/app/assets/javascripts/list.unlist.js +++ b/app/assets/javascripts/list.unlist.js @@ -161,9 +161,8 @@ List.prototype.templateEngines.unlist = function(list, settings) { var headSel = '.' + settings.listHeadingsClass; $(headSel, listSource).each(function() { - if( $(this).nextUntil(headSel, ':not(.unlisted)').length ) { - $(this).removeClass('unlisted'); - } + var listedCount = $(this).nextUntil(headSel, ':not(.unlisted)').length; + $(this).toggleClass('unlisted', 0==listedCount); }); }; From 53f24cd885169d4bb0adf2253257fdaabc3dd054 Mon Sep 17 00:00:00 2001 From: Julius Date: Wed, 25 Sep 2013 21:22:34 +0200 Subject: [PATCH 19/79] Fix migrate problem caused by output formating(?) --- db/migrate/20130702113610_update_group_order_totals.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20130702113610_update_group_order_totals.rb b/db/migrate/20130702113610_update_group_order_totals.rb index ca9aab67..f0052ee5 100644 --- a/db/migrate/20130702113610_update_group_order_totals.rb +++ b/db/migrate/20130702113610_update_group_order_totals.rb @@ -7,7 +7,7 @@ class UpdateGroupOrderTotals < ActiveRecord::Migration say "If you do want to update the ordergroup totals, open the rails console " + "(by running `rails c`), and enter:" - say "GroupOrder.all.each { |go| go.order.closed? and go.update_price! }", subitem: true + say "GroupOrder.all.each { |go| go.order.closed? and go.update_price! }" say "You may want to check first that no undesired accounting issues are introduced. " + "It may be wise to discuss this with those responsible for the ordering finances." From 6632f5ed7568eb8fdceb0b6510e0dab6bdb409d9 Mon Sep 17 00:00:00 2001 From: wvengen Date: Mon, 30 Sep 2013 10:57:54 +0200 Subject: [PATCH 20/79] workaround migration bug introduced by 975bcdec3a484960259e88c5d0b4d33c0e60da30 --- lib/tasks/foodsoft.rake | 8 ++++---- lib/tasks/multicoops.rake | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/tasks/foodsoft.rake b/lib/tasks/foodsoft.rake index df05c1fd..1fdd2259 100644 --- a/lib/tasks/foodsoft.rake +++ b/lib/tasks/foodsoft.rake @@ -5,12 +5,12 @@ namespace :foodsoft do task :notify_upcoming_tasks => :environment do tasks = Task.where(done: false, due_date: 1.day.from_now.to_date) for task in tasks - say "Send notifications for #{task.name} to .." + rake_say "Send notifications for #{task.name} to .." for user in task.users begin Mailer.upcoming_tasks(user, task).deliver if user.settings.notify['upcoming_tasks'] == 1 rescue - say "deliver aborted for #{user.email}.." + rake_say "deliver aborted for #{user.email}.." end end end @@ -27,7 +27,7 @@ namespace :foodsoft do begin Mailer.not_enough_users_assigned(task, user).deliver rescue - say "deliver aborted for #{user.email}" + rake_say "deliver aborted for #{user.email}" end end end @@ -49,6 +49,6 @@ namespace :foodsoft do end # Helper -def say(message) +def rake_say(message) puts message unless Rake.application.options.silent end diff --git a/lib/tasks/multicoops.rake b/lib/tasks/multicoops.rake index 130daf40..a14020b7 100644 --- a/lib/tasks/multicoops.rake +++ b/lib/tasks/multicoops.rake @@ -8,7 +8,7 @@ namespace :multicoops do task :run => :environment do task_to_run = ENV['TASK'] FoodsoftConfig.each_coop do |coop| - say "Run '#{task_to_run}' for #{coop}" + rake_say "Run '#{task_to_run}' for #{coop}" Rake::Task[task_to_run].execute end end @@ -17,7 +17,7 @@ namespace :multicoops do task :run_single => :environment do task_to_run = ENV['TASK'] FoodsoftConfig.select_foodcoop ENV['FOODCOOP'] - say "Run '#{task_to_run}' for #{ENV['FOODCOOP']}" + rake_say "Run '#{task_to_run}' for #{ENV['FOODCOOP']}" Rake::Task[task_to_run].execute end @@ -25,6 +25,6 @@ end # Helper -def say(message) - puts message unless Rake.application.options.silent +def rake_say(message) + puts message unless Rake.application.options.silent end From d36f2dd4acc1ff21f2e54b5c3e8e01b018a5e0e5 Mon Sep 17 00:00:00 2001 From: Julius Date: Wed, 25 Sep 2013 23:06:53 +0200 Subject: [PATCH 21/79] Fix minor delivery bug --- app/views/deliveries/add_stock_change.js.erb | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/app/views/deliveries/add_stock_change.js.erb b/app/views/deliveries/add_stock_change.js.erb index 049e6233..3e233bb6 100644 --- a/app/views/deliveries/add_stock_change.js.erb +++ b/app/views/deliveries/add_stock_change.js.erb @@ -5,21 +5,19 @@ $('#stock_changes tr').removeClass('success'); + var quantity = w.prompt('<%= j(t('.how_many_units', :unit => @stock_change.stock_article.unit, :name => @stock_change.stock_article.name)) %>'); + if(null === quantity) { + return false; + } + var stock_change = $( '<%= j(render(:partial => 'stock_change', :locals => {:stock_change => @stock_change})) %>' ).addClass('success'); enablePriceTooltips(stock_change); + $('input.stock-change-quantity', stock_change).val(quantity); $('#stock_changes').append(stock_change); mark_article_for_delivery(<%= @stock_change.stock_article.id %>); updateSort('#stock_changes'); - var quantity = w.prompt('<%= j(t('.how_many_units', :unit => @stock_change.stock_article.unit, :name => @stock_change.stock_article.name)) %>'); <%# how to properly escape here? %> - if(null === quantity) { - stock_change.remove(); - mark_article_for_delivery(<%= @stock_change.stock_article.id %>); - return false; - } - $('input.stock-change-quantity', stock_change).val(quantity); - })(window); From 0bb62332c04b280e9325e09d9cfbe30920dd0901 Mon Sep 17 00:00:00 2001 From: wvengen Date: Tue, 1 Oct 2013 00:05:46 +0200 Subject: [PATCH 22/79] localeapp roundtrip --- config/locales/en.yml | 12 ++-- config/locales/fr.yml | 4 +- config/locales/nl.yml | 142 +++++++++++++++++++++--------------------- 3 files changed, 79 insertions(+), 79 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 02a5bb1f..c3dcfadf 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -430,7 +430,7 @@ en: create: notice: Delivery was created. Please don’t forget to create invoice! create_stock_article: - notice: The new stock article »%{name}« was saved. + notice: The new stock article "%{name}" was saved. destroy: notice: Delivery was deleted. edit: @@ -478,7 +478,7 @@ en: update: notice: Delivery was updated. update_stock_article: - notice: The stock article »%{name}« was updated. + notice: The stock article "%{name}" was updated. documents: order_by_articles: filename: Order %{name}-%{date} - by articles @@ -1313,7 +1313,7 @@ en: prices: Prices (net/FC) select_all: Select all stockit: In stock - supplier: Supplier + supplier: Producer title: Article unit_quantity: Unit quantity index: @@ -1395,7 +1395,7 @@ en: notice: Page was created cshow: error_noexist: Page doesn’t exist! - redirect_notice: Redirected from %{page} .. + redirect_notice: Redirected from %{page} ... destroy: notice: The page '%{page}' and all subpages have been deleted successfully. edit: @@ -1536,7 +1536,7 @@ en: message: private: Message doesn’t show in Foodsoft mail inbox order_article: - units_to_order: If you change the total amount of delivered units, you also have to change individual group amounts by clicking on the article name. They will not be automatically recalculated and otherwise ordergroups will be accounted for undelivered articles! + units_to_order: If you change the total amount of delivered units, you also have to change individual group amounts by clicking on the article name. They will not be automatically recalculated and so ordergroups may be accounted for articles that were not delivered! update_current_price: Also update the price of the current order stock_article: copy_stock_article: @@ -1866,7 +1866,7 @@ en: title: Show task update: notice: Task has been updated - notice_converted: Task has been updated and was converted to a regular task + notice_converted: Task has been updated and was converted to a non-repeating task. user: more: Nothing to do? %{tasks_link} are tasks for sure. tasks_link: Here diff --git a/config/locales/fr.yml b/config/locales/fr.yml index fe52e77e..7ba4c3c7 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -1288,7 +1288,7 @@ fr: article_count: ! 'Articles commandés:' name: Nom prices: Prix brut/net - prices_sum: Totaux (des prix bruts/nets) + prices_sum: ! 'Totaux (des prix bruts/nets):' unit_quantity: Unités par lots x Lots units_full: Lots complet units_ordered: Unités commandées @@ -1536,7 +1536,7 @@ fr: message: private: Le message n'apparaîtra pas dans la boîte de réception du Foodsoft order_article: - units_to_order: Nombre de lots livrés + units_to_order: update_current_price: Modifie aussi le prix des commandes en cours stock_article: copy_stock_article: diff --git a/config/locales/nl.yml b/config/locales/nl.yml index c2f0ee5b..f6e29a95 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -428,11 +428,11 @@ nl: add_stock_change: how_many_units: create: - notice: + notice: Levering is aangemaakt. Vergeet niet een factuur te maken! create_stock_article: - notice: + notice: Nieuw voorraadsartikel "%{name}" gemaakt. destroy: - notice: + notice: Levering is verwijdered. edit: title: form: @@ -476,7 +476,7 @@ nl: remove_article: suppliers_overview: update: - notice: + notice: Levering is bijgewerkt. update_stock_article: notice: documents: @@ -1061,7 +1061,7 @@ nl: text1: messages: create: - notice: + notice: Bericht is opgeslagen en wordt verzonden. index: new: title: @@ -1078,9 +1078,9 @@ nl: subscribe: subscribe_msg: wiki: - no_user_found: - search: - search_user: + no_user_found: Geen gebruiker gevonden + search: Zoeken ... + search_user: Gebruiker zoeken title: show: all_messages: @@ -1091,15 +1091,15 @@ nl: title: model: delivery: - each_stock_article_must_be_unique: + each_stock_article_must_be_unique: In een levering mag ieder voorraadsartikel maar een keer voorkomen. membership: - no_admin_delete: + no_admin_delete: Lidmaatschap kan niet beeindigd worden. Je bent de laatste administrator. order_article: - error_price: + error_price: moet ingevuld worden en een huidige prijs hebben page: - redirect: + redirect: Doorverwijzing naar [[%{title}]]... user: - no_ordergroup: + no_ordergroup: geen huishouden navigation: admin: home: Overzicht @@ -1187,46 +1187,46 @@ nl: delimiter: ordergroups: edit: - title: + title: Huidhouden bewerken index: - title: + title: Huishoudens model: - error_single_group: - invalid_balance: + error_single_group: ! '%{user} behoort al tot een ander huishouden' + invalid_balance: is geen geldig nummer orders: articles: - article_count: - name: - prices: - prices_sum: - unit_quantity: - units_full: - units_ordered: + article_count: ! 'Bestelde artikelen:' + name: Naam + prices: Netto/bruto prijs + prices_sum: ! 'Totaal (netto/bruto prijs):' + unit_quantity: Groothandelseenheid + units_full: Volle eenheden + units_ordered: Bestelde eenheden create: - notice: + notice: De bestelling is aangemaakt. edit: - title: + title: Bestelling aanpassen fax: - amount: - articles: - customer_number: - delivery_day: - heading: - name: - number: - to_address: + amount: Aantal + articles: Artikelen + customer_number: Klantnummer + delivery_day: Bezorgdag + heading: Bestelling voor %{name} + name: Naam + number: Nummer + to_address: Verzendadres finish: notice: De bestelling is gesloten. form: - ignore_warnings: - name: - note: - origin: - prices: - select_all: - stockit: - supplier: - title: + ignore_warnings: Waarschuwingen negeren + name: Naam + note: Notitie + origin: Herkomst + prices: Prijs (netto/FC) + select_all: Alles selecteren + stockit: Beschikbaar + supplier: Producent + title: Artikel unit_quantity: index: action_end: @@ -1244,7 +1244,7 @@ nl: error_closed: Bestelling was al afgerekend error_nosel: error_starts_before_ends: - notice_close: + notice_close: ! 'Bestelling: %{name}, tot %{ends}' stock: Voorraad warning_ordered: warning_ordered_stock: @@ -1288,7 +1288,7 @@ nl: finished: gesloten open: lopend update: - notice: + notice: De bestelling is bijgewerkt. pages: all: new_page: @@ -1302,12 +1302,12 @@ nl: body: title_toc: create: - notice: + notice: Pagina is gemaakt. cshow: error_noexist: - redirect_notice: + redirect_notice: Doorverwezen van %{page} ... destroy: - notice: + notice: De pagina '%{page}' en alle subpagina's zijn verwijderd. edit: title: error_stale_object: @@ -1351,7 +1351,7 @@ nl: versions: title: update: - notice: + notice: Pagina is bijgewerkt. version: author: date_format: @@ -1394,11 +1394,11 @@ nl: address: Adres apple_limit: contact: Contact - deactivated: - description: + deactivated: inactief + description: Beschrijving members: Leden - no_weekly_job: - weekly_job: + no_weekly_job: geen wekelijkse taak ingesteld + weekly_job: wekelijkse taak group_form_fields: search: Zoeken ... search_user: Gebruiker zoeken @@ -1407,8 +1407,8 @@ nl: loginInfo: edit_profile: Profiel aanpassen feedback: - desc: - title: + desc: Fout gevonden? Opmerking? Idee? + title: Feedback help: Help homepage_title: Foodcoop startpagina bezoeken logout: Uitloggen @@ -1436,7 +1436,7 @@ nl: total_sum: Totaalsom who_ordered: Wie heeft besteld? workgroup_members: - title: + title: Groepsleden simple_form: error_notification: default_message: @@ -1550,7 +1550,7 @@ nl: address: contact_person: customer_number: - delivery_days: + delivery_days: Bezorgdagen email: fax: is_subscribed: @@ -1601,7 +1601,7 @@ nl: 'yes': Ja stock_takings: create: - notice: + notice: Inventarisatie is aangelegd. edit: title: index: @@ -1629,12 +1629,12 @@ nl: date: note: update: - notice: + notice: Inventarisatie is bijgewerkt. stockit: check: not_empty: destroy: - notice: + notice: Artikel %{name} is verwijdered. edit: title: form: @@ -1674,14 +1674,14 @@ nl: search_text: title: stock_create: - notice: + notice: Voorraadsartikel is opgeslagen. stock_update: - notice: + notice: Voorraadsartikel is bijgewerkt. suppliers: create: - notice: + notice: Leverancier is aangemaakt. destroy: - notice: + notice: Leverancier is verwijderd edit: title: index: @@ -1707,7 +1707,7 @@ nl: new_delivery: show_deliveries: update: - notice: + notice: Leverancier is bijgewerkt support: array: last_word_connector: @@ -1715,7 +1715,7 @@ nl: words_connector: tasks: accept: - notice: + notice: Je hebt de taak geaccepteerd archive: title: archive_tasks: @@ -1724,9 +1724,9 @@ nl: task_format: who: create: - notice: + notice: Taak is aangemaakt destroy: - notice: + notice: Taak is verwijderd edit: title: warning_periodic: @@ -1764,7 +1764,7 @@ nl: title: repeated: set_done: - notice: + notice: De status van de taak is aangepast show: accept_task: confirm_delete_group: @@ -1775,8 +1775,8 @@ nl: reject_task: title: update: - notice: - notice_converted: + notice: Taak is bijgewerkt + notice_converted: Taak is bijgewerkt en omgezet naar een eenmalige taak. user: more: tasks_link: From 9ac9d1ea50413f32169f7c98edeadad11bc7d248 Mon Sep 17 00:00:00 2001 From: wvengen Date: Wed, 2 Oct 2013 16:32:01 +0200 Subject: [PATCH 23/79] add spec for foodcoops/foodsoft#179 --- spec/integration/balancing_spec.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/spec/integration/balancing_spec.rb b/spec/integration/balancing_spec.rb index 2bf860be..eba7973e 100644 --- a/spec/integration/balancing_spec.rb +++ b/spec/integration/balancing_spec.rb @@ -103,6 +103,23 @@ describe 'settling an order', :type => :feature do expect(GroupOrderArticle.exists?(goa1.id)).to be_false end + it 'keeps product when amount is set to zero' do + within("#order_article_#{oa.id}") do + click_link I18n.t('ui.edit') + end + within("#edit_order_article_#{oa.id}") do + fill_in :order_article_units_to_order, :with => 0 + find('input[type="submit"]').click + end + expect(page).to have_selector("#order_article_#{oa.id}") + # make sure it still works after reloading + visit new_finance_order_path(order_id: order.id) + expect(page).to have_selector("#order_article_#{oa.id}") + expect(OrderArticle.exists?(oa.id)).to be_true + oa.reload + expect(oa.units_to_order).to eq(0) + end + end end From 6cfaa4979a6e76a7f2987ecaef413bdbafcf80fc Mon Sep 17 00:00:00 2001 From: wvengen Date: Wed, 2 Oct 2013 16:32:29 +0200 Subject: [PATCH 24/79] show lines with zero units but with member orders in balancing screen (closes foodcoops/foodsoft#179) --- app/controllers/finance/balancing_controller.rb | 2 +- app/models/order_article.rb | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/controllers/finance/balancing_controller.rb b/app/controllers/finance/balancing_controller.rb index 8528e4d3..8de1444c 100644 --- a/app/controllers/finance/balancing_controller.rb +++ b/app/controllers/finance/balancing_controller.rb @@ -10,7 +10,7 @@ class Finance::BalancingController < Finance::BaseController flash.now.alert = t('finance.balancing.new.alert') if @order.closed? @comments = @order.comments - @articles = @order.order_articles.ordered.includes(:article, :article_price, + @articles = @order.order_articles.ordered_or_member.includes(:article, :article_price, group_order_articles: {group_order: :ordergroup}) sort_param = params['sort'] || 'name' diff --git a/app/models/order_article.rb b/app/models/order_article.rb index 85a0da79..bd90706b 100644 --- a/app/models/order_article.rb +++ b/app/models/order_article.rb @@ -12,7 +12,8 @@ class OrderArticle < ActiveRecord::Base validate :article_and_price_exist validates_uniqueness_of :article_id, scope: :order_id - scope :ordered, :conditions => "units_to_order >= 1" + scope :ordered, :conditions => "units_to_order > 0" + scope :ordered_or_member, -> { includes(:group_order_articles).where("units_to_order > 0 OR group_order_articles.result > 0") } before_create :init_from_balancing after_destroy :update_ordergroup_prices From 1d8fefcfb74a50d57108a0a2dc7078098ac83c7b Mon Sep 17 00:00:00 2001 From: wvengen Date: Wed, 2 Oct 2013 17:08:24 +0200 Subject: [PATCH 25/79] small i18n update --- app/views/invites/new.html.haml | 2 +- config/locales/de.yml | 1 - config/locales/en.yml | 1 - config/locales/fr.yml | 1 - config/locales/nl.yml | 1 - 5 files changed, 1 insertion(+), 5 deletions(-) diff --git a/app/views/invites/new.html.haml b/app/views/invites/new.html.haml index eb9081cb..2332db00 100644 --- a/app/views/invites/new.html.haml +++ b/app/views/invites/new.html.haml @@ -4,4 +4,4 @@ = form.hidden_field :group_id = form.input :email = form.submit t('.action') - = link_to t('.back'), :back + = link_to t('ui.or_cancel'), :back diff --git a/config/locales/de.yml b/config/locales/de.yml index 1663cc07..d46ea8d3 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -971,7 +971,6 @@ de: title: Person einladen new: action: Einlading abschicken - back: oder zurück body:

Hier kannst du eine Person in die Gruppe %{group} einladen, die noch nicht Mitglied der Foodcoop ist.

success: Benutzerin wurde erfolgreich eingeladen. layouts: diff --git a/config/locales/en.yml b/config/locales/en.yml index c3dcfadf..bdb867c3 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -975,7 +975,6 @@ en: title: Invite person new: action: Send invite - back: or go back body:

Here you can add a person to the group %{group}, who is not yet a member of the foodcoop.

success: User was invited successfully. layouts: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 7ba4c3c7..f4d809c4 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -994,7 +994,6 @@ fr: title: Engrainer une personne new: action: Engrainer! - back: ou revenir en arrière body:

Sur cette page, tu peux engrainer une personne qui ne fait pas encore partie de la Boufcoop à rejoindre la cellule %{group} success: La_le membre a été engrainéE avec succès! layouts: diff --git a/config/locales/nl.yml b/config/locales/nl.yml index f6e29a95..abf19a21 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -972,7 +972,6 @@ nl: title: new: action: - back: body: success: layouts: From a8ace3bc79309b9df163458e6716cff863084656 Mon Sep 17 00:00:00 2001 From: wvengen Date: Wed, 2 Oct 2013 17:13:49 +0200 Subject: [PATCH 26/79] add missing i18n --- app/controllers/application_controller.rb | 6 +++--- config/locales/de.yml | 5 +++++ config/locales/en.yml | 5 +++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 96b2e510..9c77fe48 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -26,7 +26,7 @@ class ApplicationController < ActionController::Base def deny_access session[:return_to] = request.original_url - redirect_to login_url, :alert => 'Access denied!' + redirect_to login_url, :alert => I18n.t('application.controller.error_denied') end private @@ -37,7 +37,7 @@ class ApplicationController < ActionController::Base # No user at all: redirect to login page. session[:user_id] = nil session[:return_to] = request.original_url - redirect_to login_url, :alert => 'Authentication required!' + redirect_to login_url, :alert => I18n.t('application.controller.error_authn') else # We have an authenticated user, now check role... # Roles gets the user through his memberships. @@ -83,7 +83,7 @@ class ApplicationController < ActionController::Base def authenticate_membership_or_admin @group = Group.find(params[:id]) unless @group.member?(@current_user) or @current_user.role_admin? - redirect_to root_path, alert: "Diese Aktion ist nur für Mitglieder der Gruppe erlaubt!" + redirect_to root_path, alert: I18n.t('application.controller.error_members_only') end end diff --git a/config/locales/de.yml b/config/locales/de.yml index d46ea8d3..f562bf87 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -212,6 +212,11 @@ de: workgroups: members: Mitglieder name: Name + application: + controller: + error_denied: + error_authn: + error_members_only: 'Diese Aktion ist nur für Mitglieder der Gruppe erlaubt!' article_categories: create: notice: Die Kategorie wurde gespeichert diff --git a/config/locales/en.yml b/config/locales/en.yml index bdb867c3..e42480e3 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -212,6 +212,11 @@ en: workgroups: members: members name: name + application: + controller: + error_denied: 'Access denied!' + error_authn: 'Authentication required!' + error_members_only: 'This action is only available to members of the group!' article_categories: create: notice: Category was stored From 17bbb0705b960cc80aefa54aa15e585ff111fa4a Mon Sep 17 00:00:00 2001 From: wvengen Date: Wed, 2 Oct 2013 17:23:49 +0200 Subject: [PATCH 27/79] fix i18n --- .../finance/financial_transactions_controller.rb | 8 ++++---- config/locales/de.yml | 12 +++++++----- config/locales/en.yml | 12 +++++++----- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/app/controllers/finance/financial_transactions_controller.rb b/app/controllers/finance/financial_transactions_controller.rb index a129a49d..8865958e 100644 --- a/app/controllers/finance/financial_transactions_controller.rb +++ b/app/controllers/finance/financial_transactions_controller.rb @@ -34,7 +34,7 @@ class Finance::FinancialTransactionsController < ApplicationController @financial_transaction = FinancialTransaction.new(params[:financial_transaction]) @financial_transaction.user = current_user @financial_transaction.add_transaction! - redirect_to finance_ordergroup_transactions_url(@ordergroup), notice: t('finance.financial_transactions.create.notice') + redirect_to finance_ordergroup_transactions_url(@ordergroup), notice: I18n.t('finance.financial_transactions.controller.create.notice') rescue ActiveRecord::RecordInvalid => error flash.now[:alert] = error.message render :action => :new @@ -44,16 +44,16 @@ class Finance::FinancialTransactionsController < ApplicationController end def create_collection - raise "Notiz wird benötigt!" if params[:note].blank? + raise I18n.t('finance.financial_transactions.controller.create_collection.error_note_required') if params[:note].blank? params[:financial_transactions].each do |trans| # ignore empty amount fields ... unless trans[:amount].blank? Ordergroup.find(trans[:ordergroup_id]).add_financial_transaction!(trans[:amount], params[:note], @current_user) end end - redirect_to finance_ordergroups_url, notice: t('finance.create_collection.create.notice') + redirect_to finance_ordergroups_url, notice: I18n.t('finance.financial_transactions.controller.create_collection.notice') rescue => error - redirect_to finance_new_transaction_collection_url, alert: t('finance.create_collection.create.alert', error: error.to_s) + redirect_to finance_new_transaction_collection_url, alert: I18n.t('finance.financial_transactions.controller.create_collection.alert', error: error.to_s) end protected diff --git a/config/locales/de.yml b/config/locales/de.yml index f562bf87..b956b3f3 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -649,11 +649,13 @@ de: create: notice: Rechnung wurde erstellt. financial_transactions: - create: - notice: Die Transaktion wurde gespeichert. - create_collection: - alert: ! 'Ein Fehler ist aufgetreten: %{error}' - notice: Alle Transaktionen wurden gespeichert. + controller: + create: + notice: Die Transaktion wurde gespeichert. + create_collection: + alert: ! 'Ein Fehler ist aufgetreten: %{error}' + error_note_required: ! 'Notiz wird benötigt!' + notice: Alle Transaktionen wurden gespeichert. index: balance: ! 'Kontostand: %{balance}' last_updated_at: (zuletzt aktualisiert vor %{when}) diff --git a/config/locales/en.yml b/config/locales/en.yml index e42480e3..2c89b7f1 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -653,11 +653,13 @@ en: create: notice: Invoice was created financial_transactions: - create: - notice: The transaction was saved. - create_collection: - alert: ! 'An error occured: %{error}' - notice: All transactions were saved. + controller: + create: + notice: The transaction was saved. + create_collection: + alert: ! 'An error occured: %{error}' + error_note_required: ! 'Note is required!' + notice: All transactions were saved. index: balance: ! 'Balance of account: %{balance}' last_updated_at: (last updated %{when} ago) From 3574f239c6fa7e309a43937383b9bf29c274fc4e Mon Sep 17 00:00:00 2001 From: wvengen Date: Wed, 2 Oct 2013 17:33:37 +0200 Subject: [PATCH 28/79] localeapp roundtrip --- config/locales/de.yml | 8 ++--- config/locales/en.yml | 10 +++--- config/locales/fr.yml | 17 +++++++--- config/locales/nl.yml | 77 ++++++++++++++++++++++++++++--------------- 4 files changed, 72 insertions(+), 40 deletions(-) diff --git a/config/locales/de.yml b/config/locales/de.yml index b956b3f3..a0a0e3a7 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -214,9 +214,9 @@ de: name: Name application: controller: - error_denied: - error_authn: - error_members_only: 'Diese Aktion ist nur für Mitglieder der Gruppe erlaubt!' + error_authn: + error_denied: + error_members_only: Diese Aktion ist nur für Mitglieder der Gruppe erlaubt! article_categories: create: notice: Die Kategorie wurde gespeichert @@ -654,7 +654,7 @@ de: notice: Die Transaktion wurde gespeichert. create_collection: alert: ! 'Ein Fehler ist aufgetreten: %{error}' - error_note_required: ! 'Notiz wird benötigt!' + error_note_required: Notiz wird benötigt! notice: Alle Transaktionen wurden gespeichert. index: balance: ! 'Kontostand: %{balance}' diff --git a/config/locales/en.yml b/config/locales/en.yml index 2c89b7f1..b13f4707 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -214,9 +214,9 @@ en: name: name application: controller: - error_denied: 'Access denied!' - error_authn: 'Authentication required!' - error_members_only: 'This action is only available to members of the group!' + error_authn: Authentication required! + error_denied: Access denied! + error_members_only: This action is only available to members of the group! article_categories: create: notice: Category was stored @@ -658,7 +658,7 @@ en: notice: The transaction was saved. create_collection: alert: ! 'An error occured: %{error}' - error_note_required: ! 'Note is required!' + error_note_required: Note is required! notice: All transactions were saved. index: balance: ! 'Balance of account: %{balance}' @@ -905,7 +905,7 @@ en: warning: Warning, if you have less then %{threshold} of apple points, you are not allowed to place an order! changes_saved: Changes saved. index: - due_date_format: ! '%A %d %b' + due_date_format: ! '%A %d %B' messages: title: Newest Messages view_all: See all messages diff --git a/config/locales/fr.yml b/config/locales/fr.yml index f4d809c4..18e2cfea 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -212,6 +212,11 @@ fr: workgroups: members: membres name: nom + application: + controller: + error_authn: + error_denied: + error_members_only: article_categories: create: notice: La catégorie a bien été définie. @@ -655,11 +660,13 @@ fr: create: notice: La facture a bien été définie. financial_transactions: - create: - notice: La transaction a été sauvegardée. - create_collection: - alert: ! 'Une erreur s''est produite: %{error}' - notice: Les transactions ont été sauvegardées. + controller: + create: + notice: La transaction a été sauvegardée. + create_collection: + alert: ! 'Une erreur s''est produite: %{error}' + error_note_required: + notice: Les transactions ont été sauvegardées. index: balance: ! 'Solde: %{balance}' last_updated_at: (dernière mise à jour il y a %{when}) diff --git a/config/locales/nl.yml b/config/locales/nl.yml index abf19a21..221d9373 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -212,6 +212,11 @@ nl: workgroups: members: leden name: naam + application: + controller: + error_authn: Inloggen vereist. + error_denied: Geen toegang. + error_members_only: Deze actie is alleen beschikbaar voor leden van de groep! article_categories: create: notice: Categorie is opgeslagen @@ -645,11 +650,13 @@ nl: create: notice: Rekening is gemaakt financial_transactions: - create: - notice: De transactie is opgeslagen. - create_collection: - alert: - notice: Alle transacties zijn opgeslagen. + controller: + create: + notice: De transactie is opgeslagen. + create_collection: + alert: + error_note_required: Notitie ontbreekt. + notice: Alle transacties zijn opgeslagen. index: balance: ! 'Tegoed: %{balance}' last_updated_at: (laatst bijgewerkt %{when} geleden) @@ -668,8 +675,8 @@ nl: sidebar: title: ordergroup: - remove: - remove_group: + remove: Verwijderen + remove_group: Huishouden verwijderen transactions: amount: Bedrag date: Datum @@ -856,7 +863,7 @@ nl: title: Lopende bestellingen update: error_general: - error_stale: + error_stale: In de tussentijd heeft iemand anders ook bestelt, daarom kon je bestelling niet opgeslagen worden. Sorry! notice: De bestelling is opgeslagen. helpers: application: @@ -890,19 +897,19 @@ nl: home: apple_bar: desc: - more_info: + more_info: Meer informatie points: warning: changes_saved: Wijzigingen opgeslagen. index: - due_date_format: + due_date_format: ! '%A %d %B' messages: title: view_all: my_ordergroup: - funds: - last_update: - title: + funds: ! '| Beschikbaar tegoed:' + last_update: Laatst gewijzigd %{when} geleden + title: Mijn huishouden transactions: amount: Bedrag note: Notitie @@ -913,13 +920,13 @@ nl: ordergroup: title: tasks_move: - action: - desc: - title: + action: Taken op je nemen/annuleren + desc: Je bent voor de volgende taken verantwoordelijk. + title: Taken op je nemen tasks_open: - action: - desc: - title: + action: open taken + desc: Er zijn %{size} + title: open taken title: Beginpagina your_tasks: Jouw taken no_ordergroups: Jammergenoeg ben je niet aangesloten bij een huishouden. @@ -946,7 +953,7 @@ nl: admin: finances: accounts: Tegoeden bijwerken - settle: + settle: Bestelling afrekenen title: Financiën foodcoop: Foodcoop members: Leden @@ -1051,13 +1058,31 @@ nl: Vriendelijke groet van %{foodcoop}.' reset_password: - subject: - text: + subject: Nieuw wachtwoord voor %{username} + text: ! 'Beste %{user}, + + + Jij (of iemand anders) heeft een nieuw wachtwoord aangevraagd voor het foodcoop ordersysteem. + + Ga naar de volgende pagina om een nieuw wachtwoord in te voeren: %{link} + + Dit kan slechts éenmaal gedaan worden, en op zijn laatst op %{expires}. + + Wanneer je je wachtwoord niet wilt veranderen, hoef je niets te doen; dan blijft je huidige wachtwoord geldig. + + + Groeten van je foodcoop!' upcoming_tasks: - nextweek: - subject: - text0: - text1: + nextweek: ! 'Taken voor komende week:' + subject: Er is een taak te doen! + text0: ! 'Beste %{user}, + + + Je bent opgegeven voor "%{task}". Deze taak is morgen te vervullen (%{when})!' + text1: ! 'Mijn taken: %{user_tasks_url} + + + Groeten van %{foodcoop}.' messages: create: notice: Bericht is opgeslagen en wordt verzonden. From 75e858db71feb3f6c20a25a4fc3c2b8706997b5e Mon Sep 17 00:00:00 2001 From: wvengen Date: Wed, 2 Oct 2013 22:55:14 +0200 Subject: [PATCH 29/79] bundle update --- Gemfile.lock | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 059ef232..a9112511 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -51,7 +51,7 @@ GEM erubis (>= 2.6.6) binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) - bootstrap-datepicker-rails (1.1.1.7) + bootstrap-datepicker-rails (1.1.1.8) railties (>= 3.0) builder (3.0.4) bullet (4.6.0) @@ -95,7 +95,7 @@ GEM exception_notification (4.0.1) actionmailer (>= 3.0.4) activesupport (>= 3.0.4) - execjs (2.0.1) + execjs (2.0.2) expression_parser (0.9.0) factory_girl (4.2.0) activesupport (>= 3.0.0) @@ -214,20 +214,20 @@ GEM rake (10.1.0) rdoc (3.12.2) json (~> 1.4) - redis (3.0.4) + redis (3.0.5) redis-namespace (1.3.1) redis (~> 3.0.0) ref (1.0.5) - responders (1.0.0.rc) + responders (1.0.0) railties (>= 3.2, < 5) - resque (1.25.0) + resque (1.25.1) mono_logger (~> 1.0) multi_json (~> 1.0) redis-namespace (~> 1.2) sinatra (>= 0.9.2) vegas (~> 0.1.2) rspec-core (2.14.5) - rspec-expectations (2.14.2) + rspec-expectations (2.14.3) diff-lcs (>= 1.1.3, < 2.0) rspec-mocks (2.14.3) rspec-rails (2.14.0) @@ -240,13 +240,12 @@ GEM ruby-prof (0.13.0) ruby-rc4 (0.1.5) rubyzip (0.9.9) - sass (3.2.10) + sass (3.2.11) sass-rails (3.2.6) railties (~> 3.2.0) sass (>= 3.1.10) tilt (~> 1.3) - select2-rails (3.4.8) - sass-rails + select2-rails (3.5.0) thor (~> 0.14) selenium-webdriver (2.35.1) childprocess (>= 0.2.5) From 1674dcf851db372ad236925fdd19e156c6003630 Mon Sep 17 00:00:00 2001 From: wvengen Date: Thu, 3 Oct 2013 14:07:03 +0200 Subject: [PATCH 30/79] fix i18n of article sync --- app/views/articles/sync.html.haml | 7 +++---- config/locales/de.yml | 8 +++++--- config/locales/en.yml | 18 ++++++++++-------- config/locales/fr.yml | 6 ++++-- config/locales/nl.yml | 16 +++++++++------- 5 files changed, 31 insertions(+), 24 deletions(-) diff --git a/app/views/articles/sync.html.haml b/app/views/articles/sync.html.haml index d740cb6e..1039aee4 100644 --- a/app/views/articles/sync.html.haml +++ b/app/views/articles/sync.html.haml @@ -1,4 +1,4 @@ -- title 'Artikel mit externer Datenbank synchronisieren' +- title t('.title') = form_tag update_synchronized_supplier_articles_path(@supplier) do %h2= t '.outlist.title' @@ -19,9 +19,8 @@ %h2= t '.update.title' %p %i - %b= @updated_articles.size - = t '.update.update_msg' - = t('.update.body').html_safe + = t '.update.update_msg', count: @updated_articles.size + = t '.update.body' %table.table %thead %tr diff --git a/config/locales/de.yml b/config/locales/de.yml index a0a0e3a7..893739d6 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -310,18 +310,20 @@ de: error_nosel: Du hast keine Artikel ausgewählt parse_upload: body:

Bitte überprufe die engelesenen Artikel.

Achtung, momentan gibt es keine Überprüfung auf doppelte Artikel.

+ title: + sync: outlist: body: ! 'Folgende Artikel wurden ausgelistet und werden gelöscht:' body_skip: Es müssen keine Artikel gelöscht werden. title: Auslisten ... price_short: Preis - submit: Alle löschen/aktualisieren + submit: Alle synchronisieren title: Artikel mit externer Datenbank synchronisieren unit_quantity_short: GebGr update: - body:

Jeder Artikel wird doppelt angezeigt. Die alten Werte sind grau und die Textfelder sind mit den aktuellen Werten vorausgefüllt.

Abweichungen zu den alten Artikeln sind gelb markiert.

+ body: ! 'Jeder Artikel wird doppelt angezeigt: die alten Werte sind grau und die Textfelder sind mit den aktuellen Werten vorausgefüllt. Abweichungen zu den alten Artikeln sind gelb markiert.' title: Aktualisieren ... - update_msg: ! 'Artikel müssen aktualisiert werden:' + update_msg: ! '%{count} Artikel müssen aktualisiert werden.' upload: body:

Die Datei muss eine Textdatei mit der Endung '.csv' sein. Die erste Zeile wird beim Einlesen ignoriert.

Die Felder müssen mit einem Semikolon (';') getrennt und der Text mit doppelten Anführungszeichen ("Text...") umklammert werden.

Als Zeichensatz wird UTF-8 erwartet. Korrekte Reihenfolge der Spalten:

fields: diff --git a/config/locales/en.yml b/config/locales/en.yml index b13f4707..915f4341 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -310,20 +310,22 @@ en: error_nosel: You have selected no articles parse_upload: body:

Please verify the articles.

Warning, at the moment there is no check for duplicate articles.

+ title: Upload articles + sync: outlist: - body: ! 'The following articles were outlisted and deleted:' + body: ! 'The following articles were removed from the list and will be deleted:' body_skip: No articles to delete. - title: Outlist ... + title: Remove from list ... price_short: Price - submit: Delete/update all + submit: Synchronize all title: Synchronize articles with external database - unit_quantity_short: unit quantity + unit_quantity_short: Unit quantity update: - body: ! '

Every article is shown twice. The old values are gray and the text fields contain the current values.

- -

Differences with the old articles are marked yellow.

' + body: ! 'Every article is shown twice: old values are gray, while the text fields contain updated values. Differences with the old articles are marked yellow.' title: Update ... - update_msg: ! 'Articles must be updated:' + update_msg: + one: One article needs to be updated. + other: ! '%{count} articles need to be updated.' upload: body:

The file has to be a text file with the ending '.csv' The first line will be ignored when imported

The fields have to be separated with semicolons (';') and the text enclosed by double quotation marks ("text...").

As character set UTF-8 is demanded. Correct order of the column:

fields: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 18e2cfea..2c176d31 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -312,6 +312,8 @@ fr: body: ! '

Merci de vérifier les articles importés.

Attention, les doublons ne sont pas automatiquement détectés.

.' + title: + sync: outlist: body: ! 'Les articles suivants ne sont plus dans la liste et seront donc supprimés:' body_skip: Aucun article à supprimer. @@ -321,9 +323,9 @@ fr: title: Synchroniser les articles avec la base de données extérieure unit_quantity_short: U/L update: - body:

Chaque article apparaît deux fois. Les anciennes données sont rappelées en gris, et les champs du formulaire ont été préremplis avec les nouvelles valeurs.

Les changements sont marqués en jaune.

+ body: ! 'Chaque article apparaît deux fois: les anciennes données sont rappelées en gris, et les champs du formulaire ont été préremplis avec les nouvelles valeurs. Les changements sont marqués en jaune.' title: Mettre à jour... - update_msg: ! 'Ces articles doivent être mis à jour:' + update_msg: upload: body: ! '

Le fichier doit être au format texte et son nom doit se terminer par l''extension ".csv". La première ligne sera ignorée lors de l''importation.

diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 221d9373..05b3ea5e 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -310,20 +310,22 @@ nl: error_nosel: Je hebt geen artikelen geselecteerd parse_upload: body:

Ingelezen artikelen graag controleren.

Let op, momenteel vind er geen controle op dubbele artikelen plaats.

+ title: + sync: outlist: - body: ! 'De volgende artikelen werden uit de lijst gehaald en worden gewist:' - body_skip: Er zijn geen artikelen om te wissen. + body: ! 'De volgende artikelen zijn uit de lijst gehaald en worden verwijderd:' + body_skip: Er zijn geen artikelen om te verwijderen. title: Uit de lijst halen ... price_short: prijs - submit: Alle wissen/bijwerken + submit: Alles synchroniseren title: Artikelen met externe database synchroniseren unit_quantity_short: Gr.Eenh. update: - body: ! '

Ieder artikel wordt tweemaal getoond. De oude waarden zijn grijs, en de tekstvelden bevatten de huidige waarden.

- -

Verschillen met de oude artikelen zijn geel gemarkeerd.

' + body: ! 'Ieder artikel wordt tweemaal getoond: oude waarden zijn grijs, en de tekstvelden bevatten de nieuwe waarden. Verschillen met de oude artikelen zijn geel gemarkeerd.' title: Bijwerken ... - update_msg: ! 'De volgende artikelen moeten bijgewerkt worden: ' + update_msg: + one: Er moet éen artikel bijgewerkt worden. + other: Er moeten %{count} artikelen bijgewerkt worden. upload: body: fields: From bbcad49831f9ec7872cc15981261b58e47fc6b37 Mon Sep 17 00:00:00 2001 From: wvengen Date: Thu, 3 Oct 2013 16:03:13 +0200 Subject: [PATCH 31/79] start moving from simple_form i18n to activerecord --- app/helpers/application_helper.rb | 14 +++++++ app/views/article_categories/index.html.haml | 4 +- app/views/articles/_articles.html.haml | 17 ++++----- app/views/articles/_edit_all_table.html.haml | 24 +++++------- .../articles/_import_search_results.haml | 14 +++---- app/views/articles/sync.html.haml | 20 +++++----- app/views/articles/upload.html.haml | 22 +++++------ config/locales/en.yml | 37 ++++++++++--------- 8 files changed, 81 insertions(+), 71 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 167a558d..c9caff30 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -73,6 +73,20 @@ module ApplicationHelper link_to(text, url_for(url_options), html_options) end + + # Generates text for table heading for model attribute + # When the 'short' option is true, abbreviations will be used: + # When there is a non-empty model attribute 'foo', it looks for + # the model attribute translation 'foo_short' and use that as + # heading, with an acronym title of 'foo'. + def heading_helper(model, attribute, options = {}) + s = model.human_attribute_name(attribute) + if options[:short] + sshort = model.human_attribute_name("#{attribute}_short".to_sym, default: '') + s = raw "#{sshort}" unless sshort.empty? + end + s + end # Generates a link to the top of the website def link_to_top diff --git a/app/views/article_categories/index.html.haml b/app/views/article_categories/index.html.haml index dc18f042..0ec33119 100644 --- a/app/views/article_categories/index.html.haml +++ b/app/views/article_categories/index.html.haml @@ -5,8 +5,8 @@ %table.table.table-striped %thead %tr - %th= t('simple_form.labels.article_category.name') - %th= t('simple_form.labels.article_category.description') + %th= heading_helper ArticleCategory, :article_category + %th= heading_helper ArticleCategory, :description %th %tbody - @article_categories.each do |article_category| diff --git a/app/views/articles/_articles.html.haml b/app/views/articles/_articles.html.haml index fd00f23d..e8a1c7b1 100644 --- a/app/views/articles/_articles.html.haml +++ b/app/views/articles/_articles.html.haml @@ -6,16 +6,15 @@ %thead %tr %th - %th= sort_link_helper t('simple_form.labels.article.name'), "name" + %th= sort_link_helper heading_helper(Article, :name), "name" %th - %th= sort_link_helper t('simple_form.labels.article.article_category'), "category" - %th= sort_link_helper t('simple_form.labels.article.unit'), "unit" - %th= sort_link_helper t('simple_form.labels.article.note'), "note" - %th{:style => "width: 4em;"} - %acronym{:title => t('.unit_quantity_desc')}= t '.unit_quantity_short' - %th{:style => "width: 5em;"}= t '.price_netto' - %th{:style => "width: 3.5em;"}= t 'simple_form.labels.defaults.tax' - %th{:style => "width: 4em;"}= t 'simple_form.labels.defaults.deposit' + %th= sort_link_helper heading_helper(Article, :category), "category" + %th= sort_link_helper heading_helper(Article, :unit), "unit" + %th= sort_link_helper heading_helper(Article, :note), "note" + %th{:style => "width: 4em;"}= heading_helper Article, :unit_quantity, short: true + %th{:style => "width: 5em;"}= heading_helper Article, :price + %th{:style => "width: 3.5em;"}= heading_helper Article, :tax + %th{:style => "width: 4em;"}= heading_helper Article, :deposit %th{:style => "width: 3em;"} %tbody#listbody diff --git a/app/views/articles/_edit_all_table.html.haml b/app/views/articles/_edit_all_table.html.haml index bd9441f7..e7752792 100644 --- a/app/views/articles/_edit_all_table.html.haml +++ b/app/views/articles/_edit_all_table.html.haml @@ -1,20 +1,16 @@ %table.table %thead %tr - %th - %acronym{:title => t('.available_desc')}= t '.available_short' - %th= t 'simple_form.labels.article.name' - %th= t 'simple_form.labels.article.unit' - %th - %acronym{:title => t('.price_desc')}= t '.price_short' - %th - %acronym{:title => t('.unit_quantity_desc')}= t '.unit_quantity_short' - %th - %acronym{:title => t('.order_number_desc')}= t '.order_number_short' - %th= t 'simple_form.labels.article.note' - %th= t 'simple_form.labels.article.article_category' - %th= t 'simple_form.labels.defaults.tax' - %th= t 'simple_form.labels.defaults.deposit' + %th= heading_helper Article, :availability, short: true + %th= heading_helper Article, :name + %th= heading_helper Article, :unit + %th= heading_helper Article, :price, short: true + %th= heading_helper Article, :unit_quantity, short: true + %th= heading_helper Article, :order_number, short: true + %th= heading_helper Article, :note + %th= heading_helper Article, :article_category + %th= heading_helper Article, :tax + %th= heading_helper Article, :deposit %tbody - @articles.each_with_index do |article, index| = fields_for "articles[#{article.id || index}]", article do |form| diff --git a/app/views/articles/_import_search_results.haml b/app/views/articles/_import_search_results.haml index 6d4c6720..254abca8 100644 --- a/app/views/articles/_import_search_results.haml +++ b/app/views/articles/_import_search_results.haml @@ -5,13 +5,13 @@ %table.table.table-striped %thead %tr - %th= t 'simple_form.labels.article.name' - %th= t 'simple_form.labels.article.origin' - %th= t 'simple_form.labels.article.manufacturer' - %th= t 'simple_form.labels.article.note' - %th{:style => "width:4em"}= t 'simple_form.labels.defaults.price' - %th= t 'simple_form.labels.article.unit' - %th= t 'simple_form.labels.defaults.unit_quantity' + %th= heading_helper Article, :name + %th= heading_helper Article, :origin + %th= heading_helper Article, :manufacturer + %th= heading_helper Article, :note + %th{:style => "width:4em"}= heading_helper Article, :price + %th= heading_helper Article, :unit + %th= heading_helper Article, :unit_quantity, short: true %th %tbody - for article in @articles diff --git a/app/views/articles/sync.html.haml b/app/views/articles/sync.html.haml index 1039aee4..4fe32a3c 100644 --- a/app/views/articles/sync.html.haml +++ b/app/views/articles/sync.html.haml @@ -24,16 +24,16 @@ %table.table %thead %tr - %th= t 'simple_form.labels.article.name' - %th= t 'simple_form.labels.article.note' - %th= t 'simple_form.labels.article.manufacturer' - %th= t 'simple_form.labels.article.origin' - %th= t 'simple_form.labels.article.unit' - %th= t '.unit_quantity_short' - %th= t '.price_short' - %th= t 'simple_form.labels.defaults.tax' - %th= t 'simple_form.labels.defaults.deposit' - %th= t 'simple_form.labels.article.article_category' + %th= heading_helper Article, :name + %th= heading_helper Article, :note + %th= heading_helper Article, :manufacturer + %th= heading_helper Article, :origin + %th= heading_helper Article, :unit + %th= heading_helper Article, :unit_quantity, short: true + %th= heading_helper Article, :price + %th= heading_helper Article, :tax + %th= heading_helper Article, :deposit + %th= heading_helper Article, :article_category %tbody - @updated_articles.each do |updated_article, attrs| - article = Article.find(updated_article.id) diff --git a/app/views/articles/upload.html.haml b/app/views/articles/upload.html.haml index 7cb5f4fb..6a8b4d50 100644 --- a/app/views/articles/upload.html.haml +++ b/app/views/articles/upload.html.haml @@ -2,19 +2,19 @@ = t('.body').html_safe %pre = [t('.fields.status'), - t('simple_form.labels.defaults.order_number'), - t('simple_form.labels.article.name'), - t('simple_form.labels.article.note'), - t('simple_form.labels.article.manufacturer'), - t('simple_form.labels.article.origin'), - t('simple_form.labels.article.unit'), - t('simple_form.labels.defaults.price'), - t('simple_form.labels.defaults.tax'), - t('simple_form.labels.defaults.deposit'), - t('simple_form.labels.defaults.unit_quantity'), + Article.human_attribute_name(:order_number), + Article.human_attribute_name(:name), + Article.human_attribute_name(:note), + Article.human_attribute_name(:manufacturer), + Article.human_attribute_name(:origin), + Article.human_attribute_name(:unit), + Article.human_attribute_name(:price), + Article.human_attribute_name(:tax), + Article.human_attribute_name(:deposit), + Article.human_attribute_name(:unit_quantity), t('.fields.season_amount'), t('.fields.season_price'), - t('simple_form.labels.article.article_category')].join(" | ") + Article.human_attribute_name(:article_category)].join(" | ") = form_for :articles, :url => parse_upload_supplier_articles_path(@supplier), :html => { :multipart => true } do |f| diff --git a/config/locales/en.yml b/config/locales/en.yml index 915f4341..790df83e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -36,16 +36,27 @@ en: activerecord: attributes: article: - article_category: article category + article_category: Category availability: Is article available? - deposit: deposit - fc_price: FC price - fc_share: FC share - gross_price: gross price - price: price + availability_short: avail. + deposit: Deposit + fc_price: FoodCoop price + fc_price_short: FC price + fc_share: FoodCoop margin + fc_share_short: FC margin + gross_price: Gross price + manufacturer: Manufacturer + name: Name + note: Note + origin: Origin + price: Price tax: VAT - unit: unit - unit_quantity: unit quantity + unit: Unit + unit_quantity: Unit quantity + unit_quantity_short: U.Q. + article_category: + description: Description + name: Name financial_transaction: amount: amount note: note @@ -1559,16 +1570,6 @@ en: required_users: How many users will be needed in total? tax: In percentage, standard is 7,0 labels: - article: - article_category: Category - manufacturer: Manufacturer - name: Name - note: Note - origin: Origin - unit: Unit - article_category: - description: Description - name: Name defaults: amount: Amount date: Date From 26e207aeb106f35465025cbcfcbf5754793ce0a8 Mon Sep 17 00:00:00 2001 From: Julius Date: Thu, 3 Oct 2013 16:10:18 +0200 Subject: [PATCH 32/79] Reuse some list.js standard template functions (thanks to wvengen https://gist.github.com/wvengen/6784056) --- app/assets/javascripts/list.unlist.js | 122 ++++++++------------------ 1 file changed, 36 insertions(+), 86 deletions(-) diff --git a/app/assets/javascripts/list.unlist.js b/app/assets/javascripts/list.unlist.js index 1bbc12a7..b40cb98f 100644 --- a/app/assets/javascripts/list.unlist.js +++ b/app/assets/javascripts/list.unlist.js @@ -1,3 +1,6 @@ +// for use with listjs 0.2.0 +// https://github.com/javve/list.js + /******************************************************************************* ******************************************************************************** @@ -50,6 +53,7 @@ End copyright notice of the original code +(function(w, undefined) { /******************************************************************************* Begin copy-pasted and modified code *******************************************************************************/ @@ -57,10 +61,23 @@ Begin copy-pasted and modified code // * template engine which adds class 'unlisted' instead of removing from DOM // * especially useful in case of formulars // * uses jQuery's $ -List.prototype.templateEngines.unlist = function(list, settings) { - var listSource = ListJsHelpers.getByClass(settings.listClass, list.listContainer, true), - itemSource = getItemSource(settings.item), - templater = this; +w.List.prototype.templateEngines.unlist = function(list, settings) { + var h = w.ListJsHelpers; + + // start with standard engine, override specific methods afterwards + this.superClass = w.List.prototype.templateEngines.standard; + this.superClass(list, settings); + + // todo refer to listjs code instead of copy-pasting + var listSource = h.getByClass(settings.listClass, list.listContainer, true); + var templater = this; + var ensure = { + created: function(item) { + if(item.elm === undefined) { + templater.create(item); + } + } + }; var init = { start: function(options) { @@ -74,88 +91,20 @@ List.prototype.templateEngines.unlist = function(list, settings) { list.on('updated', templater.updateListHeadings); } }; - - function getItemSource(item) { - if (item === undefined) { - var nodes = listSource.childNodes, - items = []; - - for (var i = 0, il = nodes.length; i < il; i++) { - // Only textnodes have a data attribute - if (nodes[i].data === undefined) { - return nodes[i]; - } - } - return null; - } else if (item.indexOf("<") !== -1) { // Try create html element of list, do not work for tables!! - var div = document.createElement('div'); - div.innerHTML = item; - return div.firstChild; - } else { - return document.getElementById(settings.item); - } - } - - var ensure = { - created: function(item) { - if (item.elm === undefined) { - templater.create(item); - } - } - }; - - /* Get values from element */ - this.get = function(item, valueNames) { - ensure.created(item); - var values = {}; - for(var i = 0, il = valueNames.length; i < il; i++) { - var elm = ListJsHelpers.getByClass(valueNames[i], item.elm, true); - values[valueNames[i]] = elm ? elm.innerHTML : ""; - } - return values; - }; - - /* Sets values at element */ - this.set = function(item, values) { - ensure.created(item); - for(var v in values) { - if (values.hasOwnProperty(v)) { - // TODO speed up if possible - var elm = ListJsHelpers.getByClass(v, item.elm, true); - if (elm) { - elm.innerHTML = values[v]; - } - } - } - }; - - this.create = function(item) { - if (item.elm !== undefined) { - return; - } - /* If item source does not exists, use the first item in list as - source for new items */ - var newItem = itemSource.cloneNode(true); - newItem.id = ""; - item.elm = newItem; - templater.set(item, item.values()); - }; - this.remove = function(item) { - listSource.removeChild(item.elm); - }; - this.show = function(item) { - ensure.created(item); - listSource.appendChild(item.elm); // append item (or move it to the end) - $(item.elm).removeClass('unlisted'); - }; - this.hide = function(item) { - ensure.created(item); - $(item.elm).addClass('unlisted'); - listSource.appendChild(item.elm); - }; - this.clear = function() { - $(listSource.childNodes).addClass('unlisted'); - }; + + this.show = function(item) { + ensure.created(item); + listSource.appendChild(item.elm); // append item (or move it to the end) + $(item.elm).removeClass('unlisted'); + }; + this.hide = function(item) { + ensure.created(item); + $(item.elm).addClass('unlisted'); + listSource.appendChild(item.elm); + }; + this.clear = function() { + $(listSource.childNodes).addClass('unlisted'); + }; this.updateListHeadings = function() { var headSel = '.' + settings.listHeadingsClass; @@ -172,3 +121,4 @@ List.prototype.templateEngines.unlist = function(list, settings) { /******************************************************************************* End copy-pasted and modified code *******************************************************************************/ +})(window); From 3f822dc396ef6a2157d791058591116451c7608c Mon Sep 17 00:00:00 2001 From: Julius Date: Thu, 3 Oct 2013 22:03:14 +0200 Subject: [PATCH 33/79] Revert "Fix migrate problem caused by output formating(?)" This reverts commit 53f24cd885169d4bb0adf2253257fdaabc3dd054. --- db/migrate/20130702113610_update_group_order_totals.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20130702113610_update_group_order_totals.rb b/db/migrate/20130702113610_update_group_order_totals.rb index f0052ee5..ca9aab67 100644 --- a/db/migrate/20130702113610_update_group_order_totals.rb +++ b/db/migrate/20130702113610_update_group_order_totals.rb @@ -7,7 +7,7 @@ class UpdateGroupOrderTotals < ActiveRecord::Migration say "If you do want to update the ordergroup totals, open the rails console " + "(by running `rails c`), and enter:" - say "GroupOrder.all.each { |go| go.order.closed? and go.update_price! }" + say "GroupOrder.all.each { |go| go.order.closed? and go.update_price! }", subitem: true say "You may want to check first that no undesired accounting issues are introduced. " + "It may be wise to discuss this with those responsible for the ordering finances." From a3e82f5304739f109d40883d442c087405180e90 Mon Sep 17 00:00:00 2001 From: Julius Date: Thu, 3 Oct 2013 22:14:41 +0200 Subject: [PATCH 34/79] Add article price tooltip to StockTaking form --- app/views/stock_takings/_stock_change.html.haml | 5 +++-- app/views/stock_takings/new.html.haml | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/app/views/stock_takings/_stock_change.html.haml b/app/views/stock_takings/_stock_change.html.haml index 616be369..3d27c1fa 100644 --- a/app/views/stock_takings/_stock_change.html.haml +++ b/app/views/stock_takings/_stock_change.html.haml @@ -3,5 +3,6 @@ = form.hidden_field :stock_article_id = "Menge (#{stock_change.stock_article.quantity_available})" = form.text_field :quantity, :size => 5, :autocomplete => 'off' - %b= stock_change.stock_article.name - = "(#{number_to_currency(stock_change.stock_article.price)} / #{stock_change.stock_article.unit})" + %span{:data => {:toggle => :tooltip, :title => render(:partial => 'shared/article_price_info', :locals => {:article => stock_change.stock_article})}} + %b= stock_change.stock_article.name + = "(#{number_to_currency(stock_change.stock_article.price)} / #{stock_change.stock_article.unit})" diff --git a/app/views/stock_takings/new.html.haml b/app/views/stock_takings/new.html.haml index 51239ba4..c46406f3 100644 --- a/app/views/stock_takings/new.html.haml +++ b/app/views/stock_takings/new.html.haml @@ -1,5 +1,19 @@ - title t('.title') +- content_for :javascript do + :javascript + $(function() { + enablePriceTooltips(); + }); + + function enablePriceTooltips(context) { + $('[data-toggle~="tooltip"]', context).tooltip({ + animation: false, + html: true, + placement: 'left' + }); + } + - content_for :sidebar do %p %i= t('.text_deviations', inv_link: link_to(t('.temp_inventory'), stock_articles_path)).html_safe From fef8c6d99f7f457c77363cd44b54d160677beb78 Mon Sep 17 00:00:00 2001 From: Julius Date: Thu, 3 Oct 2013 22:24:21 +0200 Subject: [PATCH 35/79] Move StockArticle#history to StockArticle#show --- app/controllers/stockit_controller.rb | 10 +++++----- app/views/stockit/index.html.haml | 3 +-- .../stockit/{history.haml => show.html.haml} | 0 config/locales/de.yml | 19 +++++++++---------- config/locales/en.yml | 19 +++++++++---------- config/locales/fr.yml | 19 +++++++++---------- config/locales/nl.yml | 19 +++++++++---------- config/routes.rb | 2 -- 8 files changed, 42 insertions(+), 49 deletions(-) rename app/views/stockit/{history.haml => show.html.haml} (100%) diff --git a/app/controllers/stockit_controller.rb b/app/controllers/stockit_controller.rb index 3e3b43b2..475ac3a3 100644 --- a/app/controllers/stockit_controller.rb +++ b/app/controllers/stockit_controller.rb @@ -31,6 +31,11 @@ class StockitController < ApplicationController end end + def show + @stock_article = StockArticle.find(params[:id]) + @stock_changes = @stock_article.stock_changes.order('stock_changes.created_at DESC') + end + def destroy @article = StockArticle.find(params[:id]) @article.mark_as_deleted @@ -55,9 +60,4 @@ class StockitController < ApplicationController render :partial => 'form', :locals => {:stock_article => stock_article} end - - def history - @stock_article = StockArticle.undeleted.find(params[:stock_article_id]) - @stock_changes = @stock_article.stock_changes.order('stock_changes.created_at DESC').each {|s| s.readonly!} - end end diff --git a/app/views/stockit/index.html.haml b/app/views/stockit/index.html.haml index 477e5816..c2899d9e 100644 --- a/app/views/stockit/index.html.haml +++ b/app/views/stockit/index.html.haml @@ -45,7 +45,7 @@ %tbody - for article in @stock_articles %tr{:class => stock_article_classes(article), :id => "stockArticle-#{article.id}"} - %td=h article.name + %td= link_to article.name, article %td= article.quantity %td= article.quantity - article.quantity_available %th= article.quantity_available @@ -56,7 +56,6 @@ %td= article.article_category.name %td = link_to t('ui.edit'), edit_stock_article_path(article), class: 'btn btn-mini' - = link_to t('ui.history'), stock_article_history_path(article), class: 'btn btn-mini' = link_to t('ui.delete'), article, :method => :delete, :confirm => t('.confirm_delete'), class: 'btn btn-mini btn-danger', :remote => true %p diff --git a/app/views/stockit/history.haml b/app/views/stockit/show.html.haml similarity index 100% rename from app/views/stockit/history.haml rename to app/views/stockit/show.html.haml diff --git a/config/locales/de.yml b/config/locales/de.yml index a0a0e3a7..8971e53d 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -1731,15 +1731,6 @@ de: title: Lagerartikel bearbeiten form: price_hint: Um Chaos zu vermeiden können bis auf weiteres die Preise von angelegten Lagerartikeln nicht mehr verändert werden. - history: - change_quantity: Veränderung - datetime: Zeitpunkt - delivery: Lieferung - new_quantity: Neuer Bestand - order: Bestellung - reason: Ereignis - stock_changes: Verlauf anzeigen für »%{article_name}« - stock_taking: Inventur index: article: article: Artikel @@ -1765,6 +1756,15 @@ de: new: search_text: ! 'Suche nache Artikeln aus allen Katalogen:' title: Neuen Lagerartikel anlegen + show: + change_quantity: Veränderung + datetime: Zeitpunkt + delivery: Lieferung + new_quantity: Neuer Bestand + order: Bestellung + reason: Ereignis + stock_changes: Verlauf anzeigen für »%{article_name}« + stock_taking: Inventur stock_create: notice: Lagerartikel wurde gespeichert. stock_update: @@ -1889,7 +1889,6 @@ de: close: Schließen delete: Löschen edit: Bearbeiten - history: Verlauf anzeigen marks: close: ! '×' success: diff --git a/config/locales/en.yml b/config/locales/en.yml index b13f4707..50121ec5 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1735,15 +1735,6 @@ en: title: Edit stock articles form: price_hint: To avoid choas, it is not possible to edit the prices of already added stock articles until further notice. - history: - change_quantity: Change - datetime: Time - delivery: Delivery - new_quantity: New quantity - order: Order - reason: Reason - stock_changes: Stock quantity changes of ‘%{article_name}’ - stock_taking: Inventory index: article: article: Article @@ -1769,6 +1760,15 @@ en: new: search_text: ! 'Search for articles in all catalogues:' title: Add new stock article + show: + change_quantity: Change + datetime: Time + delivery: Delivery + new_quantity: New quantity + order: Order + reason: Reason + stock_changes: Stock quantity changes of ‘%{article_name}’ + stock_taking: Inventory stock_create: notice: Stock article was created. stock_update: @@ -1893,7 +1893,6 @@ en: close: Close delete: Delete edit: Edit - history: Show history marks: close: ! '×' success: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 18e2cfea..30f446c2 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -1737,15 +1737,6 @@ fr: title: Modifier l'article form: price_hint: Pour éviter que ça soit le bazar, les prix des articles en stock ne peuvent plus être modifiés. - history: - change_quantity: Modification - datetime: Temps - delivery: Réapprovisionnement - new_quantity: Nouveau stock - order: Commande - reason: Raison - stock_changes: Afficher l'historique pour "%{article_name}" - stock_taking: Inventaire index: article: article: Article @@ -1771,6 +1762,15 @@ fr: new: search_text: ! 'Rechercher des articles dans tous les catalogues:' title: Ajouter un article au stock + show: + change_quantity: Modification + datetime: Temps + delivery: Réapprovisionnement + new_quantity: Nouveau stock + order: Commande + reason: Raison + stock_changes: Afficher l'historique pour "%{article_name}" + stock_taking: Inventaire stock_create: notice: L'article a été sauvegardé. stock_update: @@ -1903,7 +1903,6 @@ fr: close: Fermer delete: Supprimer edit: Modifier - history: Afficher l'historique marks: close: ! '×' success: diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 221d9373..50fdf702 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -1663,15 +1663,6 @@ nl: title: form: price_hint: - history: - change_quantity: - datetime: - delivery: - new_quantity: - order: - reason: - stock_changes: - stock_taking: index: article: article: @@ -1697,6 +1688,15 @@ nl: new: search_text: title: + show: + change_quantity: + datetime: + delivery: + new_quantity: + order: + reason: + stock_changes: + stock_taking: stock_create: notice: Voorraadsartikel is opgeslagen. stock_update: @@ -1821,7 +1821,6 @@ nl: close: Sluiten delete: Verwijder edit: Bewerk - history: marks: close: ! '×' success: diff --git a/config/routes.rb b/config/routes.rb index 0f96d7fa..533d2d97 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -97,8 +97,6 @@ Foodsoft::Application.routes.draw do get :articles_search get :fill_new_stock_article_form end - - get :history end resources :suppliers do From 9a9a782bc40266d881129c37d8b01a6b971a2247 Mon Sep 17 00:00:00 2001 From: Julius Date: Thu, 3 Oct 2013 23:21:53 +0200 Subject: [PATCH 36/79] Complete StockArticle#show view --- app/views/stockit/show.html.haml | 62 +++++++++++++++++++++++--------- config/locales/de.yml | 2 +- config/locales/en.yml | 2 +- config/locales/fr.yml | 2 +- 4 files changed, 49 insertions(+), 19 deletions(-) diff --git a/app/views/stockit/show.html.haml b/app/views/stockit/show.html.haml index f4fe2b07..5f416bf9 100644 --- a/app/views/stockit/show.html.haml +++ b/app/views/stockit/show.html.haml @@ -1,17 +1,47 @@ -- title t('.stock_changes', :article_name => @stock_article.name) +- title @stock_article.name -%table.table.table-hover#stock_changes - %thead - %tr - %th= t '.datetime' - %th= t '.reason' - %th= t '.change_quantity' - %th= t '.new_quantity' - %tbody - - reversed_history = @stock_article.quantity_history.reverse - - @stock_changes.each_with_index do |stock_change, index| - %tr - %td= l stock_change.created_at - %td= link_to_stock_change_reason(stock_change) - %td= stock_change.quantity - %td= reversed_history[index] +.row-fluid + .span6 + %dl.dl-horizontal + %dt= StockArticle.human_attribute_name 'supplier' + %dd= link_to @stock_article.supplier.name, @stock_article.supplier + %dt= StockArticle.human_attribute_name 'name' + %dd= @stock_article.name + %dt= StockArticle.human_attribute_name 'unit' + %dd= @stock_article.unit + %dt= StockArticle.human_attribute_name 'price' + %dd= number_to_currency @stock_article.price + %dt= StockArticle.human_attribute_name 'tax' + %dd= number_to_percentage @stock_article.tax + %dt= StockArticle.human_attribute_name 'deposit' + %dd= number_to_currency @stock_article.deposit + %dt= StockArticle.human_attribute_name 'fc_price' + %dd= number_to_currency @stock_article.fc_price + %dt= StockArticle.human_attribute_name 'article_category' + %dd= @stock_article.article_category.name + %dt= StockArticle.human_attribute_name 'note' + %dd= @stock_article.note + %dt= StockArticle.human_attribute_name 'quantity' + %dd= @stock_article.quantity + %dt= StockArticle.human_attribute_name 'quantity_available' + %dd= @stock_article.quantity_available + .form-actions + = link_to t('ui.edit'), edit_stock_article_path(@stock_article), class: 'btn' + + .span6 + %h2= t('.stock_changes') + %table.table.table-hover#stock_changes + %thead + %tr + %th= t '.datetime' + %th= t '.reason' + %th= t '.change_quantity' + %th= t '.new_quantity' + %tbody + - reversed_history = @stock_article.quantity_history.reverse + - @stock_changes.each_with_index do |stock_change, index| + %tr + %td= l stock_change.created_at + %td= link_to_stock_change_reason(stock_change) + %td= stock_change.quantity + %td= reversed_history[index] diff --git a/config/locales/de.yml b/config/locales/de.yml index 8971e53d..ba339ee8 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -1763,7 +1763,7 @@ de: new_quantity: Neuer Bestand order: Bestellung reason: Ereignis - stock_changes: Verlauf anzeigen für »%{article_name}« + stock_changes: Verlauf des Lagerbestands stock_taking: Inventur stock_create: notice: Lagerartikel wurde gespeichert. diff --git a/config/locales/en.yml b/config/locales/en.yml index 50121ec5..6c3fbea8 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1767,7 +1767,7 @@ en: new_quantity: New quantity order: Order reason: Reason - stock_changes: Stock quantity changes of ‘%{article_name}’ + stock_changes: Stock quantity changes stock_taking: Inventory stock_create: notice: Stock article was created. diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 30f446c2..8d16c076 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -1769,7 +1769,7 @@ fr: new_quantity: Nouveau stock order: Commande reason: Raison - stock_changes: Afficher l'historique pour "%{article_name}" + stock_changes: Afficher l'historique stock_taking: Inventaire stock_create: notice: L'article a été sauvegardé. From a9dff7f1dffafa380365047c10ff524b6dde5458 Mon Sep 17 00:00:00 2001 From: wvengen Date: Fri, 4 Oct 2013 10:09:33 +0200 Subject: [PATCH 37/79] add missing i18n --- app/controllers/login_controller.rb | 2 +- app/views/articles/sync.html.haml | 3 +-- app/views/finance/group_order_articles/_form.html.haml | 2 +- app/views/finance/order_articles/_edit.html.haml | 2 +- app/views/tasks/show.haml | 2 +- config/locales/de.yml | 4 ++++ config/locales/en.yml | 1 + 7 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/controllers/login_controller.rb b/app/controllers/login_controller.rb index 3aab74c5..43ca5fdf 100644 --- a/app/controllers/login_controller.rb +++ b/app/controllers/login_controller.rb @@ -11,7 +11,7 @@ class LoginController < ApplicationController # Sends an email to a user with the token that allows setting a new password through action "password". def reset_password if request.get? || params[:user].nil? # Catch for get request and give better error message. - redirect_to forgot_password_url, alert: 'Ein Problem ist aufgetreten. Bitte erneut versuchen' and return + redirect_to forgot_password_url, alert: I18n.t('errors.general_again') and return end if (user = User.find_by_email(params[:user][:email])) diff --git a/app/views/articles/sync.html.haml b/app/views/articles/sync.html.haml index 4fe32a3c..58273178 100644 --- a/app/views/articles/sync.html.haml +++ b/app/views/articles/sync.html.haml @@ -11,8 +11,7 @@ = hidden_field_tag "outlisted_articles[#{article.id}]", '1' = article.name - if article.in_open_order - .alert - Achtung, #{article.name} wird gerade in einer laufenden Bestellung verwendet. Bitte erst Bestellung anpassen. + .alert= t '.alert_used', article: article.name - else %i= t '.outlist.body_skip' %hr/ diff --git a/app/views/finance/group_order_articles/_form.html.haml b/app/views/finance/group_order_articles/_form.html.haml index f606e3ac..8b6d41a0 100644 --- a/app/views/finance/group_order_articles/_form.html.haml +++ b/app/views/finance/group_order_articles/_form.html.haml @@ -5,7 +5,7 @@ %h3= t('.amount_change_for', article: @order_article.article.name) .modal-body = form.input :ordergroup_id, as: :select, collection: Ordergroup.all.map { |g| [g.name, g.id] } - = form.input :result, hint: "Einheit: #{@order_article.article.unit}" + = form.input :result, hint: I18n.t('.result_hint', unit: @order_article.article.unit) .modal-footer = link_to t('ui.close'), '#', class: 'btn', data: {dismiss: 'modal'} = form.submit t('ui.save'), class: 'btn btn-primary' diff --git a/app/views/finance/order_articles/_edit.html.haml b/app/views/finance/order_articles/_edit.html.haml index 3c63807e..0dddf8cd 100644 --- a/app/views/finance/order_articles/_edit.html.haml +++ b/app/views/finance/order_articles/_edit.html.haml @@ -11,7 +11,7 @@ = f.input :unit - if @order_article.article.is_a?(StockArticle) - %div.alert Preise von Lagerartikeln können nicht geändert werden! + %div.alert= t '.stock_alert' - else = simple_fields_for :article_price, @order_article.article_price do |f| = f.input :unit_quantity diff --git a/app/views/tasks/show.haml b/app/views/tasks/show.haml index 8777d15d..644151fa 100644 --- a/app/views/tasks/show.haml +++ b/app/views/tasks/show.haml @@ -30,7 +30,7 @@ - unless @task.done? = link_to t('.mark_done'), set_done_task_path(@task), method: :post, class: 'btn' = link_to t('ui.edit'), edit_task_path(@task), class: 'btn' - = link_to t('ui.delete'), task_path(@task), :method => :delete, :confirm => "Die Aufgabe wirklich löschen?", + = link_to t('ui.delete'), task_path(@task), :method => :delete, :confirm => t('.confirm_delete_single'), class: 'btn btn-danger' - if @task.periodic? = link_to t('.delete_group'), task_path(@task, periodic: true), method: :delete, diff --git a/config/locales/de.yml b/config/locales/de.yml index 893739d6..8886d93e 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -313,6 +313,7 @@ de: title: sync: outlist: + alert_used: Achtung, %{article} wird gerade in einer laufenden Bestellung verwendet. Bitte erst Bestellung anpassen. body: ! 'Folgende Artikel wurden ausgelistet und werden gelöscht:' body_skip: Es müssen keine Artikel gelöscht werden. title: Auslisten ... @@ -686,6 +687,7 @@ de: group_order_articles: form: amount_change_for: Mengenänderung für %{article} + result_hint: 'Einheit: %{unit}' index: amount: Betrag amount_fc: Betrag(FC) @@ -722,6 +724,7 @@ de: order_articles: edit: title: Artikel aktualisieren + stock_alert: Preise von Lagerartikeln können nicht geändert werden! new: title: Neuer gelieferter Artikel die Bestellung ordergroups: @@ -1861,6 +1864,7 @@ de: notice: Aufgabenstatus wurde aktualisiert show: accept_task: Aufgabe übernehmen + confirm_delete_single: Die Aufgabe wirklich löschen? confirm_delete_group: Diese und alle folgenden wöchentlichen Aufgaben wirklich löschen? delete_group: Aufgabe und folgende löschen due_date: Fälligkeitsdatum diff --git a/config/locales/en.yml b/config/locales/en.yml index 790df83e..391291ee 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -324,6 +324,7 @@ en: title: Upload articles sync: outlist: + alert_used: Warning, %{article} is used in an open order. Please remove it from the order first. body: ! 'The following articles were removed from the list and will be deleted:' body_skip: No articles to delete. title: Remove from list ... From 64a597c68907a17b7e8d36366fa729bb9e656fbb Mon Sep 17 00:00:00 2001 From: wvengen Date: Fri, 4 Oct 2013 14:53:22 +0200 Subject: [PATCH 38/79] use i18n-js --- .gitignore | 5 +++-- Gemfile | 2 +- Gemfile.lock | 8 ++++++++ app/assets/javascripts/application.js | 2 ++ app/assets/javascripts/ordering.js | 21 ++++----------------- app/views/group_orders/_form.html.haml | 1 - app/views/layouts/_header.html.haml | 6 ++++-- config/environments/development.rb.SAMPLE | 5 ++++- config/environments/test.rb | 3 +++ config/i18n-js.yml | 4 ++++ 10 files changed, 33 insertions(+), 24 deletions(-) create mode 100644 config/i18n-js.yml diff --git a/.gitignore b/.gitignore index d26b8ce7..a3389c40 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ log/*.log tmp/**/* -config/*.yml +config/app_config.yml +config/database.yml config/initializers/secret_token.rb db/*.sqlite3 nbproject/ @@ -16,4 +17,4 @@ doc/app/ Capfile config/deploy.rb config/deploy/* -.localeapp \ No newline at end of file +.localeapp diff --git a/Gemfile b/Gemfile index e80314ed..e98aa4ea 100644 --- a/Gemfile +++ b/Gemfile @@ -19,7 +19,7 @@ end gem 'jquery-rails' gem 'select2-rails' gem 'bootstrap-datepicker-rails' - +gem 'i18n-js', git: 'git://github.com/fnando/i18n-js.git' # to avoid US-ASCII js.erb error gem 'mysql2' gem 'prawn' diff --git a/Gemfile.lock b/Gemfile.lock index c816b8c4..824f2cae 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -4,6 +4,13 @@ GIT specs: localize_input (0.1.0) +GIT + remote: git://github.com/fnando/i18n-js.git + revision: eab4137f83777963f0ebe6960704a7f64fd8911d + specs: + i18n-js (2.1.2) + i18n + GIT remote: git://github.com/technoweenie/acts_as_versioned.git revision: 63b1fc8529d028fae632fe80ec0cb25df56cd76b @@ -321,6 +328,7 @@ DEPENDENCIES factory_girl_rails (~> 4.0) faker haml-rails + i18n-js! i18n-spec inherited_resources jquery-rails diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index c6d6e36a..af02efcc 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -9,6 +9,8 @@ //= require bootstrap-datepicker/locales/bootstrap-datepicker.nl //= require jquery.observe_field //= require rails.validations +//= require i18n +//= require i18n/translations //= require_self //= require ordering //= require stupidtable diff --git a/app/assets/javascripts/ordering.js b/app/assets/javascripts/ordering.js index 159370f2..3f80d40f 100644 --- a/app/assets/javascripts/ordering.js +++ b/app/assets/javascripts/ordering.js @@ -7,9 +7,6 @@ var modified = false // indicates if anything has been clicked on this page var groupBalance = 0; // available group money -var currencySeparator = "."; // default decimal separator -var currencyPrecision = 2; // default digits behind comma -var currencyUnit = "€"; // default currency var minimumBalance = 0; // minimum group balance for the order to be succesful var toleranceIsCostly = true; // default tolerance behaviour var isStockit = false; // Wheter the order is from stock oder normal supplier @@ -23,12 +20,6 @@ var toleranceOthers = new Array(); var itemsAllocated = new Array(); // how many items the group has been allocated and should definitely get var quantityAvailable = new Array(); // stock_order. how many items are currently in stock -function setCurrencyFormat(separator, precision, unit) { - currencySeparator = separator; - currencyPrecision = precision; - currencyUnit = unit; -} - function setToleranceBehaviour(value) { toleranceIsCostly = value; } @@ -124,7 +115,7 @@ function update(item, quantity, tolerance) { } else { itemTotal[item] = price[item] * (Number(quantity)); } - $('#price_' + item + '_display').html(asMoney(itemTotal[item])); + $('#price_' + item + '_display').html(I18n.l("currency", itemTotal[item])); // update missing units var missing_units = unit[item] - (((quantityOthers[item] + Number(quantity)) % unit[item]) + Number(tolerance) + toleranceOthers[item]) @@ -137,10 +128,6 @@ function update(item, quantity, tolerance) { updateBalance(); } -function asMoney(amount) { - return String(amount.toFixed(currencyPrecision)).replace(/\./, currencySeparator) + ' ' + currencyUnit; -} - function calcUnits(unitSize, quantity, tolerance) { var units = Math.floor(quantity / unitSize) var remainder = quantity % unitSize @@ -158,10 +145,10 @@ function updateBalance() { for (i in itemTotal) { total += itemTotal[i]; } - $('#total_price').html(asMoney(total)); + $('#total_price').html(I18n.l("currency", total)); var balance = groupBalance - total; - $('#new_balance').html(asMoney(balance)); - $('#total_balance').val(asMoney(balance)); + $('#new_balance').html(I18n.l("currency", balance)); + $('#total_balance').val(I18n.l("currency", balance)); // determine bgcolor and submit button state according to balance var bgcolor = ''; if (balance < minimumBalance) { diff --git a/app/views/group_orders/_form.html.haml b/app/views/group_orders/_form.html.haml index 2bd2f30b..9e4007f3 100644 --- a/app/views/group_orders/_form.html.haml +++ b/app/views/group_orders/_form.html.haml @@ -3,7 +3,6 @@ $(function() { #{data_to_js(@ordering_data)} setGroupBalance(#{@ordering_data[:available_funds]}); - setCurrencyFormat("#{t('number.currency.format.separator')}", #{t('number.currency.format.precision')}, "#{t('number.currency.format.unit')}"); setMinimumBalance(#{FoodsoftConfig[:minimum_balance] or 0}); setToleranceBehaviour(#{FoodsoftConfig[:tolerance_is_costly]}); setStockit(#{@order.stockit?}); diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml index dfd5f2f5..b3a4e30c 100644 --- a/app/views/layouts/_header.html.haml +++ b/app/views/layouts/_header.html.haml @@ -22,7 +22,9 @@ Javascripts \================================================== / Placed at the end of the document so the pages load faster - :javascript - I18n = {locale: '#{j(I18n.locale.to_s)}'} = javascript_include_tag "application" + :javascript + I18n.defaultLocale = "#{I18n.default_locale}"; + I18n.locale = "#{I18n.locale}"; + I18n.fallbacks = true; = yield(:javascript) diff --git a/config/environments/development.rb.SAMPLE b/config/environments/development.rb.SAMPLE index 826028ba..ac1781e6 100644 --- a/config/environments/development.rb.SAMPLE +++ b/config/environments/development.rb.SAMPLE @@ -35,6 +35,9 @@ Foodsoft::Application.configure do # Expands the lines which load the assets config.assets.debug = true + # Required for i18n-js + config.assets.initialize_on_precompile = true + # Configure hostname for action mailer config.action_mailer.default_url_options = { host: 'localhost:3000' } @@ -42,4 +45,4 @@ Foodsoft::Application.configure do # Mailcatcher can be installed by gem install mailcatcher config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { address: "localhost", port: 1025 } -end \ No newline at end of file +end diff --git a/config/environments/test.rb b/config/environments/test.rb index 30c06137..b67c0285 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -11,6 +11,9 @@ Foodsoft::Application.configure do config.serve_static_assets = true config.static_cache_control = "public, max-age=3600" + # Required for i18n-js + config.assets.initialize_on_precompile = true + # Log error messages when you accidentally call methods on nil config.whiny_nils = true diff --git a/config/i18n-js.yml b/config/i18n-js.yml new file mode 100644 index 00000000..76af6fda --- /dev/null +++ b/config/i18n-js.yml @@ -0,0 +1,4 @@ +# only serve selected strings for i18n-js to keep filesize down +translations: +- file: 'app/assets/javascripts/i18n/translations.js' + only: ['*.js.*', '*.number.*', '*.date.formats.*'] From dce92b9d7cd54b41d285bd973b04b3710002d948 Mon Sep 17 00:00:00 2001 From: wvengen Date: Fri, 4 Oct 2013 15:01:24 +0200 Subject: [PATCH 39/79] i18n ordering javascript --- app/assets/javascripts/ordering.js | 2 +- config/locales/de.yml | 3 +++ config/locales/en.yml | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/ordering.js b/app/assets/javascripts/ordering.js index 3f80d40f..9c9a3d99 100644 --- a/app/assets/javascripts/ordering.js +++ b/app/assets/javascripts/ordering.js @@ -178,6 +178,6 @@ $(function() { }); $('a[data-confirm_switch_order]').click(function() { - return (!modified || confirm('Änderungen an dieser Bestellung gehen verloren, wenn zu einer anderen Bestellung gewechselt wird. Möchtest Du trotzdem wechseln?')); + return (!modified || confirm(I18n.t('js.ordering.confirm_change'))); }); }); diff --git a/config/locales/de.yml b/config/locales/de.yml index 8886d93e..8efaf074 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -985,6 +985,9 @@ de: action: Einlading abschicken body:

Hier kannst du eine Person in die Gruppe %{group} einladen, die noch nicht Mitglied der Foodcoop ist.

success: Benutzerin wurde erfolgreich eingeladen. + js: + ordering: + confirm_change: Änderungen an dieser Bestellung gehen verloren, wenn zu einer anderen Bestellung gewechselt wird. Möchtest Du trotzdem wechseln? layouts: application1: title: Foodsoft - %{title} diff --git a/config/locales/en.yml b/config/locales/en.yml index 391291ee..ad133361 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -998,6 +998,9 @@ en: action: Send invite body:

Here you can add a person to the group %{group}, who is not yet a member of the foodcoop.

success: User was invited successfully. + js: + ordering: + confirm_change: Modifications to this order will be lost when you change the order. Do you want to lose the changes you made and continue? layouts: application1: title: Foodsoft - %{title} From 3a948e9b7396738981dd37efbb5bbe6371636952 Mon Sep 17 00:00:00 2001 From: Julius Date: Fri, 4 Oct 2013 18:28:45 +0200 Subject: [PATCH 40/79] Move list.js extensions to plugins --- Gemfile | 2 +- Gemfile.lock | 3 + app/assets/javascripts/application.js | 3 +- app/assets/javascripts/list.customized.js | 69 -- app/assets/javascripts/list.delay.js | 50 ++ app/assets/javascripts/list.reset.js | 42 ++ app/views/group_orders/_form.html.haml | 6 +- vendor/assets/javascripts/list.js | 775 ---------------------- 8 files changed, 102 insertions(+), 848 deletions(-) delete mode 100644 app/assets/javascripts/list.customized.js create mode 100644 app/assets/javascripts/list.delay.js create mode 100644 app/assets/javascripts/list.reset.js delete mode 100644 vendor/assets/javascripts/list.js diff --git a/Gemfile b/Gemfile index e80314ed..f2dbd228 100644 --- a/Gemfile +++ b/Gemfile @@ -19,7 +19,7 @@ end gem 'jquery-rails' gem 'select2-rails' gem 'bootstrap-datepicker-rails' - +gem 'rails-assets-listjs', '0.2.0.beta.4' # remember to maintain list.*.js plugins and template engines on update gem 'mysql2' gem 'prawn' diff --git a/Gemfile.lock b/Gemfile.lock index c816b8c4..61e2fc6c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -192,6 +192,8 @@ GEM activesupport (= 3.2.13) bundler (~> 1.0) railties (= 3.2.13) + rails-assets-listjs (0.2.0.beta.4) + railties (>= 3.1) rails-settings-cached (0.2.4) rails (>= 3.0.0) railties (3.2.13) @@ -332,6 +334,7 @@ DEPENDENCIES prawn quiet_assets rails (~> 3.2.9) + rails-assets-listjs (= 0.2.0.beta.4) rails-settings-cached (= 0.2.4) resque rspec-core diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index c684cf31..b8dc87e8 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -10,7 +10,8 @@ //= require jquery.observe_field //= require list //= require list.unlist -//= require list.customized +//= require list.delay +//= require list.reset //= require rails.validations //= require_self //= require ordering diff --git a/app/assets/javascripts/list.customized.js b/app/assets/javascripts/list.customized.js deleted file mode 100644 index da79cbe1..00000000 --- a/app/assets/javascripts/list.customized.js +++ /dev/null @@ -1,69 +0,0 @@ -(function(window, undefined) { - -var CustomizedList = function(id, options, values) { - var self = this; - var h = window.ListJsHelpers; - - this.searchTimeout = undefined; - - var init = { - start: function(id, options, values) { - this.defaults(options); - this.list(id, options, values); - this.callbacks(options); - this.onload(options); - }, - defaults: function(options) { - options.delayedSearchClass = options.delayedSearchClass || 'delayed-search'; - options.delayedSearchTime = options.delayedSearchTime || 500; - options.highlightClass = options.highlightClass || 'btn-primary'; - options.resetSearchClass = options.resetSearchClass || 'reset-search'; - }, - list: function(id, options, values) { - self.list = new window.List(id, options, values); - }, - callbacks: function(options) { - var resetSearchButton = h.getByClass(options.resetSearchClass, self.list.listContainer); - $(resetSearchButton).click(self.resetSearch); - self.list.on('updated', self.highlightResetButton); - - var delayedSearchInput = h.getByClass(options.delayedSearchClass, self.list.listContainer); - $(delayedSearchInput).keyup(self.searchDelayStart); - }, - onload: function(options) { - var initialSearchTerm = $('.' + options.delayedSearchClass + ', .' + options.searchClass, self.list.listContainer).val(); - if('' != initialSearchTerm) { - self.list.search(initialSearchTerm); - } - } - }; - - this.searchDelayStart = function(searchString, columns) { - // TODO: if keycode corresponds to 'ENTER' ? skip delay - clearTimeout(self.searchTimeout); - self.searchTimeout = window.setTimeout(function() {self.searchDelayEnd(searchString, columns)}, options.delayedSearchTime); - - var resetSearchButton = h.getByClass(options.resetSearchClass, self.list.listContainer); - $(resetSearchButton).removeClass(options.highlightClass); - }; - - this.searchDelayEnd = function(searchString, columns) { - self.list.search(searchString, columns); - }; - - this.highlightResetButton = function() { - var resetSearchButton = h.getByClass(options.resetSearchClass, self.list.listContainer); - $(resetSearchButton).toggleClass(options.highlightClass, self.list.searched); - }; - - this.resetSearch = function() { - $('.' + options.delayedSearchClass + ', .' + options.searchClass, self.list.listContainer).val(''); - self.list.search(''); - }; - - init.start(id, options, values); -} - -window.CustomizedList = CustomizedList; - -})(window); diff --git a/app/assets/javascripts/list.delay.js b/app/assets/javascripts/list.delay.js new file mode 100644 index 00000000..72ac425c --- /dev/null +++ b/app/assets/javascripts/list.delay.js @@ -0,0 +1,50 @@ +// for use with listjs 0.2.0 +// https://github.com/javve/list.js + +(function(window, undefined) { + +window.List.prototype.plugins.delay = function(locals, options) { + var list = this; + + this.searchTimeout = undefined; + + var init = { + start: function(options) { + this.defaults(options); + this.callbacks(options); + this.onload(options); + }, + defaults: function(options) { + options.delayedSearchClass = options.delayedSearchClass || 'delayed-search'; + options.delayedSearchTime = options.delayedSearchTime || 500; + }, + callbacks: function(options) { + $('.' + options.delayedSearchClass, list.listContainer).keyup(list.searchDelayStart); + }, + onload: function(options) { + var initialSearchTerm = $('.' + options.delayedSearchClass, list.listContainer).val(); + if('' != initialSearchTerm) { + list.search(initialSearchTerm); + } + } + }; + + this.searchDelayStart = function(searchString, columns) { + // TODO: if keycode corresponds to 'ENTER' ? skip delay + clearTimeout(list.searchTimeout); + list.searchTimeout = window.setTimeout( + function() {list.searchDelayEnd(searchString, columns)}, + options.delayedSearchTime + ); + + $(list.listContainer).trigger('updateComing'); + }; + + this.searchDelayEnd = function(searchString, columns) { + list.search(searchString, columns); + }; + + init.start(options); +} + +})(window); diff --git a/app/assets/javascripts/list.reset.js b/app/assets/javascripts/list.reset.js new file mode 100644 index 00000000..9482f32c --- /dev/null +++ b/app/assets/javascripts/list.reset.js @@ -0,0 +1,42 @@ +// for use with listjs 0.2.0 +// https://github.com/javve/list.js + +(function(window, undefined) { + +window.List.prototype.plugins.reset = function(locals, options) { + var list = this; + + var init = { + start: function(options) { + this.defaults(options); + this.callbacks(options); + }, + defaults: function(options) { + options.highlightClass = options.highlightClass || 'btn-primary'; + options.resetSearchClass = options.resetSearchClass || 'reset-search'; + options.resettableClass = options.resettableClass || 'resettable'; + }, + callbacks: function(options) { + $('.' + options.resetSearchClass, list.listContainer).click(list.resetSearch); + list.on('updated', list.highlightResetButton); + + $(list.listContainer).on('updateComing', function() { + list.highlightResetButton(false); + }); + } + }; + + this.highlightResetButton = function(highlightEnabled) { + highlightEnabled = (undefined === highlightEnabled) ? (list.searched) : (highlightEnabled); + $('.' + options.resetSearchClass, list.listContainer).toggleClass(options.highlightClass, highlightEnabled); + }; + + this.resetSearch = function() { + $('.' + options.resettableClass, list.listContainer).val(''); + list.search(''); + }; + + init.start(options); +} + +})(window); diff --git a/app/views/group_orders/_form.html.haml b/app/views/group_orders/_form.html.haml index fbb4da00..3c6048c0 100644 --- a/app/views/group_orders/_form.html.haml +++ b/app/views/group_orders/_form.html.haml @@ -8,7 +8,9 @@ setToleranceBehaviour(#{FoodsoftConfig[:tolerance_is_costly]}); setStockit(#{@order.stockit?}); // create List for search-feature (using list.js, http://listjs.com) - new CustomizedList(document.body, { valueNames: ['name'], engine: 'unlist' }); + var listjsResetPlugin = ['reset', {highlightClass: 'btn-primary'}]; + var listjsDelayPlugin = ['delay', {delayedSearchTime: 500}]; + new List(document.body, { valueNames: ['name'], engine: 'unlist', plugins: [listjsResetPlugin, listjsDelayPlugin] }); }); - title t('.title'), false @@ -45,7 +47,7 @@ .well.clear .form-search .input-append - = text_field_tag :article, params[:article], placeholder: t('.search_article'), class: 'search-query delayed-search' + = text_field_tag :article, params[:article], placeholder: t('.search_article'), class: 'search-query delayed-search resettable' %button.add-on.btn.reset-search{:type => :button, :title => t('.reset_article_search')} %i.icon.icon-remove diff --git a/vendor/assets/javascripts/list.js b/vendor/assets/javascripts/list.js deleted file mode 100644 index 44ce6879..00000000 --- a/vendor/assets/javascripts/list.js +++ /dev/null @@ -1,775 +0,0 @@ -/* -ListJS Beta 0.2.0 -By Jonny Strömberg (www.jonnystromberg.com, www.listjs.com) - -OBS. The API is not frozen. It MAY change! - -License (MIT) - -Copyright (c) 2011 Jonny Strömberg http://jonnystromberg.com - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of the Software, -and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. -*/ -(function( window, undefined ) { -"use strict"; -var document = window.document, - h; - -var List = function(id, options, values) { - var self = this, - templater, - init, - initialItems, - Item, - Templater, - sortButtons, - events = { - 'updated': [] - }; - this.listContainer = (typeof(id) == 'string') ? document.getElementById(id) : id; - // Check if the container exists. If not return instead of breaking the javascript - if (!this.listContainer) - return; - - this.items = []; - this.visibleItems = []; // These are the items currently visible - this.matchingItems = []; // These are the items currently matching filters and search, regadlessof visible count - this.searched = false; - this.filtered = false; - - this.list = null; - this.templateEngines = {}; - - this.page = options.page || 200; - this.i = options.i || 1; - - init = { - start: function(values, options) { - options.plugins = options.plugins || {}; - this.classes(options); - templater = new Templater(self, options); - this.callbacks(options); - this.items.start(values, options); - self.update(); - this.plugins(options.plugins); - }, - classes: function(options) { - options.listClass = options.listClass || 'list'; - options.searchClass = options.searchClass || 'search'; - options.sortClass = options.sortClass || 'sort'; - }, - callbacks: function(options) { - self.list = h.getByClass(options.listClass, self.listContainer, true); - h.addEvent(h.getByClass(options.searchClass, self.listContainer), 'keyup', self.search); - sortButtons = h.getByClass(options.sortClass, self.listContainer); - h.addEvent(sortButtons, 'click', self.sort); - }, - items: { - start: function(values, options) { - if (options.valueNames) { - var itemsToIndex = this.get(), - valueNames = options.valueNames; - if (options.indexAsync) { - this.indexAsync(itemsToIndex, valueNames); - } else { - this.index(itemsToIndex, valueNames); - } - } - if (values !== undefined) { - self.add(values); - } - }, - get: function() { - // return h.getByClass('item', self.list); - var nodes = self.list.childNodes, - items = []; - for (var i = 0, il = nodes.length; i < il; i++) { - // Only textnodes have a data attribute - if (nodes[i].data === undefined) { - items.push(nodes[i]); - } - } - return items; - }, - index: function(itemElements, valueNames) { - for (var i = 0, il = itemElements.length; i < il; i++) { - self.items.push(new Item(valueNames, itemElements[i])); - } - }, - indexAsync: function(itemElements, valueNames) { - var itemsToIndex = itemElements.splice(0, 100); // TODO: If < 100 items, what happens in IE etc? - this.index(itemsToIndex, valueNames); - if (itemElements.length > 0) { - setTimeout(function() { - init.items.indexAsync(itemElements, valueNames); - }, - 10); - } else { - self.update(); - // TODO: Add indexed callback - } - } - }, - plugins: function(plugins) { - var locals = { - templater: templater, - init: init, - initialItems: initialItems, - Item: Item, - Templater: Templater, - sortButtons: sortButtons, - events: events, - reset: reset - }; - for (var i = 0; i < plugins.length; i++) { - plugins[i][1] = plugins[i][1] || {}; - var pluginName = plugins[i][1].name || plugins[i][0]; - self[pluginName] = self.plugins[plugins[i][0]].call(self, locals, plugins[i][1]); - } - } - }; - - - /* - * Add object to list - */ - this.add = function(values, callback) { - if (callback) { - addAsync(values, callback); - } - var added = [], - notCreate = false; - if (values[0] === undefined){ - values = [values]; - } - for (var i = 0, il = values.length; i < il; i++) { - var item = null; - if (values[i] instanceof Item) { - item = values[i]; - item.reload(); - } else { - notCreate = (self.items.length > self.page) ? true : false; - item = new Item(values[i], undefined, notCreate); - } - self.items.push(item); - added.push(item); - } - self.update(); - return added; - }; - - /* - * Adds items asynchronous to the list, good for adding huge amount of - * data. Defaults to add 100 items a time - */ - var addAsync = function(values, callback, items) { - var valuesToAdd = values.splice(0, 100); - items = items || []; - items = items.concat(self.add(valuesToAdd)); - if (values.length > 0) { - setTimeout(function() { - addAsync(values, callback, items); - }, 10); - } else { - self.update(); - callback(items); - } - }; - - this.show = function(i, page) { - this.i = i; - this.page = page; - self.update(); - }; - - /* Removes object from list. - * Loops through the list and removes objects where - * property "valuename" === value - */ - this.remove = function(valueName, value, options) { - var found = 0; - for (var i = 0, il = self.items.length; i < il; i++) { - if (self.items[i].values()[valueName] == value) { - templater.remove(self.items[i], options); - self.items.splice(i,1); - il--; - found++; - } - } - self.update(); - return found; - }; - - /* Gets the objects in the list which - * property "valueName" === value - */ - this.get = function(valueName, value) { - var matchedItems = []; - for (var i = 0, il = self.items.length; i < il; i++) { - var item = self.items[i]; - if (item.values()[valueName] == value) { - matchedItems.push(item); - } - } - if (matchedItems.length == 0) { - return null; - } else if (matchedItems.length == 1) { - return matchedItems[0]; - } else { - return matchedItems; - } - }; - - /* Sorts the list. - * @valueOrEvent Either a JavaScript event object or a valueName - * @sortFunction (optional) Define if natural sorting does not fullfill your needs - */ - this.sort = function(valueName, options) { - var length = self.items.length, - value = null, - target = valueName.target || valueName.srcElement, /* IE have srcElement */ - sorting = '', - isAsc = false, - asc = 'asc', - desc = 'desc', - options = options || {}; - - if (target === undefined) { - value = valueName; - isAsc = options.asc || false; - } else { - value = h.getAttribute(target, 'data-sort'); - isAsc = h.hasClass(target, asc) ? false : true; - } - for (var i = 0, il = sortButtons.length; i < il; i++) { - h.removeClass(sortButtons[i], asc); - h.removeClass(sortButtons[i], desc); - } - if (isAsc) { - if (target !== undefined) { - h.addClass(target, asc); - } - isAsc = true; - } else { - if (target !== undefined) { - h.addClass(target, desc); - } - isAsc = false; - } - - if (options.sortFunction) { - options.sortFunction = options.sortFunction; - } else { - options.sortFunction = function(a, b) { - return h.sorter.alphanum(a.values()[value].toLowerCase(), b.values()[value].toLowerCase(), isAsc); - }; - } - self.items.sort(options.sortFunction); - self.update(); - }; - - /* - * Searches the list after values with content "searchStringOrEvent". - * The columns parameter defines if all values should be included in the search, - * defaults to undefined which means "all". - */ - this.search = function(searchString, columns) { - self.i = 1; // Reset paging - var matching = [], - found, - item, - text, - values, - is, - columns = (columns === undefined) ? self.items[0].values() : columns, - searchString = (searchString === undefined) ? "" : searchString, - target = searchString.target || searchString.srcElement; /* IE have srcElement */ - - searchString = (target === undefined) ? (""+searchString).toLowerCase() : ""+target.value.toLowerCase(); - is = self.items; - // Escape regular expression characters - searchString = searchString.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); - - templater.clear(); - if (searchString === "" ) { - reset.search(); - self.searched = false; - self.update(); - } else { - self.searched = true; - - for (var k = 0, kl = is.length; k < kl; k++) { - found = false; - item = is[k]; - values = item.values(); - - for(var j in columns) { - if(values.hasOwnProperty(j) && columns[j] !== null) { - text = (values[j] != null) ? values[j].toString().toLowerCase() : ""; - if ((searchString !== "") && (text.search(searchString) > -1)) { - found = true; - } - } - } - if (found) { - item.found = true; - matching.push(item); - } else { - item.found = false; - } - } - self.update(); - } - return self.visibleItems; - }; - - /* - * Filters the list. If filterFunction() returns False hides the Item. - * if filterFunction == false are the filter removed - */ - this.filter = function(filterFunction) { - self.i = 1; // Reset paging - reset.filter(); - if (filterFunction === undefined) { - self.filtered = false; - } else { - self.filtered = true; - var is = self.items; - for (var i = 0, il = is.length; i < il; i++) { - var item = is[i]; - if (filterFunction(item)) { - item.filtered = true; - } else { - item.filtered = false; - } - } - } - self.update(); - return self.visibleItems; - }; - - /* - * Get size of the list - */ - this.size = function() { - return self.items.length; - }; - - /* - * Removes all items from the list - */ - this.clear = function() { - templater.clear(); - self.items = []; - }; - - this.on = function(event, callback) { - events[event].push(callback); - }; - - var trigger = function(event) { - var i = events[event].length; - while(i--) { - events[event][i](); - } - }; - - var reset = { - filter: function() { - var is = self.items, - il = is.length; - while (il--) { - is[il].filtered = false; - } - }, - search: function() { - var is = self.items, - il = is.length; - while (il--) { - is[il].found = false; - } - } - }; - - - this.update = function() { - var is = self.items, - il = is.length; - - self.visibleItems = []; - self.matchingItems = []; - templater.clear(); - for (var i = 0; i < il; i++) { - if (is[i].matching() && ((self.matchingItems.length+1) >= self.i && self.visibleItems.length < self.page)) { - is[i].show(); - self.visibleItems.push(is[i]); - self.matchingItems.push(is[i]); - } else if (is[i].matching()) { - self.matchingItems.push(is[i]); - is[i].hide(); - } else { - is[i].hide(); - } - } - trigger('updated'); - }; - - Item = function(initValues, element, notCreate) { - var item = this, - values = {}; - - this.found = false; // Show if list.searched == true and this.found == true - this.filtered = false;// Show if list.filtered == true and this.filtered == true - - var init = function(initValues, element, notCreate) { - if (element === undefined) { - if (notCreate) { - item.values(initValues, notCreate); - } else { - item.values(initValues); - } - } else { - item.elm = element; - var values = templater.get(item, initValues); - item.values(values); - } - }; - this.values = function(newValues, notCreate) { - if (newValues !== undefined) { - for(var name in newValues) { - values[name] = newValues[name]; - } - if (notCreate !== true) { - templater.set(item, item.values()); - } - } else { - return values; - } - }; - this.show = function() { - templater.show(item); - }; - this.hide = function() { - templater.hide(item); - }; - this.matching = function() { - return ( - (self.filtered && self.searched && item.found && item.filtered) || - (self.filtered && !self.searched && item.filtered) || - (!self.filtered && self.searched && item.found) || - (!self.filtered && !self.searched) - ); - }; - this.visible = function() { - return (item.elm.parentNode) ? true : false; - }; - init(initValues, element, notCreate); - }; - - /* Templater with different kinds of template engines. - * All engines have these methods - * - reload(item) - * - remove(item) - */ - Templater = function(list, settings) { - if (settings.engine === undefined) { - settings.engine = "standard"; - } else { - settings.engine = settings.engine.toLowerCase(); - } - return new self.constructor.prototype.templateEngines[settings.engine](list, settings); - }; - - init.start(values, options); -}; - -List.prototype.templateEngines = {}; -List.prototype.plugins = {}; - -List.prototype.templateEngines.standard = function(list, settings) { - var listSource = h.getByClass(settings.listClass, list.listContainer, true), - itemSource = getItemSource(settings.item), - templater = this; - - function getItemSource(item) { - if (item === undefined) { - var nodes = listSource.childNodes, - items = []; - - for (var i = 0, il = nodes.length; i < il; i++) { - // Only textnodes have a data attribute - if (nodes[i].data === undefined) { - return nodes[i]; - } - } - return null; - } else if (item.indexOf("<") !== -1) { // Try create html element of list, do not work for tables!! - var div = document.createElement('div'); - div.innerHTML = item; - return div.firstChild; - } else { - return document.getElementById(settings.item); - } - } - - var ensure = { - created: function(item) { - if (item.elm === undefined) { - templater.create(item); - } - } - }; - - /* Get values from element */ - this.get = function(item, valueNames) { - ensure.created(item); - var values = {}; - for(var i = 0, il = valueNames.length; i < il; i++) { - var elm = h.getByClass(valueNames[i], item.elm, true); - values[valueNames[i]] = elm ? elm.innerHTML : ""; - } - return values; - }; - - /* Sets values at element */ - this.set = function(item, values) { - ensure.created(item); - for(var v in values) { - if (values.hasOwnProperty(v)) { - // TODO speed up if possible - var elm = h.getByClass(v, item.elm, true); - if (elm) { - elm.innerHTML = values[v]; - } - } - } - }; - - this.create = function(item) { - if (item.elm !== undefined) { - return; - } - /* If item source does not exists, use the first item in list as - source for new items */ - var newItem = itemSource.cloneNode(true); - newItem.id = ""; - item.elm = newItem; - templater.set(item, item.values()); - }; - this.remove = function(item) { - listSource.removeChild(item.elm); - }; - this.show = function(item) { - ensure.created(item); - listSource.appendChild(item.elm); - }; - this.hide = function(item) { - if (item.elm !== undefined && item.elm.parentNode === listSource) { - listSource.removeChild(item.elm); - } - }; - this.clear = function() { - /* .innerHTML = ''; fucks up IE */ - if (listSource.hasChildNodes()) { - while (listSource.childNodes.length >= 1) - { - listSource.removeChild(listSource.firstChild); - } - } - }; -}; - - -/* -* These helper functions are not written by List.js author Jonny (they may have been -* adjusted, thought). -*/ -h = { - /* - * Cross browser getElementsByClassName, which uses native - * if it exists. Modified version of Dustin Diaz function: - * http://www.dustindiaz.com/getelementsbyclass - */ - getByClass: (function() { - if (document.getElementsByClassName) { - return function(searchClass,node,single) { - if (single) { - return node.getElementsByClassName(searchClass)[0]; - } else { - return node.getElementsByClassName(searchClass); - } - }; - } else { - return function(searchClass,node,single) { - var classElements = [], - tag = '*'; - if (node == null) { - node = document; - } - var els = node.getElementsByTagName(tag); - var elsLen = els.length; - var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)"); - for (var i = 0, j = 0; i < elsLen; i++) { - if ( pattern.test(els[i].className) ) { - if (single) { - return els[i]; - } else { - classElements[j] = els[i]; - j++; - } - } - } - return classElements; - }; - } - })(), - /* (elm, 'event' callback) Source: http://net.tutsplus.com/tutorials/javascript-ajax/javascript-from-null-cross-browser-event-binding/ */ - addEvent: (function( window, document ) { - if ( document.addEventListener ) { - return function( elem, type, cb ) { - if ((elem && !(elem instanceof Array) && !elem.length && !h.isNodeList(elem) && (elem.length !== 0)) || elem === window ) { - elem.addEventListener(type, cb, false ); - } else if ( elem && elem[0] !== undefined ) { - var len = elem.length; - for ( var i = 0; i < len; i++ ) { - h.addEvent(elem[i], type, cb); - } - } - }; - } - else if ( document.attachEvent ) { - return function ( elem, type, cb ) { - if ((elem && !(elem instanceof Array) && !elem.length && !h.isNodeList(elem) && (elem.length !== 0)) || elem === window ) { - elem.attachEvent( 'on' + type, function() { return cb.call(elem, window.event); } ); - } else if ( elem && elem[0] !== undefined ) { - var len = elem.length; - for ( var i = 0; i < len; i++ ) { - h.addEvent( elem[i], type, cb ); - } - } - }; - } - })(this, document), - /* (elm, attribute) Source: http://stackoverflow.com/questions/3755227/cross-browser-javascript-getattribute-method */ - getAttribute: function(ele, attr) { - var result = (ele.getAttribute && ele.getAttribute(attr)) || null; - if( !result ) { - var attrs = ele.attributes; - var length = attrs.length; - for(var i = 0; i < length; i++) { - if (attr[i] !== undefined) { - if(attr[i].nodeName === attr) { - result = attr[i].nodeValue; - } - } - } - } - return result; - }, - /* http://stackoverflow.com/questions/7238177/detect-htmlcollection-nodelist-in-javascript */ - isNodeList: function(nodes) { - var result = Object.prototype.toString.call(nodes); - if (typeof nodes === 'object' && /^\[object (HTMLCollection|NodeList|Object)\]$/.test(result) && (nodes.length == 0 || (typeof nodes[0] === "object" && nodes[0].nodeType > 0))) { - return true; - } - return false; - }, - hasClass: function(ele, classN) { - var classes = this.getAttribute(ele, 'class') || this.getAttribute(ele, 'className') || ""; - return (classes.search(classN) > -1); - }, - addClass: function(ele, classN) { - if (!this.hasClass(ele, classN)) { - var classes = this.getAttribute(ele, 'class') || this.getAttribute(ele, 'className') || ""; - classes = classes + ' ' + classN + ' '; - classes = classes.replace(/\s{2,}/g, ' '); - ele.setAttribute('class', classes); - } - }, - removeClass: function(ele, classN) { - if (this.hasClass(ele, classN)) { - var classes = this.getAttribute(ele, 'class') || this.getAttribute(ele, 'className') || ""; - classes = classes.replace(classN, ''); - ele.setAttribute('class', classes); - } - }, - /* - * The sort function. From http://my.opera.com/GreyWyvern/blog/show.dml/1671288 - */ - sorter: { - alphanum: function(a,b,asc) { - if (a === undefined || a === null) { - a = ""; - } - if (b === undefined || b === null) { - b = ""; - } - a = a.toString().replace(/&(lt|gt);/g, function (strMatch, p1){ - return (p1 == "lt")? "<" : ">"; - }); - a = a.replace(/<\/?[^>]+(>|$)/g, ""); - - b = b.toString().replace(/&(lt|gt);/g, function (strMatch, p1){ - return (p1 == "lt")? "<" : ">"; - }); - b = b.replace(/<\/?[^>]+(>|$)/g, ""); - var aa = this.chunkify(a); - var bb = this.chunkify(b); - - for (var x = 0; aa[x] && bb[x]; x++) { - if (aa[x] !== bb[x]) { - var c = Number(aa[x]), d = Number(bb[x]); - if (asc) { - if (c == aa[x] && d == bb[x]) { - return c - d; - } else { - return (aa[x] > bb[x]) ? 1 : -1; - } - } else { - if (c == aa[x] && d == bb[x]) { - return d-c;//c - d; - } else { - return (aa[x] > bb[x]) ? -1 : 1; //(aa[x] > bb[x]) ? 1 : -1; - } - } - } - } - return aa.length - bb.length; - }, - chunkify: function(t) { - var tz = [], x = 0, y = -1, n = 0, i, j; - - while (i = (j = t.charAt(x++)).charCodeAt(0)) { - var m = (i == 45 || i == 46 || (i >=48 && i <= 57)); - if (m !== n) { - tz[++y] = ""; - n = m; - } - tz[y] += j; - } - return tz; - } - } -}; - -window.List = List; -window.ListJsHelpers = h; -})(window); From 10d1615cd878f33ea4175bfab76e7cca83bd1785 Mon Sep 17 00:00:00 2001 From: Julius Date: Sat, 5 Oct 2013 22:28:04 +0200 Subject: [PATCH 41/79] Prepare tooltip for next bootstrap version (as in 1fed9834b35dbee8b329305b2a62ac1ddf8e0eb7) --- app/views/stock_takings/new.html.haml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/stock_takings/new.html.haml b/app/views/stock_takings/new.html.haml index c46406f3..6e4526f9 100644 --- a/app/views/stock_takings/new.html.haml +++ b/app/views/stock_takings/new.html.haml @@ -10,7 +10,8 @@ $('[data-toggle~="tooltip"]', context).tooltip({ animation: false, html: true, - placement: 'left' + placement: 'left', + container: 'body' }); } From 9041a350d5b15279974241b58515ec3c663ed00f Mon Sep 17 00:00:00 2001 From: Julius Date: Sat, 5 Oct 2013 22:37:17 +0200 Subject: [PATCH 42/79] Add some locales for article attributes --- config/locales/de.yml | 5 +++++ config/locales/en.yml | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/config/locales/de.yml b/config/locales/de.yml index bed1f8b9..ea3d9bf8 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -42,7 +42,10 @@ de: fc_price: Endpreis fc_share: FC-Aufschlag gross_price: Bruttopreis + name: Name + note: Notiz price: Nettopreis + supplier: Lieferantin tax: MwSt unit: Einheit unit_quantity: Gebindegröße @@ -51,6 +54,8 @@ de: note: Notiz stock_article: price: Nettopreis + quantity: Lagerbestand + quantity_available: Verfügbarer Bestand user: first_name: Vorname password: Passwort diff --git a/config/locales/en.yml b/config/locales/en.yml index cebb1c8e..d54afc8a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -42,7 +42,10 @@ en: fc_price: FC price fc_share: FC share gross_price: gross price + name: name + note: note price: price + supplier: supplier tax: VAT unit: unit unit_quantity: unit quantity @@ -50,7 +53,9 @@ en: amount: amount note: note stock_article: - price: Price + price: price + quantity: quantity + quantity_available: available quantity user: first_name: First name password: Password From 1b49a08c5e4084ee4c77f3594bb2a533b32b9876 Mon Sep 17 00:00:00 2001 From: wvengen Date: Tue, 8 Oct 2013 11:42:23 +0200 Subject: [PATCH 43/79] localeapp roundtrip --- config/locales/de.yml | 2 +- config/locales/en.yml | 2 +- config/locales/fr.yml | 7 +++++++ config/locales/nl.yml | 7 +++++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/config/locales/de.yml b/config/locales/de.yml index 8b2c4bb2..ab2c694b 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -802,7 +802,7 @@ de: note: Notiz price: Preis reset_article_search: Suche zurücksetzen - search_article: Artikel suchen... + search_article: Artikel suchen... sum: Summe sum_amount: ! 'Gesamtbestellmenge bisher:' supplier: Lieferant diff --git a/config/locales/en.yml b/config/locales/en.yml index 9b514e31..f7d04466 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -806,7 +806,7 @@ en: note: Note price: Price reset_article_search: Reset search - search_article: Search for article... + search_article: Search for article... sum: Sum sum_amount: Current amount supplier: Supplier diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 835bbdfe..f9b71327 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -42,7 +42,10 @@ fr: fc_price: prix final fc_share: supplément boufcoop gross_price: prix brut + name: + note: price: prix net + supplier: tax: TVA unit: unité unit_quantity: unités par lot @@ -51,6 +54,8 @@ fr: note: note stock_article: price: Prix net + quantity: + quantity_available: user: first_name: Prénom password: Mot de passe @@ -811,6 +816,8 @@ fr: new_funds: Nouveau solde note: Note price: Prix + reset_article_search: + search_article: sum: Prix total sum_amount: ! 'Quantité déjà commandée:' supplier: Fourni par diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 5a3d4f99..2bef7df0 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -42,7 +42,10 @@ nl: fc_price: prijs foodcoop fc_share: marge foodcoop gross_price: bruto prijs + name: + note: price: netto prijs + supplier: tax: BTW unit: eenheid unit_quantity: groothandelseenheid @@ -51,6 +54,8 @@ nl: note: notitie stock_article: price: prijs + quantity: + quantity_available: user: first_name: Voornaam password: Wachtwoord @@ -797,6 +802,8 @@ nl: new_funds: Nieuw tegoed note: Notitie price: Prijs + reset_article_search: + search_article: sum: Som sum_amount: ! 'Huidig totaalbedrag:' supplier: Leverancier From 28644dc33406eec4b023fd340662f80f9cc1f35c Mon Sep 17 00:00:00 2001 From: Julius Date: Tue, 8 Oct 2013 19:58:11 +0200 Subject: [PATCH 44/79] Force update in Order#finish; rescue if error raised --- app/controllers/orders_controller.rb | 2 ++ app/models/order.rb | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/orders_controller.rb b/app/controllers/orders_controller.rb index 7fba518a..e1cd7698 100644 --- a/app/controllers/orders_controller.rb +++ b/app/controllers/orders_controller.rb @@ -98,6 +98,8 @@ class OrdersController < ApplicationController order = Order.find(params[:id]) order.finish!(@current_user) redirect_to order, notice: I18n.t('orders.finish.notice') + rescue => error + redirect_to orders_url, alert: I18n.t('errors.general_msg', :msg => error.message) end # Renders the fax-text-file diff --git a/app/models/order.rb b/app/models/order.rb index f4545d02..057c0768 100644 --- a/app/models/order.rb +++ b/app/models/order.rb @@ -155,7 +155,7 @@ class Order < ActiveRecord::Base unless finished? Order.transaction do # set new order state (needed by notify_order_finished) - update_attributes(:state => 'finished', :ends => Time.now, :updated_by => user) + update_attributes!(:state => 'finished', :ends => Time.now, :updated_by => user) # Update order_articles. Save the current article_price to keep price consistency # Also save results for each group_order_result From b8ff4316345b22b782693a4c13c11520e7cb76b9 Mon Sep 17 00:00:00 2001 From: wvengen Date: Wed, 9 Oct 2013 10:35:27 +0200 Subject: [PATCH 45/79] clean up price tooltips javascript --- app/assets/javascripts/application.js | 16 ++++++++++++++++ app/views/deliveries/_form.html.haml | 11 ----------- app/views/deliveries/add_stock_change.js.erb | 1 - app/views/deliveries/create_stock_article.js.erb | 1 - app/views/deliveries/update_stock_article.js.erb | 1 - app/views/stock_takings/new.html.haml | 15 --------------- 6 files changed, 16 insertions(+), 29 deletions(-) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 39b99a65..221e83b0 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -120,6 +120,20 @@ $(function() { // Use bootstrap datepicker for dateinput $('.datepicker').datepicker({format: 'yyyy-mm-dd', language: I18n.locale}); + + // bootstrap tooltips (for price) + // Extra options don't work when using selector, so override defaults + // https://github.com/twbs/bootstrap/issues/3875 . These can still be + // overridden per tooltip using data-placement attributes and the like. + $.extend($.fn.tooltip.defaults, { + html: true, + animation: false, + placement: 'left', + container: 'body' + }); + $(document).tooltip({ + selector: '[data-toggle~="tooltip"]', + }); // See stupidtable.js for initialization of local table sorting }); @@ -146,3 +160,5 @@ function highlightRow(checkbox) { function setHiddenId(text, li) { $('hidden_id').value = li.id; } + + diff --git a/app/views/deliveries/_form.html.haml b/app/views/deliveries/_form.html.haml index c9bd8fcd..3e1a3b6c 100644 --- a/app/views/deliveries/_form.html.haml +++ b/app/views/deliveries/_form.html.haml @@ -61,8 +61,6 @@ return true; } }); - - enablePriceTooltips(); }); function mark_article_for_delivery(stock_article_id) { @@ -80,15 +78,6 @@ return ( 0 == $('#stock_change_stock_article_' + stock_article_id).length ); } - function enablePriceTooltips(context) { - $('[data-toggle~="tooltip"]', context).tooltip({ - animation: false, - html: true, - placement: 'left', - container: 'body' // or they become a cell in the table - }); - } - = simple_form_for [@supplier, @delivery], validate: true do |f| = f.error_notification = base_errors f.object diff --git a/app/views/deliveries/add_stock_change.js.erb b/app/views/deliveries/add_stock_change.js.erb index 3e233bb6..2d01bc68 100644 --- a/app/views/deliveries/add_stock_change.js.erb +++ b/app/views/deliveries/add_stock_change.js.erb @@ -13,7 +13,6 @@ var stock_change = $( '<%= j(render(:partial => 'stock_change', :locals => {:stock_change => @stock_change})) %>' ).addClass('success'); - enablePriceTooltips(stock_change); $('input.stock-change-quantity', stock_change).val(quantity); $('#stock_changes').append(stock_change); diff --git a/app/views/deliveries/create_stock_article.js.erb b/app/views/deliveries/create_stock_article.js.erb index 5e2893a9..cb9d0159 100644 --- a/app/views/deliveries/create_stock_article.js.erb +++ b/app/views/deliveries/create_stock_article.js.erb @@ -8,7 +8,6 @@ $('div.container-fluid').prepend( var stock_article_for_adding = $( '<%= j(render(:partial => 'stock_article_for_adding', :locals => {:article => @stock_article})) %>' ).addClass('success'); - enablePriceTooltips(stock_article_for_adding); $('#stock_articles_for_adding tbody').append(stock_article_for_adding); updateSort('#stock_articles_for_adding'); diff --git a/app/views/deliveries/update_stock_article.js.erb b/app/views/deliveries/update_stock_article.js.erb index ef46636d..7b2d56d6 100644 --- a/app/views/deliveries/update_stock_article.js.erb +++ b/app/views/deliveries/update_stock_article.js.erb @@ -10,7 +10,6 @@ $('div.container-fluid').prepend( var stock_article_for_adding = $( '<%= j(render(:partial => 'stock_article_for_adding', :locals => {:article => @stock_article, :delivery => @delivery})) %>' ).addClass('success'); - enablePriceTooltips(stock_article_for_adding); $('#stock_article_<%= @stock_article.id %>').replaceWith(stock_article_for_adding); updateSort('#stock_articles_for_adding'); diff --git a/app/views/stock_takings/new.html.haml b/app/views/stock_takings/new.html.haml index 6e4526f9..51239ba4 100644 --- a/app/views/stock_takings/new.html.haml +++ b/app/views/stock_takings/new.html.haml @@ -1,20 +1,5 @@ - title t('.title') -- content_for :javascript do - :javascript - $(function() { - enablePriceTooltips(); - }); - - function enablePriceTooltips(context) { - $('[data-toggle~="tooltip"]', context).tooltip({ - animation: false, - html: true, - placement: 'left', - container: 'body' - }); - } - - content_for :sidebar do %p %i= t('.text_deviations', inv_link: link_to(t('.temp_inventory'), stock_articles_path)).html_safe From 762292ef8e61bca3c2534693901acc56c759b6ed Mon Sep 17 00:00:00 2001 From: wvengen Date: Wed, 9 Oct 2013 22:29:19 +0200 Subject: [PATCH 46/79] small i18n move --- app/controllers/orders_controller.rb | 4 ++-- config/locales/de.yml | 1 - config/locales/en.yml | 3 +-- config/locales/fr.yml | 1 - config/locales/nl.yml | 3 +-- 5 files changed, 4 insertions(+), 8 deletions(-) diff --git a/app/controllers/orders_controller.rb b/app/controllers/orders_controller.rb index 7fba518a..65dc951b 100644 --- a/app/controllers/orders_controller.rb +++ b/app/controllers/orders_controller.rb @@ -107,9 +107,9 @@ class OrdersController < ApplicationController supplier = order.supplier contact = FoodsoftConfig[:contact].symbolize_keys text = I18n.t('orders.fax.heading', :name => FoodsoftConfig[:name]) - text += "\n" + I18n.t('orders.fax.customer_number') + ': #{supplier.customer_number}' unless supplier.customer_number.blank? + text += "\n#{Supplier.human_attribute_name(:customer_number)}: #{supplier.customer_number}" unless supplier.customer_number.blank? text += "\n" + I18n.t('orders.fax.delivery_day') - text += "\n\n#{supplier.name}\n#{supplier.address}\n" + I18n.t('simple_form.labels.supplier.fax') + ": #{supplier.fax}\n\n" + text += "\n\n#{supplier.name}\n#{supplier.address}\n#{Supplier.human_attribute_name(:fax)}: #{supplier.fax}\n\n" text += "****** " + I18n.t('orders.fax.to_address') + "\n\n" text += "#{FoodsoftConfig[:name]}\n#{contact[:street]}\n#{contact[:zip_code]} #{contact[:city]}\n\n" text += "****** " + I18n.t('orders.fax.articles') + "\n\n" diff --git a/config/locales/de.yml b/config/locales/de.yml index 8efaf074..802084f1 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -1307,7 +1307,6 @@ de: fax: amount: Menge articles: Artikel - customer_number: Kundennummer delivery_day: Liefertag heading: Bestellung für %{name} name: Name diff --git a/config/locales/en.yml b/config/locales/en.yml index ad133361..afd0b49e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1320,7 +1320,6 @@ en: fax: amount: Amount articles: Articles - customer_number: Customer number delivery_day: Delivery day heading: Order for %{name} name: Name @@ -1652,7 +1651,7 @@ en: supplier: address: Address contact_person: Contact person - customer_number: Customer ID + customer_number: Customer number delivery_days: Delivery days email: Email fax: Fax diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 2c176d31..50ae3b5b 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -1307,7 +1307,6 @@ fr: fax: amount: Quantité articles: Articles - customer_number: Numéro de client de la coop delivery_day: Jour de livraison heading: Commande pour %{name} name: Nom diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 05b3ea5e..50c7ccd6 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -1235,7 +1235,6 @@ nl: fax: amount: Aantal articles: Artikelen - customer_number: Klantnummer delivery_day: Bezorgdag heading: Bestelling voor %{name} name: Naam @@ -1575,7 +1574,7 @@ nl: supplier: address: contact_person: - customer_number: + customer_number: Klantnummer delivery_days: Bezorgdagen email: fax: From 552af7925d6ecf865962f638093c5bc77af8be1b Mon Sep 17 00:00:00 2001 From: wvengen Date: Wed, 9 Oct 2013 22:41:23 +0200 Subject: [PATCH 47/79] i18n simple_form move of tasks --- app/views/tasks/show.haml | 12 ++++++------ config/locales/en.yml | 18 +++++++++--------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/app/views/tasks/show.haml b/app/views/tasks/show.haml index 644151fa..86de92bf 100644 --- a/app/views/tasks/show.haml +++ b/app/views/tasks/show.haml @@ -3,22 +3,22 @@ %section %dl.dl-horizontal - %dt= t 'simple_form.labels.task.name' + %dt= Task.human_attribute_name(:name) %dd= @task.name - if @task.description.present? - %dt= t 'simple_form.labels.defaults.description' + %dt= Task.human_attribute_name(:description) %dd= simple_format(@task.description) - if @task.due_date.present? - %dt= t '.due_date' + %dt= Task.human_attribute_name(:due_date) %dd = format_date(@task.due_date) - if @task.periodic? %i.icon-repeat{title: t('tasks.repeated')} - %dt= t 'simple_form.labels.task.duration' + %dt= Task.human_attribute_name(:duration) %dd= t('.hours', count: @task.duration) - %dt= t 'simple_form.labels.task.user_list' + %dt= Task.human_attribute_name(:user_list) %dd= task_assignments(@task) - %dt= t 'simple_form.labels.task.workgroup' + %dt= Task.human_attribute_name(:workgroup) %dd - if @task.workgroup = link_to @task.workgroup.name, workgroup_tasks_path(workgroup_id: @task.workgroup_id) diff --git a/config/locales/en.yml b/config/locales/en.yml index afd0b49e..4d46865d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -62,6 +62,14 @@ en: note: note stock_article: price: Price + task: + done: Done? + due_date: Due date + duration: Duration + name: Name + required_users: People required + user_list: Responsible user + workgroup: Workgroup user: first_name: First name password: Password @@ -1663,14 +1671,6 @@ en: phone: Phone phone2: Phone 2 url: Homepage - task: - done: Done? - due_date: Due date - duration: Duration - name: Name - required_users: People required - user_list: Responsible user - workgroup: Workgroup user: email: Email last_name: Last name @@ -1869,9 +1869,9 @@ en: notice: The state of the task has been updated show: accept_task: Accept task + confirm_delete_single: Are you sure you want to delete the task? confirm_delete_group: Really delete this and all subsequent tasks? delete_group: Delete task and subsequent - due_date: Due date hours: ! '%{count}h' mark_done: Mark task as done reject_task: Reject task From 78c81b194c668d4674abc40609b8f6402a0e2256 Mon Sep 17 00:00:00 2001 From: wvengen Date: Wed, 9 Oct 2013 23:00:07 +0200 Subject: [PATCH 48/79] i18n simple_form move of foodcoop --- app/helpers/application_helper.rb | 6 ++++-- app/views/foodcoop/users/_users.html.haml | 12 ++++++------ config/locales/de.yml | 19 +++++++++---------- config/locales/en.yml | 19 +++++++++---------- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index c9caff30..46f5e6c9 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -79,10 +79,12 @@ module ApplicationHelper # When there is a non-empty model attribute 'foo', it looks for # the model attribute translation 'foo_short' and use that as # heading, with an acronym title of 'foo'. + # Other options are passed through to I18n. def heading_helper(model, attribute, options = {}) - s = model.human_attribute_name(attribute) + i18nopts = options.select {|a| !['short'].include?(a) } + s = model.human_attribute_name(attribute, i18nopts) if options[:short] - sshort = model.human_attribute_name("#{attribute}_short".to_sym, default: '') + sshort = model.human_attribute_name("#{attribute}_short".to_sym, options.merge({defaults: ''})) s = raw "#{sshort}" unless sshort.empty? end s diff --git a/app/views/foodcoop/users/_users.html.haml b/app/views/foodcoop/users/_users.html.haml index 90b1de3a..1ecbb107 100644 --- a/app/views/foodcoop/users/_users.html.haml +++ b/app/views/foodcoop/users/_users.html.haml @@ -4,12 +4,12 @@ %table.table.table-striped %thead %tr - %th= t 'simple_form.labels.user.nick' - %th= t 'simple_form.labels.user.name' - %th= t 'simple_form.labels.user.email' - %th= t 'simple_form.labels.user.phone' - %th= t 'simple_form.labels.user.ordergroup' - %th= t 'simple_form.labels.user.workgroup', count: 3 + %th= heading_helper User, :nick + %th= heading_helper User, :name + %th= heading_helper User, :email + %th= heading_helper User, :phone + %th= heading_helper User, :ordergroup + %th= heading_helper User, :workgroup, count: 3 %tbody - for user in @users %tr diff --git a/config/locales/de.yml b/config/locales/de.yml index 802084f1..98fdcca6 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -52,8 +52,17 @@ de: stock_article: price: Nettopreis user: + email: Email first_name: Vorname + last_name: Nachname + name: Name + nick: Benutzername + ordergroup: Bestellgruppe password: Passwort + phone: Telefon + workgroup: + one: Arbeitsgruppe + other: Arbeitsgruppen errors: format: ! '%{attribute} %{message}' general: Ein Problem ist aufgetreten. @@ -1668,16 +1677,6 @@ de: required_users: Anzahl user_list: Verantwortliche workgroup: Arbeitsgruppe - user: - email: Email - last_name: Nachname - name: Name - nick: Benutzername - ordergroup: Bestellgruppe - phone: Telefon - workgroup: - one: Arbeitsgruppe - other: Arbeitsgruppen workgroup: next_weekly_tasks_number: Für wieviel Wochen im Voraus sollen Aufgaben erstellt werden? role_admin: Administration diff --git a/config/locales/en.yml b/config/locales/en.yml index 4d46865d..54581e6a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -71,8 +71,17 @@ en: user_list: Responsible user workgroup: Workgroup user: + email: Email first_name: First name + last_name: Last name + name: Name + nick: Username + ordergroup: Ordergroup password: Password + phone: Telephone + workgroup: + one: Workgroup + other: Workgroups errors: format: ! '%{attribute} %{message}' general: A problem has occured. @@ -1671,16 +1680,6 @@ en: phone: Phone phone2: Phone 2 url: Homepage - user: - email: Email - last_name: Last name - name: Name - nick: Username - ordergroup: Ordergroup - phone: Telephone - workgroup: - one: Workgroup - other: Workgroups workgroup: next_weekly_tasks_number: For how many weeks in advance would you like to define tasks? role_admin: Administration From c3d22e883df4243f53161161a21ab301e93621c8 Mon Sep 17 00:00:00 2001 From: wvengen Date: Wed, 9 Oct 2013 23:12:26 +0200 Subject: [PATCH 49/79] i18n simple_form move of suppliers --- app/views/suppliers/index.haml | 6 ++--- app/views/suppliers/shared_suppliers.haml | 10 ++++---- app/views/suppliers/show.haml | 28 ++++++++++---------- config/locales/de.yml | 31 ++++++++++++----------- config/locales/en.yml | 30 +++++++++++----------- 5 files changed, 53 insertions(+), 52 deletions(-) diff --git a/app/views/suppliers/index.haml b/app/views/suppliers/index.haml index 2ea9ad27..e49c8f83 100644 --- a/app/views/suppliers/index.haml +++ b/app/views/suppliers/index.haml @@ -6,9 +6,9 @@ %table.table.table-striped %thead %tr - %th= t 'simple_form.labels.supplier.name' - %th= t 'simple_form.labels.supplier.phone' - %th= t 'simple_form.labels.supplier.customer_number' + %th= heading_helper Supplier, :name + %th= heading_helper Supplier, :phone + %th= heading_helper Supplier, :customer_number, short: true %th %th %th diff --git a/app/views/suppliers/shared_suppliers.haml b/app/views/suppliers/shared_suppliers.haml index 22cf67da..8e9c3eef 100644 --- a/app/views/suppliers/shared_suppliers.haml +++ b/app/views/suppliers/shared_suppliers.haml @@ -4,11 +4,11 @@ %table.table.table-striped %thead %tr - %th= t 'simple_form.labels.supplier.name' - %th= t 'simple_form.labels.supplier.address' - %th= t 'simple_form.labels.supplier.note' - %th= t 'simple_form.labels.supplier.delivery_days' - %th= t 'simple_form.labels.supplier.is_subscribed' + %th= heading_helper Supplier, :name + %th= heading_helper Supplier, :address + %th= heading_helper Supplier, :note + %th= heading_helper Supplier, :delivery_days + %th= heading_helper Supplier, :is_subscribed %tbody - for shared_supplier in @shared_suppliers %tr diff --git a/app/views/suppliers/show.haml b/app/views/suppliers/show.haml index 0a9417fe..1b239775 100644 --- a/app/views/suppliers/show.haml +++ b/app/views/suppliers/show.haml @@ -7,29 +7,29 @@ = t 'suppliers.shared_supplier_note' %dl.dl-horizontal - %dt= t('simple_form.labels.supplier.address') + ':' + %dt= heading_helper(Supplier, :address) + ':' %dd= @supplier.address - %dt= t('simple_form.labels.supplier.phone') + ':' + %dt= heading_helper(Supplier, :phone) + ':' %dd= @supplier.phone - %dt= t('simple_form.labels.supplier.phone2') + ':' + %dt= heading_helper(Supplier, :phone2) + ':' %dd= @supplier.phone2 - %dt= t('simple_form.labels.supplier.fax') + ':' + %dt= heading_helper(Supplier, :fax) + ':' %dd= @supplier.fax - %dt= t('simple_form.labels.supplier.email') + ':' + %dt= heading_helper(Supplier, :email) + ':' %dd= @supplier.email - %dt= t('simple_form.labels.supplier.url') + ':' + %dt= heading_helper(Supplier, :url) + ':' %dd= link_to @supplier.url, @supplier.url - %dt= t('simple_form.labels.supplier.contact_person') + ':' + %dt= heading_helper(Supplier, :contact_person) + ':' %dd= @supplier.contact_person - %dt= t('simple_form.labels.supplier.customer_number') + ':' + %dt= heading_helper(Supplier, :customer_number) + ':' %dd= @supplier.customer_number - %dt= t('simple_form.labels.supplier.delivery_days') + ':' + %dt= heading_helper(Supplier, :delivery_days) + ':' %dd= @supplier.delivery_days - %dt= t('simple_form.labels.supplier.order_howto') + ':' + %dt= heading_helper(Supplier, :order_howto) + ':' %dd= @supplier.order_howto - %dt= t('simple_form.labels.supplier.note') + ':' + %dt= heading_helper(Supplier, :note) + ':' %dd= @supplier.note - %dt= t('simple_form.labels.supplier.min_order_quantity') + ':' + %dt= heading_helper(Supplier, :min_order_quantity) + ':' %dd= @supplier.min_order_quantity .clearfix @@ -43,8 +43,8 @@ %table.table.table-horizontal %thead %tr - %th= t 'simple_form.labels.defaults.date' - %th= t 'simple_form.labels.defaults.amount' + %th= heading_helper Delivery, :date + %th= heading_helper Delivery, :amount %tbody - for delivery in @deliveries %tr diff --git a/config/locales/de.yml b/config/locales/de.yml index 98fdcca6..b2f0f149 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -51,6 +51,22 @@ de: note: Notiz stock_article: price: Nettopreis + supplier: + address: Adresse + contact_person: Ansprechparter_in + customer_number: Kundennummer + customer_number_short: Kundennr. + delivery_days: Liefertage + email: Email + fax: FAX + is_subscribed: abonniert? + min_order_quantity: Mindestbestellmenge + name: Name + note: Notiz + order_howto: Howto Bestellen + phone: Telefon + phone2: Telefon 2 + url: Homepage user: email: Email first_name: Vorname @@ -1654,21 +1670,6 @@ de: privacy: Privatsphäre stock_article: supplier: Lieferant - supplier: - address: Adresse - contact_person: Ansprechparter_in - customer_number: Kundennummer - delivery_days: Liefertage - email: Email - fax: FAX - is_subscribed: abonniert? - min_order_quantity: Mindestbestellmenge - name: Name - note: Notiz - order_howto: Howto Bestellen - phone: Telefon - phone2: Telefon 2 - url: Homepage task: done: Erledigt? due_date: Wann erledigen? diff --git a/config/locales/en.yml b/config/locales/en.yml index 54581e6a..65b84388 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -62,6 +62,21 @@ en: note: note stock_article: price: Price + supplier: + address: Address + contact_person: Contact person + customer_number: Customer number + delivery_days: Delivery days + email: Email + fax: Fax + is_subscribed: subscribed? + min_order_quantity: Minimum order quantity + name: Name + note: Note + order_howto: How to order + phone: Phone + phone2: Phone 2 + url: Homepage task: done: Done? due_date: Due date @@ -1665,21 +1680,6 @@ en: privacy: Privacy stock_article: supplier: Supplier - supplier: - address: Address - contact_person: Contact person - customer_number: Customer number - delivery_days: Delivery days - email: Email - fax: Fax - is_subscribed: subscribed? - min_order_quantity: Minimum order quantity - name: Name - note: Note - order_howto: How to order - phone: Phone - phone2: Phone 2 - url: Homepage workgroup: next_weekly_tasks_number: For how many weeks in advance would you like to define tasks? role_admin: Administration From 6ba971fe15f5e2774680141423b5d7f56450a031 Mon Sep 17 00:00:00 2001 From: wvengen Date: Wed, 9 Oct 2013 23:19:40 +0200 Subject: [PATCH 50/79] i18n simple_form move of deliveries --- app/views/deliveries/index.html.haml | 4 ++-- app/views/deliveries/show.html.haml | 6 +++--- config/locales/de.yml | 7 ++++--- config/locales/en.yml | 6 +++--- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/app/views/deliveries/index.html.haml b/app/views/deliveries/index.html.haml index 16b0388b..423332b1 100644 --- a/app/views/deliveries/index.html.haml +++ b/app/views/deliveries/index.html.haml @@ -3,9 +3,9 @@ %table.table.table-striped %thead %tr - %th= t 'simple_form.labels.delivery.delivered_on' + %th= heading_helper Delivery, :delivered_on %th.numeric= t 'deliveries.invoice_amount' - %th= t 'simple_form.labels.defaults.note' + %th= heading_helper Delivery, :note %tbody - for delivery in @deliveries %tr diff --git a/app/views/deliveries/show.html.haml b/app/views/deliveries/show.html.haml index 05a39db6..d5df7fd5 100644 --- a/app/views/deliveries/show.html.haml +++ b/app/views/deliveries/show.html.haml @@ -1,16 +1,16 @@ - title t('.title') %dl - %dt= t 'simple_form.labels.delivery.supplier' + %dt= heading_helper Delivery, :supplier %dd= @delivery.supplier.name - %dt= t 'simple_form.labels.delivery.delivered_on' + %dt= heading_helper Delivery, :delivered_on %dd= @delivery.delivered_on %dt= t 'deliveries.invoice_amount' %dd= link_to_invoice(@delivery) - if @delivery.invoice %dt= t 'deliveries.invoice_net_amount' %dd= number_to_currency @delivery.invoice.net_amount - %dt= t 'simple_form.labels.defaults.note' + %dt= heading_helper Delivery, :note %dd= simple_format @delivery.note %h2= t '.title_articles' diff --git a/config/locales/de.yml b/config/locales/de.yml index b2f0f149..0145c947 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -46,6 +46,10 @@ de: tax: MwSt unit: Einheit unit_quantity: Gebindegröße + delivery: + delivered_on: Lieferdatum + note: Notiz + supplier: Lieferantin financial_transaction: amount: Betrag note: Notiz @@ -1612,9 +1616,6 @@ de: title: Titel unit_quantity: Gebindegröße user_tokens: Mitglieder - delivery: - delivered_on: Lieferdatum - supplier: Lieferantin group_order_article: ordergroup_id: Bestellgruppe result: Menge diff --git a/config/locales/en.yml b/config/locales/en.yml index 65b84388..fb322d84 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -57,6 +57,9 @@ en: article_category: description: Description name: Name + delivery: + delivered_on: Delivery date + supplier: Supplier financial_transaction: amount: amount note: note @@ -1622,9 +1625,6 @@ en: title: Title unit_quantity: Unit quantity user_tokens: Members - delivery: - delivered_on: Delivery date - supplier: Supplier group_order_article: ordergroup_id: Ordergroup result: Amount From 67e29620f4e957bdd5c5a4a9e88afaff3b5d1810 Mon Sep 17 00:00:00 2001 From: wvengen Date: Wed, 9 Oct 2013 23:37:08 +0200 Subject: [PATCH 51/79] i18n simple_form move of invoices --- .../finance/invoices/_invoices.html.haml | 16 +++++++------- app/views/finance/invoices/show.html.haml | 20 ++++++++--------- config/locales/de.yml | 22 +++++++++---------- config/locales/en.yml | 22 +++++++++---------- 4 files changed, 40 insertions(+), 40 deletions(-) diff --git a/app/views/finance/invoices/_invoices.html.haml b/app/views/finance/invoices/_invoices.html.haml index 1663c609..621a08fe 100644 --- a/app/views/finance/invoices/_invoices.html.haml +++ b/app/views/finance/invoices/_invoices.html.haml @@ -5,14 +5,14 @@ %table.table.table-striped %thead %tr - %th= t 'simple_form.labels.invoice.number' - %th= t 'simple_form.labels.invoice.supplier' - %th= t 'simple_form.labels.invoice.date' - %th= t 'simple_form.labels.invoice.paid_on' - %th= t 'simple_form.labels.invoice.amount' - %th= t 'simple_form.labels.invoice.delivery' - %th= t 'simple_form.labels.invoice.order' - %th= t 'simple_form.labels.invoice.note' + %th= heading_helper Invoice, :number + %th= heading_helper Invoice, :supplier + %th= heading_helper Invoice, :date + %th= heading_helper Invoice, :paid_on + %th= heading_helper Invoice, :amount + %th= heading_helper Invoice, :delivery + %th= heading_helper Invoice, :order + %th= heading_helper Invoice, :note %th %th %tbody diff --git a/app/views/finance/invoices/show.html.haml b/app/views/finance/invoices/show.html.haml index 28bb4519..1106aa5c 100644 --- a/app/views/finance/invoices/show.html.haml +++ b/app/views/finance/invoices/show.html.haml @@ -1,38 +1,38 @@ - title t('.title', number: @invoice.number) %p - %b= t('simple_form.labels.invoice.supplier') + ':' + %b= heading_helper(Invoice, :supplier) + ':' = @invoice.supplier.name - if @invoice.delivery %p - %b= t('simple_form.labels.invoice.delivery') + ':' + %b= heading_helper(Invoice, :delivery) + ':' = t('finance.invoices.linked', what_link: link_to(t('finance.invoices.linked_delivery'), [@invoice.supplier,@invoice.delivery])).html_safe - if @invoice.order %p - %b= t('simple_form.labels.invoice.order') + ':' + %b= heading_helper(Invoice, :order) + ':' = t('finance.invoices.linked', what_link: link_to(t('finance.invoices.linked_order'), @invoice.order)).html_safe %p - %b= t('simple_form.labels.invoice.number') + ':' + %b= heading_helper(Invoice, :number) + ':' = @invoice.number %p - %b= t('simple_form.labels.invoice.date') + ':' + %b= heading_helper(Invoice, :date) + ':' = @invoice.date %p - %b= t('simple_form.labels.invoice.paid_on') + ':' + %b= heading_helper(Invoice, :paid_on) + ':' = @invoice.paid_on %p - %b= t('simple_form.labels.invoice.amount') + ':' + %b= heading_helper(Invoice, :amount) + ':' = number_to_currency @invoice.amount %p - %b= t('simple_form.labels.invoice.deposit') + ':' + %b= heading_helper(Invoice, :deposit) + ':' = number_to_currency @invoice.deposit %p - %b= t('simple_form.labels.invoice.deposit_credit') + ':' + %b= heading_helper(Invoice, :deposit_credit) + ':' = number_to_currency @invoice.deposit_credit %p - %b= t('simple_form.labels.invoice.note') + ':' + %b= heading_helper(Invoice, :note) + ':' =h @invoice.note = link_to t('ui.edit'), edit_finance_invoice_path(@invoice) diff --git a/config/locales/de.yml b/config/locales/de.yml index 0145c947..f016c5c5 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -53,6 +53,17 @@ de: financial_transaction: amount: Betrag note: Notiz + invoice: + amount: Betrag + date: Rechnungsdatum + delivery: Lieferung + deposit: Pfand berechnet + deposit_credit: Pfand gutgeschrieben + note: Notiz + number: Nummer + order: Bestellung + paid_on: Bezahlt am + supplier: Lieferant stock_article: price: Nettopreis supplier: @@ -1619,17 +1630,6 @@ de: group_order_article: ordergroup_id: Bestellgruppe result: Menge - invoice: - amount: Betrag - date: Rechnungsdatum - delivery: Lieferung - deposit: Pfand berechnet - deposit_credit: Pfand gutgeschrieben - note: Notiz - number: Nummer - order: Bestellung - paid_on: Bezahlt am - supplier: Lieferant message: body: Inhalt group_id: Gruppe diff --git a/config/locales/en.yml b/config/locales/en.yml index fb322d84..dfdb1475 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -63,6 +63,17 @@ en: financial_transaction: amount: amount note: note + invoice: + amount: Amount + date: Billing date + delivery: Delivery + deposit: Deposit charged + deposit_credit: Deposit returned + note: Note + number: Number + order: Order + paid_on: Paid on + supplier: Supplier stock_article: price: Price supplier: @@ -1628,17 +1639,6 @@ en: group_order_article: ordergroup_id: Ordergroup result: Amount - invoice: - amount: Amount - date: Billing date - delivery: Delivery - deposit: Deposit charged - deposit_credit: Deposit returned - note: Note - number: Number - order: Order - paid_on: Paid on - supplier: Supplier message: body: Body group_id: Group From 6c17c179824786e057875d4d6a9070b1c7cd57e0 Mon Sep 17 00:00:00 2001 From: wvengen Date: Wed, 9 Oct 2013 23:41:15 +0200 Subject: [PATCH 52/79] i18n simple_form move of fax pdf --- app/documents/order_fax.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/documents/order_fax.rb b/app/documents/order_fax.rb index f2182944..766a784c 100644 --- a/app/documents/order_fax.rb +++ b/app/documents/order_fax.rb @@ -21,15 +21,15 @@ class OrderFax < OrderPdf text "#{contact[:zip_code]} #{contact[:city]}", size: 9, align: :right move_down 5 unless @order.supplier.try(:customer_number).blank? - text "#{I18n.t('simple_form.labels.supplier.customer_number')}: #{@order.supplier[:customer_number]}", size: 9, align: :right + text "#{Supplier.human_attribute_name :customer_number}: #{@order.supplier[:customer_number]}", size: 9, align: :right move_down 5 end unless contact[:phone].blank? - text "#{I18n.t('simple_form.labels.supplier.phone')}: #{contact[:phone]}", size: 9, align: :right + text "#{Supplier.human_attribute_name :phone}: #{contact[:phone]}", size: 9, align: :right move_down 5 end unless contact[:email].blank? - text "#{I18n.t('simple_form.labels.supplier.email')}: #{contact[:email]}", size: 9, align: :right + text "#{Supplier.human_attribute_name :email}: #{contact[:email]}", size: 9, align: :right end end @@ -40,7 +40,7 @@ class OrderFax < OrderPdf text @order.supplier.try(:address).to_s unless @order.supplier.try(:fax).blank? move_down 5 - text "#{I18n.t('simple_form.labels.supplier.fax')}: #{@order.supplier[:fax]}" + text "#{Supplier.human_attribute_name :fax}: #{@order.supplier[:fax]}" end end @@ -48,10 +48,10 @@ class OrderFax < OrderPdf text Date.today.strftime(I18n.t('date.formats.default')), align: :right move_down 10 - text "#{I18n.t('simple_form.labels.delivery.delivered_on')}:" + text "#{Delivery.human_attribute_name :delivered_on}:" move_down 10 unless @order.supplier.try(:contact_person).blank? - text "#{I18n.t('simple_form.labels.supplier.contact_person')}: #{@order.supplier[:contact_person]}" + text "#{Supplier.human_attribute_name :contact_person}: #{@order.supplier[:contact_person]}" move_down 10 end From 1afd8b83874d78bf492ab28637b92d896a2e900c Mon Sep 17 00:00:00 2001 From: wvengen Date: Thu, 10 Oct 2013 17:47:12 +0200 Subject: [PATCH 53/79] bundle update --- Gemfile.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 83e3a43a..00e6eebe 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -87,7 +87,7 @@ GEM coffee-script-source (1.6.3) commonjs (0.2.7) daemons (1.1.9) - database_cleaner (1.1.1) + database_cleaner (1.2.0) debug_inspector (0.0.2) diff-lcs (1.2.4) erubis (2.7.0) @@ -160,7 +160,7 @@ GEM mime-types (1.25) mini_portile (0.5.1) mono_logger (1.1.0) - multi_json (1.8.0) + multi_json (1.8.1) mysql2 (0.3.13) net-scp (1.1.2) net-ssh (>= 2.6.5) @@ -242,7 +242,7 @@ GEM ruby-prof (0.13.0) ruby-rc4 (0.1.5) rubyzip (0.9.9) - sass (3.2.11) + sass (3.2.12) sass-rails (3.2.6) railties (~> 3.2.0) sass (>= 3.1.10) @@ -297,7 +297,7 @@ GEM execjs rails (>= 3.1) railties (>= 3.1) - tzinfo (0.3.37) + tzinfo (0.3.38) uglifier (2.2.1) execjs (>= 0.3.0) multi_json (~> 1.0, >= 1.0.2) From d64590a534b15a2e44fe56795b2acd8972db6a3e Mon Sep 17 00:00:00 2001 From: wvengen Date: Thu, 10 Oct 2013 17:49:06 +0200 Subject: [PATCH 54/79] more robustness --- app/models/ordergroup.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/ordergroup.rb b/app/models/ordergroup.rb index 6e1b65dc..0188abcf 100644 --- a/app/models/ordergroup.rb +++ b/app/models/ordergroup.rb @@ -66,7 +66,7 @@ class Ordergroup < Group end def avg_jobs_per_euro - stats[:orders_sum] != 0 ? stats[:jobs_size].to_f / stats[:orders_sum].to_f : 0 + stats[:jobs_size].to_f / stats[:orders_sum].to_f rescue 0 end # This is the ordergroup job per euro performance @@ -90,7 +90,7 @@ class Ordergroup < Group # Global average def self.avg_jobs_per_euro stats = Ordergroup.pluck(:stats) - stats.sum {|s| s[:jobs_size].to_f } / stats.sum {|s| s[:orders_sum].to_f } + stats.sum {|s| s[:jobs_size].to_f } / stats.sum {|s| s[:orders_sum].to_f } rescue 0 end def account_updated From a339ae4c7c246d3a1c61dc7b94e79e7538810c60 Mon Sep 17 00:00:00 2001 From: wvengen Date: Thu, 10 Oct 2013 19:12:59 +0200 Subject: [PATCH 55/79] i18n simple_form move of remaining labels --- config/locales/de.yml | 139 ++++++++++++++++++++---------------------- config/locales/en.yml | 105 ++++++++++++++++--------------- 2 files changed, 118 insertions(+), 126 deletions(-) diff --git a/config/locales/de.yml b/config/locales/de.yml index 1891a6b3..c7748dca 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -38,17 +38,27 @@ de: article: article_category: Kategorie availability: Artikel ist verfügbar? + availability_short: verf. deposit: Pfand fc_price: Endpreis - fc_share: FC-Aufschlag + fc_price_short: + fc_share: FoodCoop-Aufschlag + fc_share_short: FC-Aufschlag gross_price: Bruttopreis + manufacturer: Produzent name: Name note: Notiz + order_number: Bestellnummer + origin: Herkunft price: Nettopreis supplier: Lieferantin tax: MwSt unit: Einheit unit_quantity: Gebindegröße + unit_quantity_short: GebGr + article_category: + description: Beschreibung + name: Name delivery: delivered_on: Lieferdatum note: Notiz @@ -56,6 +66,9 @@ de: financial_transaction: amount: Betrag note: Notiz + group_order_article: + ordergroup_id: Bestellgruppe + result: Menge invoice: amount: Betrag date: Rechnungsdatum @@ -67,10 +80,41 @@ de: order: Bestellung paid_on: Bezahlt am supplier: Lieferant + message: + body: Inhalt + group_id: Gruppe + private: Privat + recipient_tokens: Empfänger_innen + sent_to_all: An alle Mitglieder schicken + subject: Betreff + order: + ends: Endet am + note: Notiz + starts: Läuft vom + order_article: + units_to_order: Menge + update_current_price: Globalen Preis aktualisieren + order_comment: + text: Kommentiere diese Bestellung ... + ordergroup: + contact_address: Adresse + contact_person: Kontaktperson + contact_phone: Telefon + description: Beschreibung + ignore_apple_restriction: Bestellstop bei zu wenig Äpfeln ignorieren + name: Name + user_tokens: Mitglieder + page: + body: Inhalt + parent_id: Oberseite + title: Titel stock_article: price: Nettopreis quantity: Lagerbestand quantity_available: Verfügbarer Bestand + stock_taking: + date: Datum + note: Notiz supplier: address: Adresse contact_person: Ansprechparter_in @@ -87,6 +131,17 @@ de: phone: Telefon phone2: Telefon 2 url: Homepage + stock_article: + supplier: Lieferant + task: + description: Beschreibung + done: Erledigt? + due_date: Wann erledigen? + duration: Dauer + name: Name + required_users: Anzahl + user_list: Verantwortliche + workgroup: Arbeitsgruppe user: email: Email first_name: Vorname @@ -95,10 +150,21 @@ de: nick: Benutzername ordergroup: Bestellgruppe password: Passwort + password_confirmation: Passwort wiederholen phone: Telefon workgroup: one: Arbeitsgruppe other: Arbeitsgruppen + workgroup: + name: Name + description: Beschreibung + next_weekly_tasks_number: Für wieviel Wochen im Voraus sollen Aufgaben erstellt werden? + role_admin: Administration + role_article_meta: Artikeldatenbank + role_finance: Finanzen + role_orders: Bestellverwaltung + role_suppliers: Lieferanten + user_tokens: Mitglieder errors: format: ! '%{attribute} %{message}' general: Ein Problem ist aufgetreten. @@ -1607,60 +1673,6 @@ de: required_users: Wieviel Benutzerinnen werden insgesamt benötigt? tax: In Prozent, Standard sind 7,0 labels: - article: - article_category: Kategorie - manufacturer: Produzent - name: Name - note: Notiz - origin: Herkunft - unit: Einheit - article_category: - description: Beschreibung - name: Name - defaults: - amount: Betrag - date: Datum - deposit: Pfand - description: Beschreibung - email: E-Mail - note: Notiz - order_number: Bestellnummer - ordergroup: Bestellgruppe - password: Passwort - password_confirmation: Passwort wiederholen - phone: Telefon - price: Preis (netto) - tax: MwSt - title: Titel - unit_quantity: Gebindegröße - user_tokens: Mitglieder - group_order_article: - ordergroup_id: Bestellgruppe - result: Menge - message: - body: Inhalt - group_id: Gruppe - private: Privat - recipient_tokens: Empfänger_innen - sent_to_all: An alle Mitglieder schicken - subject: Betreff - order: - ends: Endet am - starts: Läuft vom - order_article: - units_to_order: Menge - update_current_price: Globalen Preis aktualisieren - order_comment: - text: Kommentiere diese Bestellung ... - ordergroup: - contact_address: Adresse - contact_person: Kontaktperson - contact_phone: Telefon - ignore_apple_restriction: Bestellstop bei zu wenig Äpfeln ignorieren - name: Name - page: - body: Inhalt - parent_id: Oberseite settings: messages: send_as_email: Bekomme Nachrichten als Emails. @@ -1676,23 +1688,6 @@ de: settings_group: messages: Nachrichten privacy: Privatsphäre - stock_article: - supplier: Lieferant - task: - done: Erledigt? - due_date: Wann erledigen? - duration: Dauer - name: Name - required_users: Anzahl - user_list: Verantwortliche - workgroup: Arbeitsgruppe - workgroup: - next_weekly_tasks_number: Für wieviel Wochen im Voraus sollen Aufgaben erstellt werden? - role_admin: Administration - role_article_meta: Artikeldatenbank - role_finance: Finanzen - role_orders: Bestellverwaltung - role_suppliers: Lieferanten 'no': Nein options: settings: diff --git a/config/locales/en.yml b/config/locales/en.yml index 228aacbe..04cc88cd 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -48,8 +48,9 @@ en: manufacturer: Manufacturer name: Name note: Note + order_number: Order number origin: Origin - price: Price + price: Price (net) supplier: Supplier tax: VAT unit: Unit @@ -60,10 +61,14 @@ en: name: Name delivery: delivered_on: Delivery date + note: Note supplier: Supplier financial_transaction: amount: amount note: note + group_order_article: + ordergroup_id: Ordergroup + result: Amount invoice: amount: Amount date: Billing date @@ -75,14 +80,45 @@ en: order: Order paid_on: Paid on supplier: Supplier + message: + body: Body + group_id: Group + private: Private + recipient_tokens: Recipients + sent_to_all: Send to all members + subject: Subject + order: + ends: Ends at + note: Note + starts: Starts at + order_article: + units_to_order: Amount of units + update_current_price: Globally update current price + order_comment: + text: Add comment to this order ... + ordergroup: + contact_address: Address + contact_person: Contact person + contact_phone: Phone + description: Description + ignore_apple_restriction: Ignore order stop by apple points restriction + name: Name + user_tokens: Members + page: + body: Body + parent_id: Parent page stock_article: price: Price quantity: Quantity quantity_available: Available quantity + stock_taking: + date: Date + note: Note supplier: address: Address contact_person: Contact person customer_number: Customer number + customer_number_short: Cust.nr. delivery_days: Delivery days email: Email fax: Fax @@ -94,7 +130,10 @@ en: phone: Phone phone2: Phone 2 url: Homepage + stock_article: + supplier: Supplier task: + description: Description done: Done? due_date: Due date duration: Duration @@ -110,10 +149,21 @@ en: nick: Username ordergroup: Ordergroup password: Password + password_confirmation: Repeat password phone: Telephone workgroup: one: Workgroup other: Workgroups + workgroup: + name: Name + description: Description + next_weekly_tasks_number: For how many weeks in advance would you like to define tasks? + role_admin: Administration + role_article_meta: Article database + role_finance: Finances + role_orders: Order management + role_suppliers: Suppliers + user_tokens: Members errors: format: ! '%{attribute} %{message}' general: A problem has occured. @@ -1624,50 +1674,6 @@ en: required_users: How many users will be needed in total? tax: In percentage, standard is 7,0 labels: - defaults: - amount: Amount - date: Date - deposit: Deposit - description: Description - email: Email - note: Note - order_number: Order number - ordergroup: Ordergroup - password: Password - password_confirmation: Repeat password - phone: Phone - price: Price (net) - tax: VAT - title: Title - unit_quantity: Unit quantity - user_tokens: Members - group_order_article: - ordergroup_id: Ordergroup - result: Amount - message: - body: Body - group_id: Group - private: Private - recipient_tokens: Recipients - sent_to_all: Send to all members - subject: Subject - order: - ends: Ends at - starts: Starts at - order_article: - units_to_order: Amount of units - update_current_price: Globally update current price - order_comment: - text: Add comment to this order ... - ordergroup: - contact_address: Address - contact_person: Contact person - contact_phone: Phone - ignore_apple_restriction: Ignore order stop by apple points restriction - name: Name - page: - body: Body - parent_id: Parent page settings: messages: send_as_email: Receive messages as emails. @@ -1683,15 +1689,6 @@ en: settings_group: messages: Messages privacy: Privacy - stock_article: - supplier: Supplier - workgroup: - next_weekly_tasks_number: For how many weeks in advance would you like to define tasks? - role_admin: Administration - role_article_meta: Article database - role_finance: Finances - role_orders: Order management - role_suppliers: Suppliers 'no': 'No' options: settings: From 23b38b5a46c629226ec1f6ccf5c6358c45a56d14 Mon Sep 17 00:00:00 2001 From: wvengen Date: Thu, 10 Oct 2013 19:22:43 +0200 Subject: [PATCH 56/79] fix category heading --- app/controllers/articles_controller.rb | 4 ++-- app/views/articles/_articles.html.haml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/articles_controller.rb b/app/controllers/articles_controller.rb index b29fd594..c9dd1362 100644 --- a/app/controllers/articles_controller.rb +++ b/app/controllers/articles_controller.rb @@ -7,12 +7,12 @@ class ArticlesController < ApplicationController sort = case params['sort'] when "name" then "articles.name" when "unit" then "articles.unit" - when "category" then "article_categories.name" + when "article_category" then "article_categories.name" when "note" then "articles.note" when "availability" then "articles.availability" when "name_reverse" then "articles.name DESC" when "unit_reverse" then "articles.unit DESC" - when "category_reverse" then "article_categories.name DESC" + when "article_category_reverse" then "article_categories.name DESC" when "note_reverse" then "articles.note DESC" when "availability_reverse" then "articles.availability DESC" end diff --git a/app/views/articles/_articles.html.haml b/app/views/articles/_articles.html.haml index e8a1c7b1..283abc53 100644 --- a/app/views/articles/_articles.html.haml +++ b/app/views/articles/_articles.html.haml @@ -8,7 +8,7 @@ %th %th= sort_link_helper heading_helper(Article, :name), "name" %th - %th= sort_link_helper heading_helper(Article, :category), "category" + %th= sort_link_helper heading_helper(Article, :article_category), "article_category" %th= sort_link_helper heading_helper(Article, :unit), "unit" %th= sort_link_helper heading_helper(Article, :note), "note" %th{:style => "width: 4em;"}= heading_helper Article, :unit_quantity, short: true From 389b45a50553bb9ced938f0073fd8862ea9f6484 Mon Sep 17 00:00:00 2001 From: wvengen Date: Thu, 10 Oct 2013 19:23:37 +0200 Subject: [PATCH 57/79] fix stockit i18n reference --- app/views/stockit/_form.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/stockit/_form.html.haml b/app/views/stockit/_form.html.haml index 8b96aea8..32e58623 100644 --- a/app/views/stockit/_form.html.haml +++ b/app/views/stockit/_form.html.haml @@ -11,7 +11,7 @@ %span.add-on % = f.input :deposit - else - = f.input :price, :input_html => {:disabled => 'disabled'}, :hint => t('.form.price_hint') + = f.input :price, :input_html => {:disabled => 'disabled'}, :hint => t('.price_hint') = f.association :article_category .form-actions = f.submit class: 'btn' From 092bc6b1502a094d68273ad1528e90f6a508ca55 Mon Sep 17 00:00:00 2001 From: wvengen Date: Thu, 17 Oct 2013 15:32:03 +0200 Subject: [PATCH 58/79] translation updates --- config/locales/fr.yml | 1 + config/locales/nl.yml | 71 ++++++++++++++++++++++++------------------- 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/config/locales/fr.yml b/config/locales/fr.yml index f9b71327..9fcefb99 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -507,6 +507,7 @@ fr: filename: Commande %{name}-%{date} - Répartition par cellules rows: - Nom de l'article + - Commandée - Quantité - Prix unitaire - Unités par lot diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 2bef7df0..501ee0f1 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -42,10 +42,10 @@ nl: fc_price: prijs foodcoop fc_share: marge foodcoop gross_price: bruto prijs - name: - note: + name: Naam + note: Notitie price: netto prijs - supplier: + supplier: Leverancier tax: BTW unit: eenheid unit_quantity: groothandelseenheid @@ -332,7 +332,7 @@ nl: one: Er moet éen artikel bijgewerkt worden. other: Er moeten %{count} artikelen bijgewerkt worden. upload: - body: + body:

Het bestand moet een utf-8 tekstbestand zijn met als extensie '.csv'. De eerste regel wordt overgeslagen.

Velden moeten met een puntkomma (';') gescheiden worden, en tekst mag tussen dubbele aanhalingstekstens ("Tekst...") staan.

Volgende van de kolommen:

fields: season_amount: season_price: @@ -503,6 +503,7 @@ nl: filename: Bestelling %{name}-%{date} - Huishoudenslijst rows: - Artikel + - Besteld - Hoeveelheid - Prijs - Gr.Eenh. @@ -871,7 +872,7 @@ nl: remaining: nog %{remaining} title: Lopende bestellingen update: - error_general: + error_general: Er is een probleem opgetreden, de bestelling kon niet bijgewerkt worden. error_stale: In de tussentijd heeft iemand anders ook bestelt, daarom kon je bestelling niet opgeslagen worden. Sorry! notice: De bestelling is opgeslagen. helpers: @@ -913,8 +914,8 @@ nl: index: due_date_format: ! '%A %d %B' messages: - title: - view_all: + title: Nieuwste berichten + view_all: Alle berichten bekijken my_ordergroup: funds: ! '| Beschikbaar tegoed:' last_update: Laatst gewijzigd %{when} geleden @@ -944,7 +945,7 @@ nl: description: Omschrijving funds: ! 'Beschikbaar krediet:' invite: Iemand uitnodigen - people: + people: Personen search: Zoeken ... title: Mijn huishouden ordergroup_cancelled: Je bent geen lid meer van de groep %{group}. @@ -982,19 +983,25 @@ nl: write_message: Bericht schrijven invites: errors: - already_member: + already_member: is al lid van de foodcoop. modal_form: - body: - title: + body:

Hier kun je iemand die nog geen lid is uitnodigen voor de groep%{group}.

Na aanmelding is hij of zij automatisch lid van deze groep.

+ title: Iemand uitnodigen new: - action: - body: - success: + action: Uitnodiging versturen + body:

Hier kun je iemand die nog geen lid is, uitnodigen voor de groep %{group}.

+ success: Persoon is uitgenodigd. layouts: application1: title: Foodsoft - %{title} email: - footer: + footer: ! '-- + + Foodsoft: %{foodsoft} + + Foodcoop-Homepage: %{foodcoop} + + Help: %{help}' foodsoft: Foodsoft header: feedback: @@ -1011,7 +1018,7 @@ nl: page: Pagina %{number} login: accept_invitation: - body: + body:

Je bent uitgenodigd als lid voor foodcoop %{foodcoop} in de groep %{group}.

Als je wilt meedoen, vul dan dit formulier in.

Natuurlijk zullen we je informatie niet delen met anderen. Je kunt zelf aangeven, welke informatie voor andere leden beschikbaar is (maar beheerders hebben daar altijd toegang toe).

submit: Foodsoft account aanmaken title: Uitnodiging voor %{name} controller: @@ -1033,9 +1040,9 @@ nl: submit: Nieuw wachtwoord opslaan title: Nieuw wachtwoord mailer: - dateformat: + dateformat: ! '%d %b' feedback: - header: + header: ! '%{user} schreef op %{date}:' subject: foodsoft_message: footer: @@ -1107,21 +1114,21 @@ nl: new: list: desc: - mail: + mail: bijvoorbeeld door een email te sturen naar %{email}. subscribe: subscribe_msg: wiki: no_user_found: Geen gebruiker gevonden search: Zoeken ... search_user: Gebruiker zoeken - title: + title: Nieuw bericht show: - all_messages: - from: - reply: - sent_on: - subject: - title: + all_messages: Berichtenoverzicht + from: ! 'Van:' + reply: Antwoorden + sent_on: ! 'Verzonden:' + subject: ! 'Onderwerp:' + title: Bericht lezen model: delivery: each_stock_article_must_be_unique: In een levering mag ieder voorraadsartikel maar een keer voorkomen. @@ -1262,9 +1269,9 @@ nl: title: Artikel unit_quantity: index: - action_end: - confirm_delete: - confirm_end: + action_end: Sluiten + confirm_delete: Wil je de bestelling werkelijk verwijderen? + confirm_end: Wil je de bestelling %{order} werkelijk sluiten? Dit kun je niet ongedaan maken. ended_orders: Gesloten bestellingen ending: new_order: @@ -1285,11 +1292,11 @@ nl: title: orders: ending: - start: + start: Start status: - supplier: + supplier: Leverancier show: - action_end: + action_end: Sluiten! amounts: articles: articles_ordered: From 4e61e764dfdcd252d48f9390f216afd94fc10c29 Mon Sep 17 00:00:00 2001 From: wvengen Date: Thu, 17 Oct 2013 16:35:50 +0200 Subject: [PATCH 59/79] fix haml indentation errors --- app/views/shared/_open_orders.html.haml | 2 +- app/views/suppliers/_form.haml | 4 ++-- app/views/suppliers/show.haml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/shared/_open_orders.html.haml b/app/views/shared/_open_orders.html.haml index ebda2730..63259520 100644 --- a/app/views/shared/_open_orders.html.haml +++ b/app/views/shared/_open_orders.html.haml @@ -2,7 +2,7 @@ %h2= t '.title' - if ordergroup.not_enough_apples? .alert - = t '.not_enough_apples' + = t '.not_enough_apples' - unless Order.open.empty? %table.table.table-striped %thead diff --git a/app/views/suppliers/_form.haml b/app/views/suppliers/_form.haml index 09047bc1..93de2a97 100644 --- a/app/views/suppliers/_form.haml +++ b/app/views/suppliers/_form.haml @@ -1,7 +1,7 @@ = simple_form_for @supplier do |f| - if @supplier.shared_supplier - .alert.alert-success - = t 'suppliers.shared_supplier_note' + .alert.alert-info + = t 'suppliers.shared_supplier_note' = f.hidden_field :shared_supplier_id = f.input :name = f.input :address diff --git a/app/views/suppliers/show.haml b/app/views/suppliers/show.haml index 0a9417fe..f07b09c9 100644 --- a/app/views/suppliers/show.haml +++ b/app/views/suppliers/show.haml @@ -4,7 +4,7 @@ .span6 - if shared_supplier = @supplier.shared_supplier .alert.alert-info - = t 'suppliers.shared_supplier_note' + = t 'suppliers.shared_supplier_note' %dl.dl-horizontal %dt= t('simple_form.labels.supplier.address') + ':' From 6e5184d79682052585fcfb7bd694cb108459c166 Mon Sep 17 00:00:00 2001 From: wvengen Date: Thu, 17 Oct 2013 16:20:51 +0200 Subject: [PATCH 60/79] use rails-i18n translations --- Gemfile | 1 + Gemfile.lock | 4 + config/application.rb | 3 +- config/locales/de.yml | 258 ---------------------------------- config/locales/en.yml | 258 ---------------------------------- config/locales/nl.yml | 259 ----------------------------------- config/locales/overrides.yml | 17 +++ 7 files changed, 24 insertions(+), 776 deletions(-) create mode 100644 config/locales/overrides.yml diff --git a/Gemfile b/Gemfile index 787ae113..9b116430 100644 --- a/Gemfile +++ b/Gemfile @@ -21,6 +21,7 @@ gem 'select2-rails' gem 'bootstrap-datepicker-rails' gem 'rails-assets-listjs', '0.2.0.beta.4' # remember to maintain list.*.js plugins and template engines on update gem 'i18n-js', git: 'git://github.com/fnando/i18n-js.git' # to avoid US-ASCII js.erb error +gem 'rails-i18n' gem 'mysql2' gem 'prawn' diff --git a/Gemfile.lock b/Gemfile.lock index 7ec1880f..8dddd96e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -201,6 +201,9 @@ GEM railties (= 3.2.13) rails-assets-listjs (0.2.0.beta.4) railties (>= 3.1) + rails-i18n (3.0.0) + i18n (~> 0.5) + rails (>= 3.0.0, < 4.0.0) rails-settings-cached (0.2.4) rails (>= 3.0.0) railties (3.2.13) @@ -343,6 +346,7 @@ DEPENDENCIES quiet_assets rails (~> 3.2.9) rails-assets-listjs (= 0.2.0.beta.4) + rails-i18n rails-settings-cached (= 0.2.4) resque rspec-core diff --git a/config/application.rb b/config/application.rb index 6d519277..ee7d7d71 100644 --- a/config/application.rb +++ b/config/application.rb @@ -30,7 +30,8 @@ module Foodsoft # config.time_zone = 'Central Time (US & Canada)' # Internationalization. - config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')] + config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '*.yml')] + config.i18n.available_locales = Pathname.glob(Rails.root.join('config', 'locales', '??{-*,}.yml')).map{|p| p.basename('.yml').to_s } config.i18n.default_locale = :en # Configure the default encoding used in templates for Ruby 1.9. diff --git a/config/locales/de.yml b/config/locales/de.yml index c7748dca..e1430099 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -1,38 +1,4 @@ de: - activemodel: - errors: - format: ! '%{attribute} %{message}' - general: Ein Problem ist aufgetreten. - general_again: Ein Fehler ist aufgetreten. Bitte erneut versuchen. - general_msg: ! 'Ein Fehler ist aufgetreten: %{msg}' - messages: - accepted: muss akzeptiert werden - blank: muss ausgefüllt werden - confirmation: stimmt nicht mit der Bestätigung überein - empty: muss ausgefüllt werden - equal_to: muss genau %{count} sein - even: muss gerade sein - exclusion: ist nicht verfügbar - greater_than: muss größer als %{count} sein - greater_than_or_equal_to: muss größer oder gleich %{count} sein - inclusion: ist kein gültiger Wert - invalid: ist nicht gültig - less_than: muss kleiner als %{count} sein - less_than_or_equal_to: muss kleiner oder gleich %{count} sein - not_a_number: ist keine Zahl - not_an_integer: muss ganzzahlig sein - odd: muss ungerade sein - record_invalid: ! 'Gültigkeitsprüfung ist fehlgeschlagen: %{errors}' - taken: ist bereits vergeben - taken_with_deleted: ist bereits vergeben (eine gelöschte Gruppe) - too_long: ist zu lang (nicht mehr als %{count} Zeichen) - too_short: ist zu kurz (nicht weniger als %{count} Zeichen) - wrong_length: hat die falsche Länge (muss genau %{count} Zeichen haben) - template: - body: ! 'Bitte überprüfen Sie die folgenden Felder:' - header: - one: ! 'Konnte %{model} nicht speichern: ein Fehler.' - other: ! 'Konnte %{model} nicht speichern: %{count} Fehler.' activerecord: attributes: article: @@ -166,44 +132,12 @@ de: role_suppliers: Lieferanten user_tokens: Mitglieder errors: - format: ! '%{attribute} %{message}' - general: Ein Problem ist aufgetreten. - general_again: Ein Fehler ist aufgetreten. Bitte erneut versuchen. - general_msg: ! 'Ein Fehler ist aufgetreten: %{msg}' has_many_left: ist noch mit einem/r %{collection} verknüpft! - messages: - accepted: muss akzeptiert werden - blank: muss ausgefüllt werden - confirmation: stimmt nicht mit der Bestätigung überein - empty: muss ausgefüllt werden - equal_to: muss genau %{count} sein - even: muss gerade sein - exclusion: ist nicht verfügbar - greater_than: muss größer als %{count} sein - greater_than_or_equal_to: muss größer oder gleich %{count} sein - inclusion: ist kein gültiger Wert - invalid: ist nicht gültig - less_than: muss kleiner als %{count} sein - less_than_or_equal_to: muss kleiner oder gleich %{count} sein - not_a_number: ist keine Zahl - not_an_integer: muss ganzzahlig sein - odd: muss ungerade sein - record_invalid: ! 'Gültigkeitsprüfung ist fehlgeschlagen: %{errors}' - taken: ist bereits vergeben - taken_with_deleted: ist bereits vergeben (eine gelöschte Gruppe) - too_long: ist zu lang (nicht mehr als %{count} Zeichen) - too_short: ist zu kurz (nicht weniger als %{count} Zeichen) - wrong_length: hat die falsche Länge (muss genau %{count} Zeichen haben) models: task: attributes: done: exclusion: erledigte Aufgaben können nicht wöchentlich wiederholt werden - template: - body: ! 'Bitte überprüfen Sie die folgenden Felder:' - header: - one: ! 'Konnte %{model} nicht speichern: ein Fehler.' - other: ! 'Konnte %{model} nicht speichern: %{count} Fehler.' models: article: Artikel article_category: Artikelkategorie @@ -445,102 +379,6 @@ de: file_label: Bitte wähle eine kompatible Datei aus submit: Datei hochladen title: ! '%{supplier} / Artikel hochladen' - date: - abbr_day_names: - - So - - Mo - - Di - - Mi - - Do - - Fr - - Sa - abbr_month_names: - - - - Jan - - Feb - - Mär - - Apr - - Mai - - Jun - - Jul - - Aug - - Sep - - Okt - - Nov - - Dez - day_names: - - Sonntag - - Montag - - Dienstag - - Mittwoch - - Donnerstag - - Freitag - - Samstag - formats: - default: ! '%d.%m.%Y' - long: ! '%e. %B %Y' - short: ! '%e. %b' - month_names: - - - - Januar - - Februar - - März - - April - - Mai - - Juni - - Juli - - August - - September - - Oktober - - November - - Dezember - order: - - :day - - :month - - :year - datetime: - distance_in_words: - about_x_hours: - one: etwa eine Stunde - other: etwa %{count} Stunden - about_x_months: - one: etwa ein Monat - other: etwa %{count} Monate - about_x_years: - one: etwa ein Jahr - other: etwa %{count} Jahre - almost_x_years: - one: fast ein Jahr - other: fast %{count} Jahre - half_a_minute: eine halbe Minute - less_than_x_minutes: - one: weniger als eine Minute - other: weniger als %{count} Minuten - less_than_x_seconds: - one: weniger als eine Sekunde - other: weniger als %{count} Sekunden - over_x_years: - one: mehr als ein Jahr - other: mehr als %{count} Jahre - x_days: - one: ein Tag - other: ! '%{count} Tage' - x_minutes: - one: eine Minute - other: ! '%{count} Minuten' - x_months: - one: ein Monat - other: ! '%{count} Monate' - x_seconds: - one: eine Sekunde - other: ! '%{count} Sekunden' - prompts: - day: Tag - hour: Stunden - minute: Minuten - month: Monat - second: Sekunden - year: Jahr deliveries: add_stock_change: how_many_units: Wie viele Einheiten (%{unit}) des Artikels »%{name}« liefern? @@ -640,38 +478,9 @@ de: title: ! 'Sortiermatrix der Bestellung: %{name}, beendet am %{date}' total: Insgesamt %{count} Artikel errors: - format: ! '%{attribute} %{message}' general: Ein Problem ist aufgetreten. general_again: Ein Fehler ist aufgetreten. Bitte erneut versuchen. general_msg: ! 'Ein Fehler ist aufgetreten: %{msg}' - messages: - accepted: muss akzeptiert werden - blank: muss ausgefüllt werden - confirmation: stimmt nicht mit der Bestätigung überein - empty: muss ausgefüllt werden - equal_to: muss genau %{count} sein - even: muss gerade sein - exclusion: ist nicht verfügbar - greater_than: muss größer als %{count} sein - greater_than_or_equal_to: muss größer oder gleich %{count} sein - inclusion: ist kein gültiger Wert - invalid: ist nicht gültig - less_than: muss kleiner als %{count} sein - less_than_or_equal_to: muss kleiner oder gleich %{count} sein - not_a_number: ist keine Zahl - not_an_integer: muss ganzzahlig sein - odd: muss ungerade sein - record_invalid: ! 'Gültigkeitsprüfung ist fehlgeschlagen: %{errors}' - taken: ist bereits vergeben - taken_with_deleted: ist bereits vergeben (eine gelöschte Gruppe) - too_long: ist zu lang (nicht mehr als %{count} Zeichen) - too_short: ist zu kurz (nicht weniger als %{count} Zeichen) - wrong_length: hat die falsche Länge (muss genau %{count} Zeichen haben) - template: - body: ! 'Bitte überprüfen Sie die folgenden Felder:' - header: - one: ! 'Konnte %{model} nicht speichern: ein Fehler.' - other: ! 'Konnte %{model} nicht speichern: %{count} Fehler.' feedback: create: notice: Das Feedback wurde erfolgreich verschickt. Vielen Dank! @@ -1000,15 +809,11 @@ de: option_choose: Lieferantin/Lager auswählen option_stock: Lager order_pdf: PDF erstellen - select: - prompt: Bitte wählen submit: - create: ! '%{model} speichern' invite: create: Einladung verschicken message: create: Nachricht verschicken - update: Änderungen speichern tasks: required_users: Es fehlen %{count} Mitstreiterinnen! home: @@ -1345,57 +1150,6 @@ de: home: Startseite title: Wiki workgroups: Arbeitsgruppen - number: - currency: - format: - delimiter: . - format: ! '%n %u' - precision: 2 - separator: ! ',' - significant: false - strip_insignificant_zeros: false - unit: € - format: - delimiter: . - precision: 2 - separator: ! ',' - significant: false - strip_insignificant_zeros: false - human: - decimal_units: - format: ! '%n %u' - units: - billion: - one: Milliarde - other: Milliarden - million: Millionen - quadrillion: - one: Billiarde - other: Billiarden - thousand: Tausend - trillion: Billionen - unit: - format: - delimiter: - precision: 1 - significant: true - strip_insignificant_zeros: true - storage_units: - format: ! '%n %u' - units: - byte: - one: Byte - other: Bytes - gb: GB - kb: KB - mb: MB - tb: TB - percentage: - format: - delimiter: - precision: - format: - delimiter: ordergroups: edit: title: Bestellgruppe bearbeiten @@ -1810,11 +1564,6 @@ de: show_deliveries: Zeige alle Lieferungen update: notice: Lieferant wurde aktualisiert - support: - array: - last_word_connector: ! ' und ' - two_words_connector: ! ' und ' - words_connector: ! ', ' tasks: accept: notice: Du hast die Aufgabe übernommen @@ -1889,13 +1638,6 @@ de: workgroup: title: Aufgaben für %{workgroup} title_all: Alle Aufgaben der Gruppe - time: - am: vormittags - formats: - default: ! '%A, %d. %B %Y, %H:%M Uhr' - long: ! '%A, %d. %B %Y, %H:%M Uhr' - short: ! '%d. %B, %H:%M Uhr' - pm: nachmittags ui: close: Schließen delete: Löschen diff --git a/config/locales/en.yml b/config/locales/en.yml index 04cc88cd..c8f64d60 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,38 +1,4 @@ en: - activemodel: - errors: - format: ! '%{attribute} %{message}' - general: A problem has occured. - general_again: A problem has occured. Please try again. - general_msg: ! 'A problem has occured: %{msg}' - messages: - accepted: has to be accepted - blank: has to be entered - confirmation: does not match the confirmation - empty: has to be entered - equal_to: has to be exactly %{count} - even: has to be an even number - exclusion: is not available - greater_than: has to be greater than %{count} - greater_than_or_equal_to: has to be greater than or equal to %{count} - inclusion: is not a valid value - invalid: is invalid - less_than: has to be less than %{count} - less_than_or_equal_to: has to be less than or equal to %{count} - not_a_number: is not a number - not_an_integer: must be a whole number - odd: must be odd - record_invalid: ! 'validation failed: %{errors}' - taken: is already taken - taken_with_deleted: is already taken (deleted group) - too_long: is too long (no more than %{count} characters) - too_short: is too short (use more than %{count} characters) - wrong_length: is the wrong length (has to have exactly %{count} characters) - template: - body: ! 'Please check the following fields:' - header: - one: ! 'Could not save %{model}: an error.' - other: ! 'Could not save %{model}: %{count} errors.' activerecord: attributes: article: @@ -165,44 +131,12 @@ en: role_suppliers: Suppliers user_tokens: Members errors: - format: ! '%{attribute} %{message}' - general: A problem has occured. - general_again: A problem has occured. Please try again. - general_msg: ! 'A problem has occured: %{msg}' has_many_left: is still associated with a %{collection}! - messages: - accepted: has to be accepted - blank: has to be filled - confirmation: does not match the confirmation - empty: has to be entered - equal_to: has to be exactly %{count} - even: has to be an even number - exclusion: is not available - greater_than: has to be greater than %{count} - greater_than_or_equal_to: has to be greater than or equal to %{count} - inclusion: is not a valid value - invalid: is invalid - less_than: has to be less than %{count} - less_than_or_equal_to: has to be less than or equal to %{count} - not_a_number: is not a number - not_an_integer: must be a whole number - odd: must be odd - record_invalid: ! 'validation failed: %{errors}' - taken: is already taken - taken_with_deleted: is already taken (deleted group) - too_long: is too long (no more than %{count} characters) - too_short: is too short (use more than %{count} characters) - wrong_length: is the wrong length (has to have exactly %{count} characters) models: task: attributes: done: exclusion: finished tasks may not be repeated weekly - template: - body: ! 'Please check the following fields:' - header: - one: ! 'Could not save %{model}: an error.' - other: ! 'Could not save %{model}: %{count} errors.' models: article: Article article_category: Article category @@ -446,102 +380,6 @@ en: file_label: Please choose a compatible file submit: Upload file title: ! '%{supplier} / upload articles' - date: - abbr_day_names: - - Su - - Mo - - Tu - - We - - Th - - Fr - - Sa - abbr_month_names: - - - - Jan - - Feb - - Mar - - Apr - - May - - Jun - - Jul - - Aug - - Sep - - Oct - - Nov - - Dec - day_names: - - Sunday - - Monday - - Tuesday - - Wednesday - - Thursday - - Friday - - Saturday - formats: - default: ! '%d/%m/%Y' - long: ! '%e %B %Y' - short: ! '%e %b' - month_names: - - - - January - - February - - March - - April - - May - - June - - July - - August - - September - - October - - November - - December - order: - - :day - - :month - - :year - datetime: - distance_in_words: - about_x_hours: - one: about one hour - other: about %{count} hours - about_x_months: - one: about one month - other: about %{count} months - about_x_years: - one: about one year - other: about %{count} years - almost_x_years: - one: almost one year - other: almost %{count} years - half_a_minute: half a minute - less_than_x_minutes: - one: less than one minute - other: less then %{count} minutes - less_than_x_seconds: - one: less than a second - other: less than %{count} seconds - over_x_years: - one: more then a year - other: more than %{count} year - x_days: - one: one day - other: ! '%{count} days' - x_minutes: - one: one minute - other: ! '%{count} minutes' - x_months: - one: one month - other: ! '%{count} months' - x_seconds: - one: eine Sekunde - other: ! '%{count} seconds' - prompts: - day: day - hour: hours - minute: minutes - month: months - second: seconds - year: years deliveries: add_stock_change: how_many_units: ! 'How many units (%{unit}) to deliver? Stock article name: %{name}.' @@ -643,38 +481,9 @@ en: one: One article in total other: ! '%{count} articles in total' errors: - format: ! '%{attribute} %{message}' general: A problem has occured. general_again: A problem has occured. Please try again. general_msg: ! 'A problem has occured: %{msg}' - messages: - accepted: has to be accepted - blank: has to be filled - confirmation: does not match the confirmation - empty: has to be entered - equal_to: has to be exactly %{count} - even: has to be an even number - exclusion: is not available - greater_than: has to be greater than %{count} - greater_than_or_equal_to: has to be greater than or equal to %{count} - inclusion: is not a valid value - invalid: is invalid - less_than: has to be less than %{count} - less_than_or_equal_to: has to be less than or equal to %{count} - not_a_number: is not a number - not_an_integer: must be a whole number - odd: must be odd - record_invalid: ! 'validation failed: %{errors}' - taken: is already taken - taken_with_deleted: is already taken (deleted group) - too_long: is too long (no more than %{count} characters) - too_short: is too short (use more than %{count} characters) - wrong_length: is the wrong length (has to have exactly %{count} characters) - template: - body: ! 'Please check the following fields:' - header: - one: ! 'Could not save %{model}: an error.' - other: ! 'Could not save %{model}: %{count} errors.' feedback: create: notice: Your feedback was sent successfully. Thanks a lot! @@ -1001,15 +810,11 @@ en: option_choose: Choose supplier/stock option_stock: Stock order_pdf: Create PDF - select: - prompt: please select submit: - create: save %{model} invite: create: send invitation message: create: send message - update: save changes tasks: required_users: ! '%{count} members are still needed!' home: @@ -1346,57 +1151,6 @@ en: home: Home title: Wiki workgroups: Workgroups - number: - currency: - format: - delimiter: . - format: ! '%n %u' - precision: 2 - separator: . - significant: false - strip_insignificant_zeros: false - unit: € - format: - delimiter: . - precision: 2 - separator: ! ',' - significant: false - strip_insignificant_zeros: false - human: - decimal_units: - format: ! '%n %u' - units: - billion: - one: billion - other: billions - million: million - quadrillion: - one: quadrillion - other: quadrillions - thousand: thousand - trillion: trillion - unit: - format: - delimiter: - precision: 1 - significant: true - strip_insignificant_zeros: true - storage_units: - format: ! '%n %u' - units: - byte: - one: byte - other: bytes - gb: GB - kb: KB - mb: MB - tb: TB - percentage: - format: - delimiter: - precision: - format: - delimiter: ordergroups: edit: title: Edit ordergroups @@ -1811,11 +1565,6 @@ en: show_deliveries: Show all deliveries update: notice: Supplier was updated - support: - array: - last_word_connector: ! ' and ' - two_words_connector: ! ' and ' - words_connector: ! ', ' tasks: accept: notice: You have accepted the task @@ -1889,13 +1638,6 @@ en: workgroup: title: Tasks for %{workgroup} title_all: All group tasks - time: - am: morning - formats: - default: ! '%A, %d %B %Y, %H:%M' - long: ! '%A, %d %B %Y, %H:%M' - short: ! '%d %B, %H:%M' - pm: afternoon ui: close: Close delete: Delete diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 53454284..de5980bd 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -1,38 +1,4 @@ nl: - activemodel: - errors: - format: ! '%{attribute} %{message}' - general: Er is een probleem opgetreden. - general_again: Een probleem is opgetreden. Graag opnieuw proberen. - general_msg: ! 'Een probleem is opgetreden: %{msg}' - messages: - accepted: moet geaccepteerd worden - blank: moet ingevuld worden - confirmation: komt niet overeen - empty: moet ingevuld worden - equal_to: moet precies %{count} zijn - even: moet even zijn - exclusion: is niet beschikbaar - greater_than: moet groter zijn dan %{count} - greater_than_or_equal_to: moet groter dan of gelijk aan %{count} zijn - inclusion: is geen geldige waarde - invalid: is ongeldig - less_than: moet minder zijn dan %{count} - less_than_or_equal_to: moet minder dan of gelijk aan %{count} zijn - not_a_number: is geen getal - not_an_integer: moet een geheel getal zijn - odd: moet oneven zijn - record_invalid: ! 'geldigheidscontrole is mislukt: %{errors}' - taken: bestaat al - taken_with_deleted: bestaat al (verwijderde groep) - too_long: is te lang (niet meer dan %{count} tekens) - too_short: is te kort (niet minder dan %{count} tekens) - wrong_length: heeft de verkeerde lengte (moet precies %{count} tekens hebben) - template: - body: ! 'Controleer de volgende velden:' - header: - one: ! 'Kon %{model} niet opslaan: één fout.' - other: ! 'Kon %{model} niet opslaan: %{count} fouten.' activerecord: attributes: article: @@ -60,34 +26,7 @@ nl: first_name: Voornaam password: Wachtwoord errors: - format: ! '%{attribute} %{message}' - general: Er is een probleem opgetreden. - general_again: Er is een probleem opgetreden. Probeer het opnieuw. - general_msg: ! 'Er is een probleem opgetreden: %{msg}' has_many_left: is nog met een %{collection} verbonden! - messages: - accepted: moet geaccepteerd worden - blank: moet ingevuld worden - confirmation: komt niet overeen - empty: moet ingevuld worden - equal_to: moet precies %{count} zijn - even: moet even zijn - exclusion: is niet beschikbaar - greater_than: moet groter dan %{count} zijn - greater_than_or_equal_to: moet groter zijn dan of gelijk aan %{count} - inclusion: is geen geldige waarde - invalid: is ongeldig - less_than: moet kleiner izjn dan %{count} - less_than_or_equal_to: moet kleiner zijn dan of gelijk aan %{count} - not_a_number: is geen getal - not_an_integer: moet een geheel getal zijn - odd: moet oneven zijn - record_invalid: ! 'geldigheidscontrole is mislukt: %{errors}' - taken: bestaat al - taken_with_deleted: bestaat al (verwijderde groep) - too_long: is te lang (niet meer dan %{count} tekens) - too_short: is te kort (niet minder dan %{count} tekens) - wrong_length: heeft de verkeerde lengte (moet precies %{count} tekens zijn) models: task: attributes: @@ -340,102 +279,6 @@ nl: file_label: Graag een compatibel bestand uitkiezen submit: Bestand uploaden title: Artikelen uploaden voor %{supplier} - date: - abbr_day_names: - - Zo - - Ma - - Di - - Wo - - Do - - Vr - - Za - abbr_month_names: - - - - Jan - - Feb - - Mar - - Apr - - Mei - - Jun - - Jul - - Aug - - Sep - - Okt - - Nov - - Dec - day_names: - - Zondag - - Maandag - - Dinsdag - - Woensdag - - Donderdag - - Vrijdag - - Zaterdag - formats: - default: ! '%d-%m-%Y' - long: ! '%e %B %Y' - short: ! '%e %b' - month_names: - - - - Januari - - Februari - - Maart - - April - - Mei - - Juni - - Juli - - Augustus - - September - - Oktober - - November - - December - order: - - :day - - :month - - :year - datetime: - distance_in_words: - about_x_hours: - one: ca. één uur - other: ca. %{count} uur - about_x_months: - one: ca. één maand - other: ca. %{count} maanden - about_x_years: - one: ca. één jaar - other: ca. %{count} jaar - almost_x_years: - one: bijna één jaar - other: bijna %{count} jaar - half_a_minute: een halve minuut - less_than_x_minutes: - one: minder dan één minuut - other: minder dan %{count} minuten - less_than_x_seconds: - one: minder dan een seconde - other: minder dan %{count} seconden - over_x_years: - one: meer dan één jaar - other: meer dan %{count} jaar - x_days: - one: één dag - other: ! '%{count} dagen' - x_minutes: - one: één minuut - other: ! '%{count} minuten' - x_months: - one: één maand - other: ! '%{count} maanden' - x_seconds: - one: een seconde - other: ! '%{count} seconden' - prompts: - day: dag - hour: uren - minute: minuten - month: maanden - second: seconden - year: jaren deliveries: add_stock_change: how_many_units: @@ -528,44 +371,9 @@ nl: one: In totaal éen artikel other: In totaal %{count} artikelen errors: - format: ! '%{attribute} %{message}' general: Er is een probleem opgetreden. general_again: Er is een fout opgetreden. Probeer het opnieuw. general_msg: ! 'Er is een probleem opgetreden: %{msg}' - messages: - accepted: moet geaccepteerd worden - blank: moet ingevuld worden - confirmation: komt niet overeen met de bevestiging - empty: moet ingevuld worden - equal_to: moet precies %{count} zijn - even: moet even zijn - exclusion: moet even zijn - greater_than: moet groter dan %{count} zijn - greater_than_or_equal_to: moet groter dan of gelijk zijn aan %{count} - inclusion: geen geldige waarde - invalid: is ongeldig - less_than: moet kleiner dan %{count} zijn - less_than_or_equal_to: moet groter of gelijk aan %{count} zijn - not_a_number: is geen getal - not_an_integer: moet een geheel getal zijn - odd: moet oneven zijn - record_invalid: - taken: is al in gebruik - taken_with_deleted: is al in gebruik (verwijderde groep) - too_long: - one: is te lang (niet meer dan éen teken) - other: is te lang (niet meer dan %{count} tekens) - too_short: - one: is te kort (niet minder dan éen teken) - other: is te kort (niet minder dan %{count} tekens) - wrong_length: - one: heeft de verkeerde lengte (moet precies éen zijn) - other: heeft de verkeerde lengte (moet precies %{count} tekens hebben) - template: - body: ! 'Controleer alsjeblieft de volgende velden:' - header: - one: ! 'Kon %{model} niet opslaan: éen fout gevonden.' - other: ! 'Kon %{model} niet opslaan: %{count} fouten gevonden.' feedback: create: notice: Bericht verstuurd. Vriendelijk bedankt! @@ -892,15 +700,11 @@ nl: option_choose: Leverancier/voorraad kiezen option_stock: Voorraad order_pdf: PDF maken - select: - prompt: graag uitkiezen submit: - create: ! '%{model} opslaan' invite: create: uitnodiging versturen message: create: bericht versturen - update: wijzigingen opslaan tasks: required_users: Nog %{count} leden nodig! home: @@ -1167,57 +971,6 @@ nl: home: Begin title: Wiki workgroups: Werkgroepen - number: - currency: - format: - delimiter: ! ' ' - format: ! '%n %u' - precision: 2 - separator: ! ',' - significant: false - strip_insignificant_zeros: false - unit: € - format: - delimiter: ! ',' - precision: 2 - separator: ! ' ' - significant: false - strip_insignificant_zeros: false - human: - decimal_units: - format: ! '%n %u' - units: - billion: - one: miljard - other: miljard - million: miljoen - quadrillion: - one: biljard - other: biljard - thousand: duizend - trillion: triljoen - unit: - format: - delimiter: - precision: 1 - significant: true - strip_insignificant_zeros: true - storage_units: - format: ! '%n %u' - units: - byte: - one: byte - other: bytes - gb: GB - kb: KB - mb: MB - tb: TB - percentage: - format: - delimiter: - precision: - format: - delimiter: ordergroups: edit: title: Huidhouden bewerken @@ -1740,11 +1493,6 @@ nl: show_deliveries: update: notice: Leverancier is bijgewerkt - support: - array: - last_word_connector: - two_words_connector: - words_connector: tasks: accept: notice: Je hebt de taak geaccepteerd @@ -1818,13 +1566,6 @@ nl: workgroup: title: title_all: - time: - am: morgen - formats: - default: ! '%A, %d %B %Y, %H:%M' - long: ! '%A, %d %B %Y, %H:%M' - short: ! '%d %B, %H:%M' - pm: middag ui: close: Sluiten delete: Verwijder diff --git a/config/locales/overrides.yml b/config/locales/overrides.yml new file mode 100644 index 00000000..e3442417 --- /dev/null +++ b/config/locales/overrides.yml @@ -0,0 +1,17 @@ +# This file contains overrides that do not go through localeapp. +# If there's a key in one language, it forces presence in other languages +# which means that we can't override in specific languages only. This file +# makes that possible. +en: + number: + currency: + format: + unit: ! '€ ' +nl: + number: + currency: + format: + delimiter: ! ' ' + unit: ! '€ ' + format: + delimiter: ! ' ' From e1eb6031c83f9d5a64bc5693972556bc71f73fc2 Mon Sep 17 00:00:00 2001 From: wvengen Date: Thu, 17 Oct 2013 16:48:34 +0200 Subject: [PATCH 61/79] load fr translation for datepicker --- app/assets/javascripts/application.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index b8dc87e8..b8902ac3 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -7,6 +7,7 @@ //= require bootstrap-datepicker/core //= require bootstrap-datepicker/locales/bootstrap-datepicker.de //= require bootstrap-datepicker/locales/bootstrap-datepicker.nl +//= require bootstrap-datepicker/locales/bootstrap-datepicker.fr //= require jquery.observe_field //= require list //= require list.unlist From bfcf35cd34b9fe4145e0a4510f3916942ad23e40 Mon Sep 17 00:00:00 2001 From: wvengen Date: Thu, 17 Oct 2013 17:10:33 +0200 Subject: [PATCH 62/79] fix i18n spec after changes --- spec/i18n_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/i18n_spec.rb b/spec/i18n_spec.rb index e07d74b9..b760d124 100644 --- a/spec/i18n_spec.rb +++ b/spec/i18n_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' require 'i18n-spec' -Dir.glob('config/locales/*.yml').each do |locale_file| +Dir.glob('config/locales/??{-*,}.yml').each do |locale_file| describe "#{locale_file}" do it_behaves_like 'a valid locale file', locale_file # We're currently allowing both German and English as source language From bf0dc4af09190ef527e3e2bf382cf4b11483c569 Mon Sep 17 00:00:00 2001 From: wvengen Date: Fri, 18 Oct 2013 00:21:45 +0200 Subject: [PATCH 63/79] remove disfunctional dispatch cgis --- public/dispatch.cgi | 10 ---------- public/dispatch.fcgi | 26 -------------------------- public/dispatch.rb | 10 ---------- 3 files changed, 46 deletions(-) delete mode 100755 public/dispatch.cgi delete mode 100755 public/dispatch.fcgi delete mode 100755 public/dispatch.rb diff --git a/public/dispatch.cgi b/public/dispatch.cgi deleted file mode 100755 index 3848806d..00000000 --- a/public/dispatch.cgi +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/ruby1.8 - -require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT) - -# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like: -# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired -require "dispatcher" - -ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun) -Dispatcher.dispatch \ No newline at end of file diff --git a/public/dispatch.fcgi b/public/dispatch.fcgi deleted file mode 100755 index 91c4ed57..00000000 --- a/public/dispatch.fcgi +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/ruby1.8 -# -# You may specify the path to the FastCGI crash log (a log of unhandled -# exceptions which forced the FastCGI instance to exit, great for debugging) -# and the number of requests to process before running garbage collection. -# -# By default, the FastCGI crash log is RAILS_ROOT/log/fastcgi.crash.log -# and the GC period is nil (turned off). A reasonable number of requests -# could range from 10-100 depending on the memory footprint of your app. -# -# Example: -# # Default log path, normal GC behavior. -# RailsFCGIHandler.process! -# -# # Default log path, 50 requests between GC. -# RailsFCGIHandler.process! nil, 50 -# -# # Custom log path, normal GC behavior. -# RailsFCGIHandler.process! '/var/log/myapp_fcgi_crash.log' -# -RAILS_ENV = "production" - -require File.dirname(__FILE__) + "/../config/environment" -require 'fcgi_handler' - -RailsFCGIHandler.process! diff --git a/public/dispatch.rb b/public/dispatch.rb deleted file mode 100755 index 3848806d..00000000 --- a/public/dispatch.rb +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/ruby1.8 - -require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT) - -# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like: -# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired -require "dispatcher" - -ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun) -Dispatcher.dispatch \ No newline at end of file From d1f9b0b0907b65a8894f78072ba7a184de4a4efa Mon Sep 17 00:00:00 2001 From: wvengen Date: Mon, 21 Oct 2013 17:55:58 +0200 Subject: [PATCH 64/79] apply changes to other translations + translation fixes --- config/locales/de.yml | 4 +- config/locales/en.yml | 5 +- config/locales/fr.yml | 486 ++++++++++-------------------------------- config/locales/nl.yml | 241 ++++++++++----------- 4 files changed, 224 insertions(+), 512 deletions(-) diff --git a/config/locales/de.yml b/config/locales/de.yml index e1430099..7d3a33e6 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -78,6 +78,7 @@ de: price: Nettopreis quantity: Lagerbestand quantity_available: Verfügbarer Bestand + supplier: Lieferant stock_taking: date: Datum note: Notiz @@ -97,8 +98,6 @@ de: phone: Telefon phone2: Telefon 2 url: Homepage - stock_article: - supplier: Lieferant task: description: Beschreibung done: Erledigt? @@ -1621,7 +1620,6 @@ de: confirm_delete_single: Die Aufgabe wirklich löschen? confirm_delete_group: Diese und alle folgenden wöchentlichen Aufgaben wirklich löschen? delete_group: Aufgabe und folgende löschen - due_date: Fälligkeitsdatum hours: ! '%{count}h' mark_done: Als erledigt markieren reject_task: Aufgabe ablehnen diff --git a/config/locales/en.yml b/config/locales/en.yml index c8f64d60..b162d0fe 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -73,10 +73,12 @@ en: page: body: Body parent_id: Parent page + title: Title stock_article: price: Price quantity: Quantity quantity_available: Available quantity + supplier: Supplier stock_taking: date: Date note: Note @@ -96,8 +98,6 @@ en: phone: Phone phone2: Phone 2 url: Homepage - stock_article: - supplier: Supplier task: description: Description done: Done? @@ -610,6 +610,7 @@ en: group_order_articles: form: amount_change_for: Change amount for %{article} + result_hint: 'Unit: %{unit}' index: amount: Amount amount_fc: Amount(FC) diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 5bb71604..463ecafc 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -1,103 +1,132 @@ fr: - activemodel: - errors: - format: ! '%{attribute} %{message}' - general: Un problème a été rencontré. - general_again: Une erreur s'est produite. Merci de réessayer. - general_msg: ! 'Une erreur s''est produite: %{msg}' - messages: - accepted: doit obligatoirement être accepté - blank: doit obligatoirement être complété - confirmation: ne correspond pas avec le champ de confirmation - empty: doit obligatoirement être complété - equal_to: doit obligatoirement être égal à %{count} - even: doit obligatoirement être pair - exclusion: n'est pas disponible - greater_than: doit obligatoirement être supérieur à %{count} - greater_than_or_equal_to: doit obligatoirement être supérieur ou égal à %{count} - inclusion: n'est pas une valeur valide - invalid: n'est pas valide - less_than: doit obligatoirement être inférieur à %{count} - less_than_or_equal_to: doit obligatoirement être inférieur à %{count} - not_a_number: n'est pas un nombre - not_an_integer: doit être un nombre entier - odd: doit obligatoirement être impair - record_invalid: ! 'la vérification a échoué: %{errors}' - taken: a déjà été attribué - taken_with_deleted: a déjà été attribué (à une cellule supprimée depuis) - too_long: est trop long (%{count} signes autorisés au maximum) - too_short: est trop court (%{count} signes au minimum doivent être présents) - wrong_length: n'est pas de la bonne longueur (exactement %{count} signes doivent être présents) - template: - body: ! 'Merci de contrôler le contenu des champs suivants:' - header: - one: ! '%{model} n''a pas pu être sauvegardé à cause de la présence d''une erreur.' - other: ! '%{model} n''a pas pu être sauvegardé car %{count} erreurs ont été trouvées.' activerecord: attributes: article: - article_category: catégorie + article_category: Catégorie availability: l'article est-il disponible? - deposit: consigne - fc_price: prix final - fc_share: supplément boufcoop - gross_price: prix brut - name: - note: - price: prix net + deposit: Consigne + fc_price: Prix final + fc_share: Supplément boufcoop + gross_price: Prix brut + manufacturer: ProductRICE_eur + name: Nom + note: Note + order_number: ! 'Numéro ' + origin: Lieu de production + price: Prix net supplier: tax: TVA - unit: unité - unit_quantity: unités par lot + unit: Unité + unit_quantity: Unités par lot + article_category: + description: Description + name: Nom + delivery: + delivered_on: Date de réapprovisionnement + supplier: Fournisseuse_r financial_transaction: amount: montant note: note + group_order_article: + ordergroup_id: Cellul + result: Quantité + invoice: + amount: Montant + date: Date de facturation + delivery: Réapprovisionnement + deposit: Consigne facturée + deposit_credit: Consigne remboursée + note: Note + number: Numéro + order: Commande + paid_on: Payée le + supplier: Fournisseuse_r + message: + body: Contenu + group_id: Cellule ou équipe + private: Privé + recipient_tokens: Destinataires + sent_to_all: Envoyer à tous les membres + subject: Sujet + order: + ends: Clôture le + starts: Ouverture le + order_article: + units_to_order: Quantité + update_current_price: Mettre à jour le prix global + order_comment: + text: Commenter cette commande... + ordergroup: + contact_address: Adresse + contact_person: Personne à contacter + contact_phone: Téléphone + description: Description + ignore_apple_restriction: Pour cette cellule, ne pas bloquer les commandes en cas de manque de glands + name: Nom + user_tokens: Membres + page: + body: Contenu + parent_id: Page parente + title: Titre stock_article: price: Prix net quantity: quantity_available: + supplier: FournisseurE + supplier: + address: Adresse + contact_person: Contact + customer_number: Numéro de client de la coop + delivery_days: Jours de livraison + email: Email + fax: Fa + is_subscribed: abonné? + min_order_quantity: Quantité minimale à commander + name: Nom + note: Note + order_howto: Comment commander + phone: Téléphone + phone2: Autre téléphone + url: Site web + task: + description: Description + done: Fait? + due_date: Echéance + duration: Durée + name: Nom + required_users: Nombre de personnes nécessaires + user_list: Responsables inscritEs + workgroup: Équipe user: + email: Email first_name: Prénom + last_name: Nom de famille + name: Nom + nick: Identifiant + ordergroup: Cellule password: Mot de passe + password_confirmation: Confirmation du mot de passe + phone: Téléphone + workgroup: + one: Équipe + other: Équipes + workgroup: + name: Nom + description: Description + next_weekly_tasks_number: Combien de temps en avance les boulots doivent ils être annoncés sur le site? + role_admin: Administration + role_article_meta: Base de données des articles + role_finance: Trésorerie + role_orders: Gestion des commandes + role_suppliers: Contact avec les fournisseusEs_rs + user_tokens: Membres errors: - format: ! '%{attribute} %{message}' - general: Une problème a été rencontré. - general_again: Une erreur s'est produite. Merci de réessayer. - general_msg: ! 'Un problème a été rencontré: %{msg}' has_many_left: est encore associé à une %{collection}! - messages: - accepted: doit obligatoirement être accepté - blank: doit obligatoirement être complété - confirmation: ne correspond pas au champ de confirmation - empty: doit obligatoirement être complété - equal_to: doit obligatoirement être égal à %{count} - even: doit être un nombre pair - exclusion: n'est pas disponible - greater_than: doit obligatoirement être supérieur à %{count} - greater_than_or_equal_to: doit obligatoirement être supérieur ou égal à %{count} - inclusion: n'est pas un valeur valide - invalid: est invalide - less_than: doit obligatoirement être inférieur à %{count} - less_than_or_equal_to: doit obligatoirement être inférieur ou égal à %{count} - not_a_number: n'est pas un nombre - not_an_integer: doit obligatoirement être un nombre entier - odd: doit obligaroirement être un nombre impair - record_invalid: ! 'la vérification a échoué: %{errors}' - taken: a déjà été attribué - taken_with_deleted: a déjà été attribué (à une cellule supprimée depuis) - too_long: est trop long (au maximum %{count} signes sont autorisés) - too_short: est trop court (au minimum %{count} signes doivent être présents) - wrong_length: n'a pas la bonne longueur (exactement %{count} signes doivent être présents) models: task: attributes: done: exclusion: répétition hebdomadaire invalide pour un boulot déjà effectué - template: - body: ! 'Merci de vérifier le contenu des champs suivants:' - header: - one: ! '%{model} n''a pu être sauvegardé à cause de la présence d''une erreur.' - other: ! '%{model} n''a pu être sauvegardé à cause de %{count} erreurs.' models: article: Article article_category: la nouvelle catégorie @@ -344,102 +373,6 @@ fr: file_label: Merci de choisir un fichier compatible submit: Transférer le fichier title: ! '%{supplier} / Transférer les données sur l''article' - date: - abbr_day_names: - - Lun - - Mar - - Mer - - Jeu - - Ven - - Sam - - Dim - abbr_month_names: - - - - Janvier - - Février - - Mars - - Avril - - Mai - - Juin - - Juillet - - Août - - Septembre - - Octobre - - Novembre - - Décembre - day_names: - - Dimanche - - Lundi - - Mardi - - Mercredi - - Jeudi - - Vendredi - - Samedi - formats: - default: ! '%d.%m.%Y' - long: ! '%e.%B %Y' - short: ! '%e. %b' - month_names: - - - - Janvier - - Février - - Mars - - Avril - - Mai - - Juin - - Juillet - - Août - - Septembre - - Octobre - - Novembre - - Décembre - order: - - :day - - :month - - :year - datetime: - distance_in_words: - about_x_hours: - one: environ une heure - other: environ %{count} heures - about_x_months: - one: environ un mois - other: environ %{count} mois - about_x_years: - one: environ un an - other: environ %{count} ans - almost_x_years: - one: presque un an - other: presque %{count} ans - half_a_minute: une demi-minute - less_than_x_minutes: - one: moins d'une minute - other: moins de %{count} minutes - less_than_x_seconds: - one: moins d'une seconde - other: moins de %{count} secondes - over_x_years: - one: plus d'un an - other: plus de %{count} ans - x_days: - one: un jour - other: ! '%{count} jours' - x_minutes: - one: une minute - other: ! '%{count} minutes' - x_months: - one: un mois - other: ! '%{count} mois' - x_seconds: - one: une seconde - other: ! '%{count} secondes' - prompts: - day: jour - hour: heures - minute: minute - month: mois - second: secondes - year: an deliveries: add_stock_change: how_many_units: Combien d unités (%{unit}) de l article %{name} doivent-elles être livrées? @@ -500,6 +433,7 @@ fr: filename: Commande %{name}-%{date} - Trier par rows: - Cellule + - - Quantité - Prix title: ! 'Ordre des articles pour la commande: %{name}, close le %{date}' @@ -523,6 +457,7 @@ fr: - Nom - Nombre de lots - Unité + - Prix/Unité - Prix unitaire total: order_matrix: @@ -539,38 +474,9 @@ fr: one: Un seul article other: ! '%{count} articles au total' errors: - format: ! '%{attribute} %{message}' general: Un problème a été rencontré. general_again: Une erreur s'est produite. Merci de réessayer. general_msg: ! 'Une erreur s''est produite: %{msg}' - messages: - accepted: doit obligatoirement être accepté - blank: doit obligatoirement être complété - confirmation: ! ' ne correspond pas au champ de confirmatio' - empty: doit obligatoirement être complété - equal_to: doit obligatoirement être égal à %{count} - even: doit obligatoirement être un nombre pair - exclusion: n'est pas disponible - greater_than: doit obligatoirement être supérieur à %{count} - greater_than_or_equal_to: doit obligatoirement être supérieur ou égal à %{count} - inclusion: n'est pas une valeur valide - invalid: n'est pas valide - less_than: doit obligatoirement être inférieur à %{count} - less_than_or_equal_to: doit obligatoirement être inférieur ou égal à %{count} - not_a_number: n'est pas un nombre - not_an_integer: doit obligatoirement être un nombre entier - odd: doit obligatoirement être un nombre impair - record_invalid: ! 'La vérification a échoué: %{errors}' - taken: a déjà été attribué - taken_with_deleted: a déjà été attribué (à une cellule supprimée depuis) - too_long: est trop long (au maximum %{count} signes sont autorisés) - too_short: est trop court (au minimum %{count} signes doivent être présents) - wrong_length: n'a pas la bonne longueur (exactement %{count} signes doivent être présents) - template: - body: ! 'Merci de contrôler le contenu des champs suivants:' - header: - one: ! '%{model} n''a pas pu être sauvegardé: une erreur trouvée.' - other: ! '%{model} n''a pas pu être sauvegardé: %{count} erreurs trouvées.' feedback: create: notice: Ton commentaire a été transmis avec succès. Merci @@ -909,15 +815,11 @@ fr: option_choose: Choix d'unE fournisseusE_r option_stock: Stock order_pdf: Générer un PDF - select: - prompt: Faire un choix submit: - create: Définir %{model} invite: create: Envoyer une invitatio message: create: Envoyer un message - update: Sauvergarder les modifications tasks: required_users: Il manque encore %{count} camarades! home: @@ -1240,57 +1142,6 @@ fr: home: Page d'accueil title: Wiki workgroups: Équipes - number: - currency: - format: - delimiter: . - format: ! '%n %u' - precision: 2 - separator: ! ',' - significant: false - strip_insignificant_zeros: false - unit: € - format: - delimiter: . - precision: 2 - separator: ! ',' - significant: false - strip_insignificant_zeros: false - human: - decimal_units: - format: ! '%n %u' - units: - billion: - one: milliard - other: milliards - million: millions - quadrillion: - one: billiard - other: billiards - thousand: mille - trillion: billions - unit: - format: - delimiter: - precision: 1 - significant: true - strip_insignificant_zeros: true - storage_units: - format: ! '%n %u' - units: - byte: - one: Octet - other: Octets - gb: Go - kb: kB - mb: MB - tb: TB - percentage: - format: - delimiter: - precision: - format: - delimiter: ordergroups: edit: title: Modifier les cellules @@ -1566,74 +1417,6 @@ fr: required_users: De combien de personnes avons-nous besoin au total? tax: En pourcentage, le standard est de 7,0 labels: - article: - article_category: Catégorie - manufacturer: ProductRICE_eur - name: Nom - note: Note - origin: Lieu de production - unit: Unité - article_category: - description: Description - name: Nom - defaults: - amount: Montant - date: Date - deposit: Consigne - description: Description - email: Email - note: Note - order_number: ! 'Numéro ' - ordergroup: Cellule - password: Mot de passe - password_confirmation: Confirmation du mot de passe - phone: Téléphone - price: Prix (net) - tax: TVA - title: Titre - unit_quantity: Unités par lot - user_tokens: Membres - delivery: - delivered_on: Date de réapprovisionnement - supplier: Fournisseuse_r - group_order_article: - ordergroup_id: Cellul - result: Quantité - invoice: - amount: Montant - date: Date de facturation - delivery: Réapprovisionnement - deposit: Consigne facturée - deposit_credit: Consigne remboursée - note: Note - number: Numéro - order: Commande - paid_on: Payée le - supplier: Fournisseuse_r - message: - body: Contenu - group_id: Cellule ou équipe - private: Privé - recipient_tokens: Destinataires - sent_to_all: Envoyer à tous les membres - subject: Sujet - order: - ends: Clôture le - starts: Ouverture le - order_article: - units_to_order: Quantité - update_current_price: Mettre à jour le prix global - order_comment: - text: Commenter cette commande... - ordergroup: - contact_address: Adresse - contact_person: Personne à contacter - contact_phone: Téléphone - ignore_apple_restriction: Pour cette cellule, ne pas bloquer les commandes en cas de manque de glands - name: - page: - body: Contenu - parent_id: Page parente settings: messages: send_as_email: Transmettre les messages de la boufcoop par email @@ -1649,48 +1432,6 @@ fr: settings_group: messages: Messages privacy: Confidentialité - stock_article: - supplier: FournisseurE - supplier: - address: Adresse - contact_person: Contact - customer_number: Numéro de client de la coop - delivery_days: Jours de livraison - email: Email - fax: Fa - is_subscribed: abonné? - min_order_quantity: Quantité minimale à commander - name: Nom - note: Note - order_howto: Comment commander - phone: Téléphone - phone2: Autre téléphone - url: Site web - task: - done: Fait? - due_date: Pour quand? - duration: Durée - name: Nom - required_users: Nombre de personnes nécessaires - user_list: Responsables inscritEs - workgroup: Équipe - user: - email: Email - last_name: Nom de famille - name: Nom - nick: Identifiant - ordergroup: Cellule - phone: Téléphone - workgroup: - one: Équipe - other: Équipes - workgroup: - next_weekly_tasks_number: Combien de temps en avance les boulots doivent ils être annoncés sur le site? - role_admin: Administration - role_article_meta: Base de données des articles - role_finance: Trésorerie - role_orders: Gestion des commandes - role_suppliers: Contact avec les fournisseusEs_rs 'no': Non options: settings: @@ -1819,11 +1560,6 @@ fr: show_deliveries: Afficher tous les réapprovisionnements update: notice: Les données du_de la fournisseurE ont été mises à jour - support: - array: - last_word_connector: et - two_words_connector: et - words_connector: ! ',' tasks: accept: notice: Tu as accepté ce boulot @@ -1884,7 +1620,6 @@ fr: accept_task: Te charger de ce boulot. confirm_delete_group: Veux-tu vraiment supprimer ce boulot hebdomadaire? delete_group: Supprimer ce boulot - due_date: Echéance hours: ! '%{count}h' mark_done: Marquer comme effectué reject_task: Refuser ce boulot @@ -1901,13 +1636,6 @@ fr: workgroup: title: Agenda de l'%{workgroup} title_all: Boulot prévu pour l'équipe - time: - am: le matin - formats: - default: ! '%A, %d. %B %Y, %Hh%M' - long: ! '%A, %d. %B %Y, %Hh%M' - short: ! '%d. %B, %Hh%M ' - pm: après-midi ui: close: Fermer delete: Supprimer diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 3f0d6378..25f54484 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -2,29 +2,129 @@ nl: activerecord: attributes: article: - article_category: categorie + article_category: Categorie availability: Artikel leverbaar? - deposit: statiegeld - fc_price: prijs foodcoop - fc_share: marge foodcoop - gross_price: bruto prijs + availability_short: leverb. + deposit: Statiegeld + fc_price: Foodcoop prijs + fc_price_short: FC prijs + fc_share: Foodcoop marge + fc_share_short: FC marge + gross_price: Bruto prijs + manufacturer: Producent name: Naam note: Notitie - price: netto prijs + origin: Herkomst + order_number: Ordernummer + price: Netto prijs supplier: Leverancier tax: BTW - unit: eenheid - unit_quantity: groothandelseenheid + unit: Eenheid + unit_quantity: Groothandelseenheid + unit_quantity_short: Gr.Eenh. + article_category: + description: Omschrijving + name: Naam + delivery: + delivered_on: + note: + supplier: financial_transaction: amount: bedrag note: notitie + group_order_article: + ordergroup_id: + result: + invoice: + amount: Bedrag + date: Factuurdatum + delivery: Levering + deposit: Statiegeld in rekening gebracht + deposit_credit: Statiegeld teruggekregen + note: Notitie + number: Nummer + order: Bestelling + paid_on: Betaald op + supplier: Leverancier + message: + body: + group_id: + private: + recipient_tokens: + sent_to_all: + subject: + order: + ends: Eindigt op + note: Notitie + starts: Start op + order_article: + units_to_order: + update_current_price: + order_comment: + text: Commentaar voor deze bestelling toevoegen ... + ordergroup: + contact_address: Adres + contact_person: Contactpersoon + contact_phone: Telefoon + description: Omschrijving + ignore_apple_restriction: + name: Naam + user_tokens: Leden + page: + body: + parent_id: stock_article: - price: prijs - quantity: - quantity_available: + price: Prijs + quantity: Aantal + quantity_available: Beschikbaar + supplier: Leverancier + supplier: + address: Adres + contact_person: Contactpersoon + customer_number: Klantnummer + delivery_days: Bezorgdagen + email: Email + fax: Fax + is_subscribed: geabonneerd? + min_order_quantity: Minimale bestelhoeveelheid + name: Naam + note: Notitie + order_howto: Hoe te bestellen + phone: Telefoon + phone2: Telefoon 2 + url: Homepage + task: + description: + done: + due_date: + duration: + name: + required_users: + user_list: + workgroup: user: + email: Email first_name: Voornaam + last_name: Achternaam + name: Naam + nick: Gebruikersnaam + ordergroup: Huishouden password: Wachtwoord + password_confirmation: Wachtwoord herhalen + phone: Telefoon + workgroup: + one: Werkgroep + other: Werkgroepen + workgroup: + name: Naam + description: Omschrijving + next_weekly_tasks_number: + role_admin: Beheer + role_article_meta: Artikelen + role_finance: Financiën + role_orders: Bestellingen + role_suppliers: Leveranciers + user_tokens: Leden errors: has_many_left: is nog met een %{collection} verbonden! models: @@ -32,11 +132,6 @@ nl: attributes: done: exclusion: gedane taken kunnen niet herhaald worden - template: - body: ! 'Controleer de volgende velden:' - header: - one: ! 'Kon %{model} niet opslaan: één foutmelding.' - other: ! 'Kon %{model} niet opslaan: %{count} foutmeldingen.' models: article: Artikel article_category: Categorie @@ -339,7 +434,8 @@ nl: filename: Bestelling %{name}-%{date} - Artikellijst rows: - Huishouden - - Hoeveelheid + - Besteld + - Ontvangen - Prijs title: ! 'Artikellijst van bestelling: %{name}, gesloten op %{date}' order_by_groups: @@ -1253,74 +1349,6 @@ nl: required_users: tax: labels: - article: - article_category: Categorie - manufacturer: Producent - name: Naam - note: Notitie - origin: Herkomst - unit: Eenheid - article_category: - description: Omschrijving - name: Naam - defaults: - amount: - date: Datum - deposit: Statiegeld - description: Omschrijving - email: Email - note: Notitie - order_number: Bestelnummer - ordergroup: Huishouden - password: Wachtwoord - password_confirmation: Wachtwoord herhalen - phone: Telefoon - price: Prijs (netto) - tax: BTW - title: Titel - unit_quantity: Groothandelseenheid - user_tokens: Leden - delivery: - delivered_on: - supplier: - group_order_article: - ordergroup_id: - result: - invoice: - amount: Bedrag - date: Factuurdatum - delivery: Levering - deposit: Statiegeld in rekening gebracht - deposit_credit: Statiegeld teruggekregen - note: Notitie - number: Nummer - order: Bestelling - paid_on: Betaald op - supplier: Leverancier - message: - body: - group_id: - private: - recipient_tokens: - sent_to_all: - subject: - order: - ends: Eindigt op - starts: Start op - order_article: - units_to_order: - update_current_price: - order_comment: - text: - ordergroup: - contact_address: Adres - contact_person: Contactpersoon - contact_phone: Telefoon - ignore_apple_restriction: - name: - page: - body: - parent_id: settings: messages: send_as_email: Berichten als emails ontvangen. @@ -1336,48 +1364,6 @@ nl: settings_group: messages: Berichten privacy: Privacy - stock_article: - supplier: - supplier: - address: - contact_person: - customer_number: Klantnummer - delivery_days: Bezorgdagen - email: - fax: - is_subscribed: - min_order_quantity: - name: - note: - order_howto: - phone: - phone2: - url: - task: - done: - due_date: - duration: - name: - required_users: - user_list: - workgroup: - user: - email: Email - last_name: Achternaam - name: Naam - nick: Gebruikersnaam - ordergroup: Huishouden - phone: Telefoon - workgroup: - one: Werkgroep - other: Werkgroepen - workgroup: - next_weekly_tasks_number: - role_admin: - role_article_meta: Artikelbestand - role_finance: Financiën - role_orders: - role_suppliers: Leveranciers 'no': Nee options: settings: @@ -1556,7 +1542,6 @@ nl: accept_task: confirm_delete_group: delete_group: - due_date: hours: mark_done: reject_task: From 1e73c82205027aff06322e49acd7cc10c550c4d5 Mon Sep 17 00:00:00 2001 From: wvengen Date: Mon, 21 Oct 2013 18:00:13 +0200 Subject: [PATCH 65/79] remove unused files (complements bf0dc4af09190ef527e3e2bf382cf4b11483c569) [ci skip] --- public/.htaccess | 40 ------- public/_index.html | 277 --------------------------------------------- 2 files changed, 317 deletions(-) delete mode 100644 public/.htaccess delete mode 100644 public/_index.html diff --git a/public/.htaccess b/public/.htaccess deleted file mode 100644 index d3c99834..00000000 --- a/public/.htaccess +++ /dev/null @@ -1,40 +0,0 @@ -# General Apache options -AddHandler fastcgi-script .fcgi -AddHandler cgi-script .cgi -Options +FollowSymLinks +ExecCGI - -# If you don't want Rails to look in certain directories, -# use the following rewrite rules so that Apache won't rewrite certain requests -# -# Example: -# RewriteCond %{REQUEST_URI} ^/notrails.* -# RewriteRule .* - [L] - -# Redirect all requests not available on the filesystem to Rails -# By default the cgi dispatcher is used which is very slow -# -# For better performance replace the dispatcher with the fastcgi one -# -# Example: -# RewriteRule ^(.*)$ dispatch.fcgi [QSA,L] -RewriteEngine On - -# If your Rails application is accessed via an Alias directive, -# then you MUST also set the RewriteBase in this htaccess file. -# -# Example: -# Alias /myrailsapp /path/to/myrailsapp/public -# RewriteBase /myrailsapp - -RewriteRule ^$ index.html [QSA] -RewriteRule ^([^.]+)$ $1.html [QSA] -RewriteCond %{REQUEST_FILENAME} !-f -RewriteRule ^(.*)$ dispatch.cgi [QSA,L] - -# In case Rails experiences terminal errors -# Instead of displaying this message you can supply a file here which will be rendered instead -# -# Example: -# ErrorDocument 500 /500.html - -ErrorDocument 500 "

Application error

Rails application failed to start properly" \ No newline at end of file diff --git a/public/_index.html b/public/_index.html deleted file mode 100644 index a2daab72..00000000 --- a/public/_index.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - Ruby on Rails: Welcome aboard - - - - - - -
- - -
- - - - -
-

Getting started

-

Here’s how to get rolling:

- -
    -
  1. -

    Create your databases and edit config/database.yml

    -

    Rails needs to know your login and password.

    -
  2. - -
  3. -

    Use script/generate to create your models and controllers

    -

    To see all available options, run it without parameters.

    -
  4. - -
  5. -

    Set up a default route and remove or rename this file

    -

    Routes are setup in config/routes.rb.

    -
  6. -
-
-
- - -
- - \ No newline at end of file From 3275e9ba31235b06c2ed7050a2ce493273c43d3a Mon Sep 17 00:00:00 2001 From: wvengen Date: Tue, 22 Oct 2013 00:09:11 +0200 Subject: [PATCH 66/79] small i18n bug --- app/views/article_categories/index.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/article_categories/index.html.haml b/app/views/article_categories/index.html.haml index 0ec33119..00bcc354 100644 --- a/app/views/article_categories/index.html.haml +++ b/app/views/article_categories/index.html.haml @@ -5,7 +5,7 @@ %table.table.table-striped %thead %tr - %th= heading_helper ArticleCategory, :article_category + %th= heading_helper ArticleCategory, :name %th= heading_helper ArticleCategory, :description %th %tbody From 13a7f84e3570218db45e0ffdb8fc23297cb3f9dc Mon Sep 17 00:00:00 2001 From: wvengen Date: Wed, 23 Oct 2013 12:48:08 +0200 Subject: [PATCH 67/79] localeapp roundtrip [ci skip] --- config/locales/de.yml | 10 +++++----- config/locales/en.yml | 7 ++++--- config/locales/fr.yml | 21 +++++++++++++++++++-- config/locales/nl.yml | 20 ++++++++++++++++---- 4 files changed, 44 insertions(+), 14 deletions(-) diff --git a/config/locales/de.yml b/config/locales/de.yml index 7d3a33e6..fc164a7c 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -7,7 +7,7 @@ de: availability_short: verf. deposit: Pfand fc_price: Endpreis - fc_price_short: + fc_price_short: fc_share: FoodCoop-Aufschlag fc_share_short: FC-Aufschlag gross_price: Bruttopreis @@ -121,8 +121,8 @@ de: one: Arbeitsgruppe other: Arbeitsgruppen workgroup: - name: Name description: Beschreibung + name: Name next_weekly_tasks_number: Für wieviel Wochen im Voraus sollen Aufgaben erstellt werden? role_admin: Administration role_article_meta: Artikeldatenbank @@ -606,7 +606,7 @@ de: group_order_articles: form: amount_change_for: Mengenänderung für %{article} - result_hint: 'Einheit: %{unit}' + result_hint: ! 'Einheit: %{unit}' index: amount: Betrag amount_fc: Betrag(FC) @@ -642,8 +642,8 @@ de: title: Rechnung %{number} order_articles: edit: - title: Artikel aktualisieren stock_alert: Preise von Lagerartikeln können nicht geändert werden! + title: Artikel aktualisieren new: title: Neuer gelieferter Artikel die Bestellung ordergroups: @@ -1617,8 +1617,8 @@ de: notice: Aufgabenstatus wurde aktualisiert show: accept_task: Aufgabe übernehmen - confirm_delete_single: Die Aufgabe wirklich löschen? confirm_delete_group: Diese und alle folgenden wöchentlichen Aufgaben wirklich löschen? + confirm_delete_single: Die Aufgabe wirklich löschen? delete_group: Aufgabe und folgende löschen hours: ! '%{count}h' mark_done: Als erledigt markieren diff --git a/config/locales/en.yml b/config/locales/en.yml index b162d0fe..34aca236 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -121,8 +121,8 @@ en: one: Workgroup other: Workgroups workgroup: - name: Name description: Description + name: Name next_weekly_tasks_number: For how many weeks in advance would you like to define tasks? role_admin: Administration role_article_meta: Article database @@ -610,7 +610,7 @@ en: group_order_articles: form: amount_change_for: Change amount for %{article} - result_hint: 'Unit: %{unit}' + result_hint: ! 'Unit: %{unit}' index: amount: Amount amount_fc: Amount(FC) @@ -646,6 +646,7 @@ en: title: Invoice %{number} order_articles: edit: + stock_alert: title: Update article new: title: Add delivered article to order @@ -1620,8 +1621,8 @@ en: notice: The state of the task has been updated show: accept_task: Accept task - confirm_delete_single: Are you sure you want to delete the task? confirm_delete_group: Really delete this and all subsequent tasks? + confirm_delete_single: Are you sure you want to delete the task? delete_group: Delete task and subsequent hours: ! '%{count}h' mark_done: Mark task as done diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 463ecafc..d064380a 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -4,9 +4,12 @@ fr: article: article_category: Catégorie availability: l'article est-il disponible? + availability_short: deposit: Consigne fc_price: Prix final + fc_price_short: fc_share: Supplément boufcoop + fc_share_short: gross_price: Prix brut manufacturer: ProductRICE_eur name: Nom @@ -18,11 +21,13 @@ fr: tax: TVA unit: Unité unit_quantity: Unités par lot + unit_quantity_short: article_category: description: Description name: Nom delivery: delivered_on: Date de réapprovisionnement + note: supplier: Fournisseuse_r financial_transaction: amount: montant @@ -50,6 +55,7 @@ fr: subject: Sujet order: ends: Clôture le + note: starts: Ouverture le order_article: units_to_order: Quantité @@ -73,10 +79,14 @@ fr: quantity: quantity_available: supplier: FournisseurE + stock_taking: + date: + note: supplier: address: Adresse contact_person: Contact customer_number: Numéro de client de la coop + customer_number_short: delivery_days: Jours de livraison email: Email fax: Fa @@ -111,8 +121,8 @@ fr: one: Équipe other: Équipes workgroup: - name: Nom description: Description + name: Nom next_weekly_tasks_number: Combien de temps en avance les boulots doivent ils être annoncés sur le site? role_admin: Administration role_article_meta: Base de données des articles @@ -349,6 +359,7 @@ fr: title: sync: outlist: + alert_used: body: ! 'Les articles suivants ne sont plus dans la liste et seront donc supprimés:' body_skip: Aucun article à supprimer. title: Exclure de la liste... @@ -433,7 +444,7 @@ fr: filename: Commande %{name}-%{date} - Trier par rows: - Cellule - - + - - Quantité - Prix title: ! 'Ordre des articles pour la commande: %{name}, close le %{date}' @@ -609,6 +620,7 @@ fr: group_order_articles: form: amount_change_for: Modification de la quantité de %{article} + result_hint: index: amount: Montant amount_fc: Montant(boufcoop) @@ -644,6 +656,7 @@ fr: title: Facture %{number} order_articles: edit: + stock_alert: title: Mettre à jour la liste des article new: title: @@ -915,6 +928,9 @@ fr: action: Engrainer! body:

Sur cette page, tu peux engrainer une personne qui ne fait pas encore partie de la Boufcoop à rejoindre la cellule %{group} success: La_le membre a été engrainéE avec succès! + js: + ordering: + confirm_change: layouts: application1: title: Foodsoft - %{title} @@ -1619,6 +1635,7 @@ fr: show: accept_task: Te charger de ce boulot. confirm_delete_group: Veux-tu vraiment supprimer ce boulot hebdomadaire? + confirm_delete_single: delete_group: Supprimer ce boulot hours: ! '%{count}h' mark_done: Marquer comme effectué diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 25f54484..2252563a 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -14,8 +14,8 @@ nl: manufacturer: Producent name: Naam note: Notitie - origin: Herkomst order_number: Ordernummer + origin: Herkomst price: Netto prijs supplier: Leverancier tax: BTW @@ -27,7 +27,7 @@ nl: name: Naam delivery: delivered_on: - note: + note: supplier: financial_transaction: amount: bedrag @@ -73,15 +73,20 @@ nl: page: body: parent_id: + title: stock_article: price: Prijs quantity: Aantal quantity_available: Beschikbaar supplier: Leverancier + stock_taking: + date: + note: supplier: address: Adres contact_person: Contactpersoon customer_number: Klantnummer + customer_number_short: delivery_days: Bezorgdagen email: Email fax: Fax @@ -94,7 +99,7 @@ nl: phone2: Telefoon 2 url: Homepage task: - description: + description: done: due_date: duration: @@ -116,8 +121,8 @@ nl: one: Werkgroep other: Werkgroepen workgroup: - name: Naam description: Omschrijving + name: Naam next_weekly_tasks_number: role_admin: Beheer role_article_meta: Artikelen @@ -352,6 +357,7 @@ nl: title: sync: outlist: + alert_used: body: ! 'De volgende artikelen zijn uit de lijst gehaald en worden verwijderd:' body_skip: Er zijn geen artikelen om te verwijderen. title: Uit de lijst halen ... @@ -597,6 +603,7 @@ nl: group_order_articles: form: amount_change_for: + result_hint: index: amount: Bedrag amount_fc: Bedrag(FC) @@ -632,6 +639,7 @@ nl: title: Factuur %{number} order_articles: edit: + stock_alert: title: Artikel bijwerken new: title: Geleverd artikel aan bestelling toevoegen @@ -891,6 +899,9 @@ nl: action: Uitnodiging versturen body:

Hier kun je iemand die nog geen lid is, uitnodigen voor de groep %{group}.

success: Persoon is uitgenodigd. + js: + ordering: + confirm_change: layouts: application1: title: Foodsoft - %{title} @@ -1541,6 +1552,7 @@ nl: show: accept_task: confirm_delete_group: + confirm_delete_single: delete_group: hours: mark_done: From 68b9f6a974d6b6098b9f61601a5f33b5b09cae69 Mon Sep 17 00:00:00 2001 From: wvengen Date: Wed, 23 Oct 2013 12:57:42 +0200 Subject: [PATCH 68/79] i18n-js assets configuration change --- config/application.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/config/application.rb b/config/application.rb index ee7d7d71..2d8cf3ef 100644 --- a/config/application.rb +++ b/config/application.rb @@ -60,7 +60,8 @@ module Foodsoft # Version of your assets, change this if you want to expire all your assets config.assets.version = '1.0' - # Do not enable database connection when precompiling assets - config.assets.initialize_on_precompile = false + # It would be nice not to enable database connection when precompiling assets, + # but i18n-js requires initialization, that's why it's on. + config.assets.initialize_on_precompile = true end end From b314363ce3f89dc4b34829fddb306cb96bead8eb Mon Sep 17 00:00:00 2001 From: wvengen Date: Thu, 24 Oct 2013 10:11:26 +0200 Subject: [PATCH 69/79] bundle update --- Gemfile.lock | 64 ++++++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 0370d43d..4c756a49 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -22,12 +22,12 @@ GEM remote: https://rubygems.org/ specs: Ascii85 (1.0.2) - actionmailer (3.2.14) - actionpack (= 3.2.14) + actionmailer (3.2.15) + actionpack (= 3.2.15) mail (~> 2.5.4) - actionpack (3.2.14) - activemodel (= 3.2.14) - activesupport (= 3.2.14) + actionpack (3.2.15) + activemodel (= 3.2.15) + activesupport (= 3.2.15) builder (~> 3.0.0) erubis (~> 2.7.0) journey (~> 1.0.4) @@ -35,18 +35,18 @@ GEM rack-cache (~> 1.2) rack-test (~> 0.6.1) sprockets (~> 2.2.1) - activemodel (3.2.14) - activesupport (= 3.2.14) + activemodel (3.2.15) + activesupport (= 3.2.15) builder (~> 3.0.0) - activerecord (3.2.14) - activemodel (= 3.2.14) - activesupport (= 3.2.14) + activerecord (3.2.15) + activemodel (= 3.2.15) + activesupport (= 3.2.15) arel (~> 3.0.2) tzinfo (~> 0.3.29) - activeresource (3.2.14) - activemodel (= 3.2.14) - activesupport (= 3.2.14) - activesupport (3.2.14) + activeresource (3.2.15) + activemodel (= 3.2.15) + activesupport (= 3.2.15) + activesupport (3.2.15) i18n (~> 0.6, >= 0.6.4) multi_json (~> 1.0) acts_as_tree (1.4.0) @@ -123,7 +123,7 @@ GEM actionpack (>= 3.2, < 5) activesupport (>= 3.2, < 5) hashery (2.1.1) - highline (1.6.19) + highline (1.6.20) hike (1.2.3) i18n (0.6.5) i18n-spec (0.4.0) @@ -137,7 +137,7 @@ GEM jquery-rails (3.0.4) railties (>= 3.0, < 5.0) thor (>= 0.14, < 2.0) - json (1.8.0) + json (1.8.1) kaminari (0.14.1) actionpack (>= 3.0.0) activesupport (>= 3.0.0) @@ -165,9 +165,9 @@ GEM activesupport (~> 3.1) polyamorous (~> 0.5.0) mime-types (1.25) - mini_portile (0.5.1) + mini_portile (0.5.2) mono_logger (1.1.0) - multi_json (1.8.1) + multi_json (1.8.2) mysql2 (0.3.13) net-scp (1.1.2) net-ssh (>= 2.6.5) @@ -195,20 +195,20 @@ GEM rack (1.4.5) rack-cache (1.2) rack (>= 0.4) - rack-protection (1.5.0) + rack-protection (1.5.1) rack rack-ssl (1.3.3) rack rack-test (0.6.2) rack (>= 1.0) - rails (3.2.14) - actionmailer (= 3.2.14) - actionpack (= 3.2.14) - activerecord (= 3.2.14) - activeresource (= 3.2.14) - activesupport (= 3.2.14) + rails (3.2.15) + actionmailer (= 3.2.15) + actionpack (= 3.2.15) + activerecord (= 3.2.15) + activeresource (= 3.2.15) + activesupport (= 3.2.15) bundler (~> 1.0) - railties (= 3.2.14) + railties (= 3.2.15) rails-assets-listjs (0.2.0.beta.4) railties (>= 3.1) rails-i18n (3.0.0) @@ -216,9 +216,9 @@ GEM rails (>= 3.0.0, < 4.0.0) rails-settings-cached (0.2.4) rails (>= 3.0.0) - railties (3.2.14) - actionpack (= 3.2.14) - activesupport (= 3.2.14) + railties (3.2.15) + actionpack (= 3.2.15) + activesupport (= 3.2.15) rack-ssl (~> 1.3.2) rake (>= 0.8.7) rdoc (~> 3.4) @@ -238,10 +238,10 @@ GEM redis-namespace (~> 1.2) sinatra (>= 0.9.2) vegas (~> 0.1.2) - rspec-core (2.14.5) + rspec-core (2.14.6) rspec-expectations (2.14.3) diff-lcs (>= 1.1.3, < 2.0) - rspec-mocks (2.14.3) + rspec-mocks (2.14.4) rspec-rails (2.14.0) actionpack (>= 3.0) activesupport (>= 3.0) @@ -276,7 +276,7 @@ GEM multi_json (~> 1.0) simplecov-html (~> 0.7.1) simplecov-html (0.7.1) - sinatra (1.4.3) + sinatra (1.4.4) rack (~> 1.4) rack-protection (~> 1.4) tilt (~> 1.3, >= 1.3.4) From 85c98c4566c3eb3aabe60e133d7ecbd44926d344 Mon Sep 17 00:00:00 2001 From: wvengen Date: Mon, 28 Oct 2013 00:49:00 +0100 Subject: [PATCH 70/79] make heroku deploy work again --- script/heroku_deploy | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/script/heroku_deploy b/script/heroku_deploy index 7f55fecf..e1e0326b 100755 --- a/script/heroku_deploy +++ b/script/heroku_deploy @@ -38,6 +38,8 @@ if ! heroku apps | grep -q "^$APP\s"; then heroku create "$APP" --region "$REGION" heroku addons:add heroku-postgresql:dev --app "$APP" heroku pg:promote `heroku config | grep 'HEROKU_POSTGRESQL_.*_URL' | cut -d: -f1` + # user-env-compile needed because config.assets.initialize_on_precompile is true + heroku labs:enable user-env-compile --app "$APP" fi heroku config:set RACK_ENV="${RAILS_ENV}" RAILS_ENV="${RAILS_ENV}" --app "$APP" @@ -66,7 +68,7 @@ echo 'web: bundle exec unicorn -p $PORT -E $RACK_ENV' >Procfile sed -i 's|\(#\s*\)\?\(config\.action_mailer\.raise_delivery_errors\)\s*=.*|\2 = false|' config/environments/${RAILS_ENV}.rb sed -i 's|\(#\s*\)\?\(config\.action_mailer\.delivery_method\)\s*=.*|\2 = :smtp|' config/environments/${RAILS_ENV}.rb # do not ignore deployment files -sed -i 's|^\(config/\*.yml\)|#\1|' .gitignore +sed -i 's|^\(config/.*\.yml\)|#\1|' .gitignore sed -i 's|^\(config/initializers/secret_token.rb\)|#\1|' .gitignore sed -i 's|^\(config/environments/development.rb\)|#\1|' .gitignore # make sure we have a full configuration @@ -85,6 +87,8 @@ else Foodsoft::Application.config.secret_token = '`openssl rand -hex 128`' EOF fi +# update Gemfile.lock after Gemfile updates (required by heroku) +bundle install --quiet # configure localeapp, manually to include environment if [ "$LOCALEAPP_KEY" ]; then cat >config/initializers/localeapp.rb <>Gemfile # also do not cache so we get locale updates sed -i 's|\(#\s*\)\?\(config\.cache_classes\)\s*=.*|\2 = false|' config/environments/${RAILS_ENV}.rb + bundle exec localeapp pull fi -# update Gemfile.lock after Gemfile updates (required by heroku) -bundle install --quiet # TODO add more extensive database seed # and push = deploy @@ -115,11 +118,9 @@ if !heroku run rake db:version >/dev/null 2>&1; then else heroku run rake db:migrate fi -# get full translations so update works -[ "$LOCALEAPP_KEY" ] && heroku run localeapp pull # restart just to be sure -heroku ps:restart +#heroku ps:restart # return to original branch git checkout -q "$ORIG_BRANCH" && git stash pop -q From 2bd559f4d9d6f0dd8eced8fd354bbab0e2e8be6a Mon Sep 17 00:00:00 2001 From: Mathijs de Bruin Date: Mon, 28 Oct 2013 15:47:21 +0100 Subject: [PATCH 71/79] Rename documentation to .md for proper rendering. --- doc/{DEVELOPMENT => DEVELOPMENT.md} | 0 doc/{README_FOR_APP => README_FOR_APP.md} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename doc/{DEVELOPMENT => DEVELOPMENT.md} (100%) rename doc/{README_FOR_APP => README_FOR_APP.md} (100%) diff --git a/doc/DEVELOPMENT b/doc/DEVELOPMENT.md similarity index 100% rename from doc/DEVELOPMENT rename to doc/DEVELOPMENT.md diff --git a/doc/README_FOR_APP b/doc/README_FOR_APP.md similarity index 100% rename from doc/README_FOR_APP rename to doc/README_FOR_APP.md From 46a6b13e23aa62366730fc9d90ccc57ee0a7cb30 Mon Sep 17 00:00:00 2001 From: Mathijs de Bruin Date: Mon, 28 Oct 2013 15:47:47 +0100 Subject: [PATCH 72/79] DEVELOPMENT *is* outdated. Link to .md docs. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e7be634b..d0dde9b1 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ More information about using this software and contributing can be found on the Install -------- -Have a look at [DEVELOPMENT](https://github.com/foodcoops/foodsoft/blob/master/doc/DEVELOPMENT) (possibly outdated) and the (more recent) [Developing Guidelines](https://github.com/foodcoops/foodsoft/wiki/Developing-Guidelines) page on the wiki. +Have a look at [DEVELOPMENT.md](https://github.com/foodcoops/foodsoft/blob/master/doc/DEVELOPMENT.md) (outdated) and the (more recent) [Developing Guidelines](https://github.com/foodcoops/foodsoft/wiki/Developing-Guidelines) page on the wiki. License ------- From ebc3c4cb991bcd6366c7228c28ffb672a0641dd3 Mon Sep 17 00:00:00 2001 From: Mathijs de Bruin Date: Mon, 28 Oct 2013 15:49:59 +0100 Subject: [PATCH 73/79] Whitespace cleanup. --- doc/DEPLOYMENT.md | 2 +- doc/DEVELOPMENT.md | 6 +++--- doc/README_FOR_APP.md | 24 ++++++++++++------------ 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/doc/DEPLOYMENT.md b/doc/DEPLOYMENT.md index 30f886a6..dad42aa3 100644 --- a/doc/DEPLOYMENT.md +++ b/doc/DEPLOYMENT.md @@ -20,4 +20,4 @@ Deploy to staging bundle exec cap deploy Deploy to production - bundle exec cap production deploy \ No newline at end of file + bundle exec cap production deploy diff --git a/doc/DEVELOPMENT.md b/doc/DEVELOPMENT.md index e2fecc18..fb226daf 100644 --- a/doc/DEVELOPMENT.md +++ b/doc/DEVELOPMENT.md @@ -15,7 +15,7 @@ Create the database configuration from the default: If you are fine with using a file-based sqlite database you are all set. The sqlite files (development/test/production) will reside in the "db" directory. Otherwise you would want to edit database.yml to suit your needs (MySQL whatever). - + (2) Configure development environment ------------------------------------- @@ -66,7 +66,7 @@ With this, you also get a ready to go user with username 'admin' and password 's (7) Try it out! ---------------- +--------------- Start the WEBrick server to try it out: bundle exec rails s @@ -93,4 +93,4 @@ Just install mailcatcher with gem install mailcatcher and start the service with From now on you have a smpt server listening on 1025. To see the emails go to - http://localhost:1080 \ No newline at end of file + http://localhost:1080 diff --git a/doc/README_FOR_APP.md b/doc/README_FOR_APP.md index 79fdd74b..0f25c510 100644 --- a/doc/README_FOR_APP.md +++ b/doc/README_FOR_APP.md @@ -3,30 +3,30 @@ Run "rake doc:app" to generate API documentation for your models and controllers = The Foodsoft -is a Web-based software to manage a non-profit food coop (product catalog, ordering, accounting, job scheduling). +is a Web-based software to manage a non-profit food coop (product catalog, ordering, accounting, job scheduling). == Bestellen -Das Bestellen ist der Hauptteil dieser Software und ein wenig kompliziert. -Hier starte ich den Versuch die Programmlogik in Text umzusetzen und +Das Bestellen ist der Hauptteil dieser Software und ein wenig kompliziert. +Hier starte ich den Versuch die Programmlogik in Text umzusetzen und verweise auf die enstprechenden Controller bzw. Modelle. Der relevante Controller ist OrderingController. === Bestellung "in Netz stellen" Darunter verstehen wir die Auswahl von Artikeln eines bestimmten Lieferanten fuer eine zeitlich begrenzte Bestellung im Internet. Die relevanten Methoden sind OrdersController#newOrder und folgende. -Jede Bestellung wird durch die Klasse Order abgebildet. +Jede Bestellung wird durch die Klasse Order abgebildet. Die zugehoerigen Artikel werden duch die Klasse OrderArticle mit den Artikeln verknuepft. Dabei werden auch die Attribute quantity, tolerance und quantity_to_order gespeichert. Diese Mengen repraesentieren die Gesamtbestellung, also alle Bestellgruppen. === Eine Bestellgruppe bestellt... -Die Methode OrdersController#order schickt uns die Bestellenseite. Mit dieser Oberflaeche +Die Methode OrdersController#order schickt uns die Bestellenseite. Mit dieser Oberflaeche koennen die Bestellgruppena die vorher ausgewaehlten Artikel bestellen. -Mittels den Buttons werden dabei live, also clientseitig, die Preise ermittelt +Mittels den Buttons werden dabei live, also clientseitig, die Preise ermittelt und der Gesamtpreis berechnet. Ist der Gesamtpreis groeßer als der aktuelle -Gruppenkontostand, so wird die Preisspalte rot unterlegt und die Bestellung +Gruppenkontostand, so wird die Preisspalte rot unterlegt und die Bestellung kann nicht gespeichert werden. === (gruppen)-Bestellung wird gespeichert @@ -67,27 +67,27 @@ Wir unterscheiden dehalb zwei Faelle: Verringe Bestellung auf 2(1) um 19uhr. => Zeile mit created_on = 18uhr wird gelöscht und in der Zeile mit created_on = 17uhr wird der Wert tolerance auf 1 gaendert. - + === Wer bekommt wieviel? Diese Frage wird wie schon erwaehnt mittels der group_order_article_quantites -Tabelle -geloest. +geloest. Beipspiel. articel x mit unit_quantity = 5. 17uhr: gruppe a bestellt 2(3), weil sie auf jeden fall was von x bekommen will 18uhr: gruppe b bestellt 2(0) 19uhr: gruppe a faellt ein dass sie doch noch mehr braucht von x und aendert auf 4(1). - + jetzt gibt es drei zeilen in der tabelle, die so aussehen: (gruppe a), 2(1), 17uhr (wurde um 19uhr von 2(3) auf 2(1) geaendert) (gruppe b), 2(0), 18uhr (gruppe a), 2(0), 19uhr. - + die zuteilung wird dann wie folgt ermittelt: zeile 1: gruppe a bekommt 2 zeile 2: gruppe b bekommt 2 zeile 3: gruppe a bekommt 1, weil jetzt das gebinde schon voll ist. - + Endstand: insg. Bestellt wurden 6(1) Gruppe a bekommt 3 einheiten. gruppe b bekommt 2 einheiten. From 41e384892c84e929e0d135ac87ecc3562d314655 Mon Sep 17 00:00:00 2001 From: Mathijs de Bruin Date: Mon, 28 Oct 2013 16:26:44 +0100 Subject: [PATCH 74/79] Getting started guide. --- README.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d0dde9b1..cb91ca71 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,55 @@ Web-based software to manage a non-profit food coop (product catalog, ordering, More information about using this software and contributing can be found on the [wiki](https://github.com/foodcoops/foodsoft/wiki). -Install --------- +System requirements +------------------- + +* [RVM](https://rvm.io/rvm/install) +* [Ruby 1.9.3](https://www.ruby-lang.org/en/downloads/) +* [Bundler](http://bundler.io/) + +Getting started +--------------- + +1. Install RVM (if you have not done so before): + + \curl -L https://get.rvm.io | bash + +2. Clone the repository from GitHub: + + git clone https://github.com/foodcoops/foodsoft.git + +3. Install Ruby dependencies: + + bundle install + +4. Setup your development environment: + + rake foodsoft:setup_development + + This will interactively prompt with several questions relating to your + required environment. + +5. Start rails by running: + + bundle exec rails s + +6. Open your favorite browser and open the web application at: + + http://localhost:3000/ + + You might want to watch a + [kitten video](https://www.youtube.com/watch?v=9Iq5yCoHp4o) + while it's loading. + +7. Login using the default credentials: `admin/secret` + +8. Change the admin password, just in case. + +9. Have phun! + +Developing +---------- Have a look at [DEVELOPMENT.md](https://github.com/foodcoops/foodsoft/blob/master/doc/DEVELOPMENT.md) (outdated) and the (more recent) [Developing Guidelines](https://github.com/foodcoops/foodsoft/wiki/Developing-Guidelines) page on the wiki. From 193e32f20bbf5d1900c9cf287008810ab92e93de Mon Sep 17 00:00:00 2001 From: Mathijs de Bruin Date: Mon, 28 Oct 2013 16:36:04 +0100 Subject: [PATCH 75/79] Deployment details / contact us. --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index cb91ca71..16c5bb96 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,15 @@ Developing Have a look at [DEVELOPMENT.md](https://github.com/foodcoops/foodsoft/blob/master/doc/DEVELOPMENT.md) (outdated) and the (more recent) [Developing Guidelines](https://github.com/foodcoops/foodsoft/wiki/Developing-Guidelines) page on the wiki. +Deploying +--------- + +As you might have noticed, documentation is scarce and insufficient. If you +intend to deploy foodsoft in production, we would love to guide you through +the process. We can be contacted through the +[developers@foodcoop.nl](mailto:developers@foodcoop.nl) or +[foodsoft@foodcoops.net](mailto:foodsoft@foodcoops.net). + License ------- From 50d2991cc0e1c3433fa008eba9ed17a31c75cdd4 Mon Sep 17 00:00:00 2001 From: wvengen Date: Tue, 29 Oct 2013 14:23:37 +0100 Subject: [PATCH 76/79] fix README markup --- README.md | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 16c5bb96..edd45078 100644 --- a/README.md +++ b/README.md @@ -20,32 +20,36 @@ Getting started --------------- 1. Install RVM (if you have not done so before): - - \curl -L https://get.rvm.io | bash + ``` + \curl -L https://get.rvm.io | bash + ``` 2. Clone the repository from GitHub: - - git clone https://github.com/foodcoops/foodsoft.git + ``` + git clone https://github.com/foodcoops/foodsoft.git + ``` 3. Install Ruby dependencies: - - bundle install + ``` + bundle install + ``` 4. Setup your development environment: - - rake foodsoft:setup_development - + ``` + rake foodsoft:setup_development + ``` This will interactively prompt with several questions relating to your required environment. 5. Start rails by running: - - bundle exec rails s + ``` + bundle exec rails s + ``` 6. Open your favorite browser and open the web application at: - - http://localhost:3000/ - + ``` + http://localhost:3000/ + ``` You might want to watch a [kitten video](https://www.youtube.com/watch?v=9Iq5yCoHp4o) while it's loading. @@ -66,9 +70,11 @@ Deploying As you might have noticed, documentation is scarce and insufficient. If you intend to deploy foodsoft in production, we would love to guide you through -the process. We can be contacted through the +the process. You can contact the mailing list +[foodsoft-discuss](http://foodsoft.51229.x6.nabble.com/foodsoft-discuss-f5.html), +or mail some of us directly at [developers@foodcoop.nl](mailto:developers@foodcoop.nl) or -[foodsoft@foodcoops.net](mailto:foodsoft@foodcoops.net). +foodsoft (at) foodcoops.net. License ------- From 75059d5bcf77a3f230da738c534f324302d2bb61 Mon Sep 17 00:00:00 2001 From: wvengen Date: Tue, 29 Oct 2013 15:27:26 +0100 Subject: [PATCH 77/79] split and cleanup documentation [ci skip] --- README.md | 69 +++--------------- doc/DEVELOPMENT.md | 96 ------------------------- doc/SETUP_DEVELOPMENT.md | 147 +++++++++++++++++++++++++++++++++++++++ doc/SETUP_PRODUCTION.md | 11 +++ 4 files changed, 168 insertions(+), 155 deletions(-) delete mode 100644 doc/DEVELOPMENT.md create mode 100644 doc/SETUP_DEVELOPMENT.md create mode 100644 doc/SETUP_PRODUCTION.md diff --git a/README.md b/README.md index edd45078..a1067c12 100644 --- a/README.md +++ b/README.md @@ -3,78 +3,29 @@ FoodSoft [![Build Status](https://travis-ci.org/foodcoops/foodsoft.png)](https://travis-ci.org/foodcoops/foodsoft) [![Code Climate](https://codeclimate.com/github/foodcoops/foodsoft.png)](https://codeclimate.com/github/foodcoops/foodsoft) [![Dependency Status](https://gemnasium.com/foodcoops/foodsoft.png)](https://gemnasium.com/foodcoops/foodsoft) -[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/foodcoops/foodsoft/trend.png)](https://bitdeli.com/free "Bitdeli Badge") +[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/foodcoops/foodsoft/trend.png)](https://bitdeli.com/foodcoops "Bitdeli Badge") Web-based software to manage a non-profit food coop (product catalog, ordering, accounting, job scheduling). +If you're a food coop considering to use foodsoft, please have a look at the [wiki page for foodcoops](https://github.com/foodcoops/foodsoft/wiki/For-foodcoops). When you'd like to experiment with or develop foodsoft, see [doc/SETUP_DEVELOPMENT](https://github.com/foodcoops/foodsoft/blob/master/doc/SETUP_DEVELOPMENT.md) on how to set it up on your own computer. + More information about using this software and contributing can be found on the [wiki](https://github.com/foodcoops/foodsoft/wiki). -System requirements -------------------- - -* [RVM](https://rvm.io/rvm/install) -* [Ruby 1.9.3](https://www.ruby-lang.org/en/downloads/) -* [Bundler](http://bundler.io/) - -Getting started ---------------- - -1. Install RVM (if you have not done so before): - ``` - \curl -L https://get.rvm.io | bash - ``` - -2. Clone the repository from GitHub: - ``` - git clone https://github.com/foodcoops/foodsoft.git - ``` - -3. Install Ruby dependencies: - ``` - bundle install - ``` - -4. Setup your development environment: - ``` - rake foodsoft:setup_development - ``` - This will interactively prompt with several questions relating to your - required environment. - -5. Start rails by running: - ``` - bundle exec rails s - ``` - -6. Open your favorite browser and open the web application at: - ``` - http://localhost:3000/ - ``` - You might want to watch a - [kitten video](https://www.youtube.com/watch?v=9Iq5yCoHp4o) - while it's loading. - -7. Login using the default credentials: `admin/secret` - -8. Change the admin password, just in case. - -9. Have phun! Developing ---------- -Have a look at [DEVELOPMENT.md](https://github.com/foodcoops/foodsoft/blob/master/doc/DEVELOPMENT.md) (outdated) and the (more recent) [Developing Guidelines](https://github.com/foodcoops/foodsoft/wiki/Developing-Guidelines) page on the wiki. +Get foodsoft [running locally](https://github.com/foodcoops/foodsoft/blob/master/doc/SETUP_DEVELOPMENT.md), +then visit our [Developing Guidelines](https://github.com/foodcoops/foodsoft/wiki/Developing-Guidelines) +page on the wiki. + Deploying --------- -As you might have noticed, documentation is scarce and insufficient. If you -intend to deploy foodsoft in production, we would love to guide you through -the process. You can contact the mailing list -[foodsoft-discuss](http://foodsoft.51229.x6.nabble.com/foodsoft-discuss-f5.html), -or mail some of us directly at -[developers@foodcoop.nl](mailto:developers@foodcoop.nl) or -foodsoft (at) foodcoops.net. +Please see [doc/SETUP_PRODUCTION](https://github.com/foodcoops/foodsoft/blob/master/doc/SETUP_PRODUCTION.md), +as well as[doc/DEPLOYMENT](https://github.com/foodcoops/foodsoft/blob/master/doc/DEPLOYMENT.md). + License ------- diff --git a/doc/DEVELOPMENT.md b/doc/DEVELOPMENT.md deleted file mode 100644 index fb226daf..00000000 --- a/doc/DEVELOPMENT.md +++ /dev/null @@ -1,96 +0,0 @@ -README for DEVELopment Project Setup -==================================== - -Gratulations, you have successfully cloned the foodsoft project -from the git repository. Now you are only a few steps away from -trying it out and then jumping into development. (This manual presumes -you have ruby and rails setup.) - -(1) Configure datebase ----------------------- -Create the database configuration from the default: - - cp config/database.yml.SAMPLE config/database.yml - -If you are fine with using a file-based sqlite database you are all set. -The sqlite files (development/test/production) will reside in the "db" directory. -Otherwise you would want to edit database.yml to suit your needs (MySQL whatever). - - -(2) Configure development environment -------------------------------------- -Again, you need to create your own copy of the default configuration: - - cp config/environments/development.rb.SAMPLE config/environments/development.rb - -Edit development.rb to specify your settings (at least the ActionMailer SMTP settings). -If you just leave the file as is, emails will not work but everything else should be okay. - - -(3) Foodsoft settings ---------------------- -You need to create your own copy of the foodsoft configuration settings: - - cp config/app_config.yml.SAMPLE config/app_config.yml - -Edit app_config.yml to suit your needs or just keep the defaults for now. - - -(4) Secret Token -------------------- -The user session are stored in cookies. Do avoid misusing the cookies and its sensitive information, rails -will encrypt it with a token. So copy the config file - - cp config/initializers/secret_token.rb.SAMPLE config/initializers/secret_token.rb - -and modify the token!! - - -(5) Required ruby and gems -------------------- -We recommend to use rvm (https://rvm.beginrescueend.com/). Install rvm and get the latest ruby (>= 1.9.3). -If installed you only need to install the gem bundler: - - gem install bundler - -After that you get the other gems easily with (from project root): - - bundle install - - -(6) Create database (schema) and load defaults --------------------------- - rake db:setup - -With this, you also get a ready to go user with username 'admin' and password 'secret'. - - -(7) Try it out! ---------------- -Start the WEBrick server to try it out: - - bundle exec rails s - - -(8) (optional) Get background jobs done ---------------------------------------- -We use for time intensive tasks a background job queue, at the moment resque with redis as key/value store. -Install redis (in ubuntu the package redis-server works out of the box) and start the resque worker with: - - rake resque:work QUEUE=foodsoft_notifier - -To have look on the current queue, failed jobs etc start the resque server with - - resque-web - - -(9) (optional) View mails in browser instead in your logs ---------------------------------------------------------- -We use mailcatcher in development mode to view all delivered mails in a browser interface. -Just install mailcatcher with gem install mailcatcher and start the service with - - mailcatcher - -From now on you have a smpt server listening on 1025. To see the emails go to - - http://localhost:1080 diff --git a/doc/SETUP_DEVELOPMENT.md b/doc/SETUP_DEVELOPMENT.md new file mode 100644 index 00000000..18a2b16f --- /dev/null +++ b/doc/SETUP_DEVELOPMENT.md @@ -0,0 +1,147 @@ +Getting foodsoft running for development +======================================== + +Gratulations, if you read this file locally, you have successfully cloned the +foodsoft project from the git repository. Now you are only a few steps away +from trying it out and then jumping into development. + +**System requirements**: +[RVM](https://rvm.io/rvm/install), +[Ruby 1.9.3](https://www.ruby-lang.org/en/downloads/) and +[Bundler](http://bundler.io/). + +Getting started +--------------- + +0. Clone the repository from GitHub: + ``` + git clone https://github.com/foodcoops/foodsoft.git + ``` + +1. Install RVM and Ruby 1.9.3 (if you have not done so before): + ``` + \curl -L https://get.rvm.io | bash + source ~/.rvm/scripts/rvm + rvm install 1.9.3 + ``` + +2. Install Ruby dependencies: + ``` + bundle install + ``` + +3. Setup your development environment: + ``` + rake foodsoft:setup_development + ``` + This will interactively prompt with several questions relating to your + required environment. + +4. Start rails by running: + ``` + bundle exec rails s + ``` + +5. Open your favorite browser and open the web application at: + ``` + http://localhost:3000/ + ``` + You might want to watch a + [kitten video](https://www.youtube.com/watch?v=9Iq5yCoHp4o) + while it's loading. + +6. Login using the default credentials: `admin/secret` + +7. Change the admin password, just in case. + +8. Have phun! + + + +Manual configuration +-------------------- + +The rake task `foodsoft:setup_development` helps you to setup foodsoft. +If you want to have more control, you can do these steps manually as +explained here. + + +1. **Configure datebase** + + Create the database configuration from the default: + ```sh + cp config/database.yml.SQLite_SAMPLE config/database.yml + ``` + If you are fine with using a file-based sqlite database you are all set. + The sqlite files (development/test/production) will reside in the "db" + directory. Otherwise you would want to copy one of the other + "database.yml.*_SAMPLE" files and edit database.yml to suit your needs. + + +2. **Configure development environment** + + Again, you need to create your own copy of the default configuration: + ``` + cp config/environments/development.rb.SAMPLE config/environments/development.rb + ``` + + Edit development.rb to specify your settings (at least the ActionMailer SMTP + settings). If you just leave the file as is, emails will not work but + everything else should be okay. + + +3. **Foodsoft settings** + + You need to create your own copy of the foodsoft configuration settings: + ``` + cp config/app_config.yml.SAMPLE config/app_config.yml + ``` + Edit app_config.yml to suit your needs or just keep the defaults for now. + + +4. **Secret token** + + The user session are stored in cookies. Do avoid misusing the cookies and + its sensitive information, rails will encrypt it with a token. So copy the + config file + ``` + cp config/initializers/secret_token.rb.SAMPLE config/initializers/secret_token.rb + ``` + and modify the token!! You can run `bundle exec rake secret` + + +5. **Create database (schema) and load defaults** + ``` + rake db:setup + ``` + With this, you also get a ready to go user with username 'admin' and + password 'secret'. + + +6. (optional) Get **background jobs** done + + We use for time intensive tasks a background job queue, at the moment resque + with redis as key/value store. Install redis (in ubuntu the package + redis-server works out of the box) and start the resque worker with: + ``` + rake resque:work QUEUE=foodsoft_notifier + ``` + To have look on the current queue, failed jobs etc start the resque server with + ``` + resque-web + ``` + + +7. (optional) **View mails in browser** instead in your logs + + We use mailcatcher in development mode to view all delivered mails in a + browser interface. Just install mailcatcher with gem install mailcatcher + and start the service with + ``` + mailcatcher + ``` + From now on you have a smtp server listening on 1025. To see the emails go to + ``` + http://localhost:1080 + ``` + diff --git a/doc/SETUP_PRODUCTION.md b/doc/SETUP_PRODUCTION.md new file mode 100644 index 00000000..58527034 --- /dev/null +++ b/doc/SETUP_PRODUCTION.md @@ -0,0 +1,11 @@ +Running foodsoft in production +============================== + +As you might have noticed, documentation is scarce and insufficient. If you +intend to deploy foodsoft in production, we would love to guide you through the +process. You can contact the mailing list +[foodsoft-discuss](http://foodsoft.51229.x6.nabble.com/foodsoft-discuss-f5.html), +or mail some of us directly at +[developers@foodcoop.nl](mailto:developers@foodcoop.nl) or foodsoft (at) +foodcoops.net. + From cee6186c9e71a7d62c8cf2cb3ef28b6490331d7f Mon Sep 17 00:00:00 2001 From: wvengen Date: Tue, 29 Oct 2013 15:31:49 +0100 Subject: [PATCH 78/79] README fixups [ci skip] --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a1067c12..b5a36800 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ FoodSoft Web-based software to manage a non-profit food coop (product catalog, ordering, accounting, job scheduling). -If you're a food coop considering to use foodsoft, please have a look at the [wiki page for foodcoops](https://github.com/foodcoops/foodsoft/wiki/For-foodcoops). When you'd like to experiment with or develop foodsoft, see [doc/SETUP_DEVELOPMENT](https://github.com/foodcoops/foodsoft/blob/master/doc/SETUP_DEVELOPMENT.md) on how to set it up on your own computer. +If you're a food coop considering to use foodsoft, please have a look at the [wiki page for foodcoops](https://github.com/foodcoops/foodsoft/wiki/For-foodcoops). When you'd like to experiment with or develop foodsoft, you can read [how to set it up](https://github.com/foodcoops/foodsoft/blob/master/doc/SETUP_DEVELOPMENT.md) on your own computer. More information about using this software and contributing can be found on the [wiki](https://github.com/foodcoops/foodsoft/wiki). @@ -23,8 +23,8 @@ page on the wiki. Deploying --------- -Please see [doc/SETUP_PRODUCTION](https://github.com/foodcoops/foodsoft/blob/master/doc/SETUP_PRODUCTION.md), -as well as[doc/DEPLOYMENT](https://github.com/foodcoops/foodsoft/blob/master/doc/DEPLOYMENT.md). +[doc/SETUP_PRODUCTION](https://github.com/foodcoops/foodsoft/blob/master/doc/SETUP_PRODUCTION.md), +as well as [doc/DEPLOYMENT](https://github.com/foodcoops/foodsoft/blob/master/doc/DEPLOYMENT.md). License From ed0ac706b98d2cf7777670270d52e981c53a49fd Mon Sep 17 00:00:00 2001 From: wvengen Date: Tue, 29 Oct 2013 15:39:56 +0100 Subject: [PATCH 79/79] small README changes [ci skip] --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b5a36800..ffe83101 100644 --- a/README.md +++ b/README.md @@ -23,8 +23,9 @@ page on the wiki. Deploying --------- -[doc/SETUP_PRODUCTION](https://github.com/foodcoops/foodsoft/blob/master/doc/SETUP_PRODUCTION.md), -as well as [doc/DEPLOYMENT](https://github.com/foodcoops/foodsoft/blob/master/doc/DEPLOYMENT.md). +Setup foodsoft to [run in production](https://github.com/foodcoops/foodsoft/blob/master/doc/SETUP_PRODUCTION.md), +and automate [deployment](https://github.com/foodcoops/foodsoft/blob/master/doc/DEPLOYMENT.md). This section is +very much a work in progress. License