Merge remote-tracking branch 'upstream/master' into multiple-recurring-tasks
Conflicts: config/locales/de.yml
This commit is contained in:
commit
46b07a6136
257 changed files with 5408 additions and 1931 deletions
23
Gemfile
23
Gemfile
|
@ -11,22 +11,22 @@ group :assets do
|
|||
gem 'coffee-rails', '~> 3.2.1'
|
||||
|
||||
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
|
||||
gem 'therubyracer', :platforms => :ruby
|
||||
gem 'therubyracer', platforms: :ruby
|
||||
|
||||
gem 'uglifier', '>= 1.0.3'
|
||||
end
|
||||
|
||||
gem 'jquery-rails'
|
||||
|
||||
|
||||
gem 'mysql2'
|
||||
gem 'prawn'
|
||||
gem 'haml-rails'
|
||||
gem 'kaminari'
|
||||
gem 'client_side_validations'
|
||||
gem 'simple_form'
|
||||
gem 'rails3_acts_as_paranoid', "~>0.2.0"
|
||||
gem 'inherited_resources'
|
||||
gem 'localize_input', :git => "git://github.com/bennibu/localize_input.git"
|
||||
gem 'localize_input', git: "git://github.com/bennibu/localize_input.git"
|
||||
gem 'wikicloth'
|
||||
gem 'daemons'
|
||||
gem 'twitter-bootstrap-rails'
|
||||
|
@ -37,15 +37,16 @@ gem 'acts_as_versioned', git: 'git://github.com/technoweenie/acts_as_versioned.g
|
|||
gem 'acts_as_tree'
|
||||
gem 'acts_as_configurable', git: 'git://github.com/bwalding/acts_as_configurable.git'
|
||||
gem 'resque'
|
||||
gem 'whenever', :require => false # For defining cronjobs, see config/schedule.rb
|
||||
gem 'whenever', require: false # For defining cronjobs, see config/schedule.rb
|
||||
|
||||
group :production do
|
||||
gem 'exception_notification', :require => 'exception_notifier'
|
||||
gem 'exception_notification', require: 'exception_notifier'
|
||||
end
|
||||
|
||||
group :development do
|
||||
gem 'sqlite3'
|
||||
|
||||
gem 'mailcatcher'
|
||||
|
||||
# Better error output
|
||||
gem 'better_errors'
|
||||
gem 'binding_of_caller'
|
||||
|
@ -56,4 +57,14 @@ group :development do
|
|||
|
||||
# Get infos when not using proper eager loading
|
||||
gem 'bullet'
|
||||
|
||||
# Hide assets requests in log
|
||||
gem 'quiet_assets'
|
||||
|
||||
# Deploy with Capistrano
|
||||
gem 'capistrano', '2.13.5'
|
||||
gem 'capistrano-ext'
|
||||
#gem 'common_deploy', require: false, path: '../../common_deploy' # pending foodcoops/foodsoft#34, git: 'git://github.com/fsmanuel/common_deploy.git'
|
||||
# Avoid having content-length warnings
|
||||
gem 'thin'
|
||||
end
|
||||
|
|
135
Gemfile.lock
135
Gemfile.lock
|
@ -22,32 +22,32 @@ GEM
|
|||
remote: https://rubygems.org/
|
||||
specs:
|
||||
Ascii85 (1.0.2)
|
||||
actionmailer (3.2.11)
|
||||
actionpack (= 3.2.11)
|
||||
mail (~> 2.4.4)
|
||||
actionpack (3.2.11)
|
||||
activemodel (= 3.2.11)
|
||||
activesupport (= 3.2.11)
|
||||
actionmailer (3.2.13)
|
||||
actionpack (= 3.2.13)
|
||||
mail (~> 2.5.3)
|
||||
actionpack (3.2.13)
|
||||
activemodel (= 3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
builder (~> 3.0.0)
|
||||
erubis (~> 2.7.0)
|
||||
journey (~> 1.0.4)
|
||||
rack (~> 1.4.0)
|
||||
rack (~> 1.4.5)
|
||||
rack-cache (~> 1.2)
|
||||
rack-test (~> 0.6.1)
|
||||
sprockets (~> 2.2.1)
|
||||
activemodel (3.2.11)
|
||||
activesupport (= 3.2.11)
|
||||
activemodel (3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
builder (~> 3.0.0)
|
||||
activerecord (3.2.11)
|
||||
activemodel (= 3.2.11)
|
||||
activesupport (= 3.2.11)
|
||||
activerecord (3.2.13)
|
||||
activemodel (= 3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
arel (~> 3.0.2)
|
||||
tzinfo (~> 0.3.29)
|
||||
activeresource (3.2.11)
|
||||
activemodel (= 3.2.11)
|
||||
activesupport (= 3.2.11)
|
||||
activesupport (3.2.11)
|
||||
i18n (~> 0.6)
|
||||
activeresource (3.2.13)
|
||||
activemodel (= 3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
activesupport (3.2.13)
|
||||
i18n (= 0.6.1)
|
||||
multi_json (~> 1.0)
|
||||
acts_as_tree (1.2.0)
|
||||
activerecord (>= 3.0.0)
|
||||
|
@ -59,6 +59,14 @@ GEM
|
|||
builder (3.0.4)
|
||||
bullet (4.3.0)
|
||||
uniform_notifier
|
||||
capistrano (2.13.5)
|
||||
highline
|
||||
net-scp (>= 1.0.0)
|
||||
net-sftp (>= 2.0.0)
|
||||
net-ssh (>= 2.0.14)
|
||||
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)
|
||||
|
@ -72,6 +80,7 @@ GEM
|
|||
commonjs (0.2.6)
|
||||
daemons (1.1.9)
|
||||
erubis (2.7.0)
|
||||
eventmachine (1.0.3)
|
||||
exception_notification (2.6.1)
|
||||
actionmailer (>= 3.0.4)
|
||||
execjs (1.4.0)
|
||||
|
@ -85,6 +94,7 @@ GEM
|
|||
railties (>= 3.1, < 4.1)
|
||||
has_scope (0.5.1)
|
||||
hashery (2.0.1)
|
||||
highline (1.6.19)
|
||||
hike (1.2.1)
|
||||
i18n (0.6.1)
|
||||
inherited_resources (1.3.1)
|
||||
|
@ -94,7 +104,7 @@ GEM
|
|||
jquery-rails (2.1.3)
|
||||
railties (>= 3.1.0, < 5.0)
|
||||
thor (~> 0.14)
|
||||
json (1.7.6)
|
||||
json (1.7.7)
|
||||
kaminari (0.14.1)
|
||||
actionpack (>= 3.0.0)
|
||||
activesupport (>= 3.0.0)
|
||||
|
@ -104,18 +114,35 @@ GEM
|
|||
actionpack (>= 3.1)
|
||||
less (~> 2.2.0)
|
||||
libv8 (3.3.10.4)
|
||||
mail (2.4.4)
|
||||
mail (2.5.3)
|
||||
i18n (>= 0.4.0)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
mailcatcher (0.5.11)
|
||||
activesupport (~> 3.0)
|
||||
eventmachine (~> 1.0.0)
|
||||
haml (>= 3.1, < 5)
|
||||
mail (~> 2.3)
|
||||
sinatra (~> 1.2)
|
||||
skinny (~> 0.2.3)
|
||||
sqlite3 (~> 1.3)
|
||||
thin (~> 1.5.0)
|
||||
meta_search (1.1.3)
|
||||
actionpack (~> 3.1)
|
||||
activerecord (~> 3.1)
|
||||
activesupport (~> 3.1)
|
||||
polyamorous (~> 0.5.0)
|
||||
mime-types (1.19)
|
||||
multi_json (1.5.0)
|
||||
mime-types (1.21)
|
||||
mono_logger (1.1.0)
|
||||
multi_json (1.7.3)
|
||||
mysql2 (0.3.11)
|
||||
net-scp (1.1.1)
|
||||
net-ssh (>= 2.6.5)
|
||||
net-sftp (2.1.2)
|
||||
net-ssh (>= 2.6.5)
|
||||
net-ssh (2.6.7)
|
||||
net-ssh-gateway (1.2.0)
|
||||
net-ssh (>= 2.6.5)
|
||||
pdf-reader (1.2.0)
|
||||
Ascii85 (~> 1.0.0)
|
||||
hashery (~> 2.0)
|
||||
|
@ -126,43 +153,44 @@ GEM
|
|||
prawn (0.12.0)
|
||||
pdf-reader (>= 0.9.0)
|
||||
ttfunk (~> 1.0.2)
|
||||
rack (1.4.3)
|
||||
quiet_assets (1.0.2)
|
||||
railties (>= 3.1, < 5.0)
|
||||
rack (1.4.5)
|
||||
rack-cache (1.2)
|
||||
rack (>= 0.4)
|
||||
rack-protection (1.3.2)
|
||||
rack-protection (1.5.0)
|
||||
rack
|
||||
rack-ssl (1.3.2)
|
||||
rack-ssl (1.3.3)
|
||||
rack
|
||||
rack-test (0.6.2)
|
||||
rack (>= 1.0)
|
||||
rails (3.2.11)
|
||||
actionmailer (= 3.2.11)
|
||||
actionpack (= 3.2.11)
|
||||
activerecord (= 3.2.11)
|
||||
activeresource (= 3.2.11)
|
||||
activesupport (= 3.2.11)
|
||||
rails (3.2.13)
|
||||
actionmailer (= 3.2.13)
|
||||
actionpack (= 3.2.13)
|
||||
activerecord (= 3.2.13)
|
||||
activeresource (= 3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
bundler (~> 1.0)
|
||||
railties (= 3.2.11)
|
||||
rails3_acts_as_paranoid (0.2.4)
|
||||
activerecord (~> 3.2)
|
||||
railties (3.2.11)
|
||||
actionpack (= 3.2.11)
|
||||
activesupport (= 3.2.11)
|
||||
railties (= 3.2.13)
|
||||
railties (3.2.13)
|
||||
actionpack (= 3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
rack-ssl (~> 1.3.2)
|
||||
rake (>= 0.8.7)
|
||||
rdoc (~> 3.4)
|
||||
thor (>= 0.14.6, < 2.0)
|
||||
rake (10.0.3)
|
||||
rdoc (3.12)
|
||||
rdoc (3.12.2)
|
||||
json (~> 1.4)
|
||||
redis (3.0.2)
|
||||
redis-namespace (1.2.1)
|
||||
redis (3.0.4)
|
||||
redis-namespace (1.3.0)
|
||||
redis (~> 3.0.0)
|
||||
responders (0.9.3)
|
||||
railties (~> 3.1)
|
||||
resque (1.23.0)
|
||||
resque (1.24.1)
|
||||
mono_logger (~> 1.0)
|
||||
multi_json (~> 1.0)
|
||||
redis-namespace (~> 1.0)
|
||||
redis-namespace (~> 1.2)
|
||||
sinatra (>= 0.9.2)
|
||||
vegas (~> 0.1.2)
|
||||
ruby-prof (0.11.2)
|
||||
|
@ -179,10 +207,13 @@ GEM
|
|||
simple_form (2.0.3)
|
||||
actionpack (~> 3.0)
|
||||
activemodel (~> 3.0)
|
||||
sinatra (1.3.3)
|
||||
rack (~> 1.3, >= 1.3.6)
|
||||
rack-protection (~> 1.2)
|
||||
sinatra (1.3.6)
|
||||
rack (~> 1.4)
|
||||
rack-protection (~> 1.3)
|
||||
tilt (~> 1.3, >= 1.3.3)
|
||||
skinny (0.2.3)
|
||||
eventmachine (~> 1.0.0)
|
||||
thin (~> 1.5.0)
|
||||
sprockets (2.2.2)
|
||||
hike (~> 1.2)
|
||||
multi_json (~> 1.0)
|
||||
|
@ -192,8 +223,12 @@ GEM
|
|||
test-unit (2.5.3)
|
||||
therubyracer (0.10.2)
|
||||
libv8 (~> 3.3.10)
|
||||
thor (0.16.0)
|
||||
tilt (1.3.3)
|
||||
thin (1.5.1)
|
||||
daemons (>= 1.0.9)
|
||||
eventmachine (>= 0.12.6)
|
||||
rack (>= 1.0.0)
|
||||
thor (0.17.0)
|
||||
tilt (1.4.1)
|
||||
treetop (1.4.12)
|
||||
polyglot
|
||||
polyglot (>= 0.3.1)
|
||||
|
@ -203,7 +238,7 @@ GEM
|
|||
less-rails (~> 2.2.3)
|
||||
railties (>= 3.1)
|
||||
therubyracer (~> 0.10.2)
|
||||
tzinfo (0.3.35)
|
||||
tzinfo (0.3.37)
|
||||
uglifier (1.3.0)
|
||||
execjs (>= 0.3.0)
|
||||
multi_json (~> 1.0, >= 1.0.2)
|
||||
|
@ -227,6 +262,8 @@ DEPENDENCIES
|
|||
better_errors
|
||||
binding_of_caller
|
||||
bullet
|
||||
capistrano (= 2.13.5)
|
||||
capistrano-ext
|
||||
client_side_validations
|
||||
coffee-rails (~> 3.2.1)
|
||||
daemons
|
||||
|
@ -236,11 +273,12 @@ DEPENDENCIES
|
|||
jquery-rails
|
||||
kaminari
|
||||
localize_input!
|
||||
mailcatcher
|
||||
meta_search
|
||||
mysql2
|
||||
prawn
|
||||
quiet_assets
|
||||
rails (~> 3.2.9)
|
||||
rails3_acts_as_paranoid (~> 0.2.0)
|
||||
resque
|
||||
ruby-prof
|
||||
sass-rails (~> 3.2.3)
|
||||
|
@ -250,6 +288,7 @@ DEPENDENCIES
|
|||
sqlite3
|
||||
test-unit
|
||||
therubyracer
|
||||
thin
|
||||
twitter-bootstrap-rails
|
||||
uglifier (>= 1.0.3)
|
||||
whenever
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
MULTI_COOP_INSTALL
|
||||
------------------
|
||||
|
||||
TODO ...
|
|
@ -1,17 +1,22 @@
|
|||
== FoodSoft
|
||||
Important
|
||||
--------
|
||||
|
||||
We changed the branch structure. The rails3 branch is now master. But you can safely send pull requests to rails3. It'll remain there for a couple of weeks.
|
||||
|
||||
FoodSoft
|
||||
=========
|
||||
|
||||
Web-based software to manage a non-profit food coop (product catalog, ordering, accounting, job scheduling).
|
||||
|
||||
== Install
|
||||
More information about using this software and contributing can be found on the [wiki](https://github.com/foodcoops/foodsoft/wiki).
|
||||
|
||||
Have a look on README_DEVEL.
|
||||
Install
|
||||
--------
|
||||
|
||||
Update, it is highly recommended to checkout the rails3 branch. As soon as possible I will merge this branch
|
||||
into master. So for beginnners, better start with the new (I hope much easier) code.
|
||||
Have a look at [DEVELOPMENT](https://github.com/foodcoops/foodsoft/blob/master/doc/DEVELOPMENT) (possibly outdated) and the (more recent) [Developing](https://github.com/foodcoops/foodsoft/wiki/Developing) page on the wiki.
|
||||
|
||||
git checkout -b rails3 origin/rails3
|
||||
|
||||
== License
|
||||
License
|
||||
-------
|
||||
|
||||
FoodSoft - a webbased foodcoop management software
|
||||
Copyright (C) 2011 Benni and Lasse
|
||||
|
@ -26,4 +31,4 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
(See file LICENSE for the full text of the GPL)
|
||||
(See file LICENSE for the full text of the GPL)
|
|
@ -35,11 +35,14 @@ $(function() {
|
|||
|
||||
// Check/Uncheck all checkboxes for a specific form
|
||||
$('input[data-check-all]').live('click', function() {
|
||||
var status = $(this).is(':checked')
|
||||
$($(this).data('check-all')).find('input[type="checkbox"]').each(function() {
|
||||
$(this).attr('checked', status);
|
||||
highlightRow($(this));
|
||||
});
|
||||
var status = $(this).is(':checked');
|
||||
var context = $(this).data('check-all');
|
||||
var elms = $('input[type="checkbox"]', context);
|
||||
for(i=elms.length-1; i>=0; --i) { // performance can be an issue here, so use native loop
|
||||
var elm = elms[i];
|
||||
elm.checked = status;
|
||||
highlightRow($(elm));
|
||||
}
|
||||
});
|
||||
|
||||
// Submit form when changing a select menu.
|
||||
|
@ -102,7 +105,7 @@ $(function() {
|
|||
|
||||
// gives the row an yellow background
|
||||
function highlightRow(checkbox) {
|
||||
var row = checkbox.parents('tr');
|
||||
var row = checkbox.closest('tr');
|
||||
if (checkbox.is(':checked')) {
|
||||
row.addClass('selected');
|
||||
} else {
|
||||
|
|
|
@ -49,7 +49,7 @@ function addData(orderArticleId, itemPrice, itemUnit, itemSubtotal, itemQuantity
|
|||
|
||||
function increaseQuantity(item) {
|
||||
var value = Number($('#q_' + item).val()) + 1;
|
||||
if (!isStockit || (value <= (quantityAvailable[item] - quantityOthers[item]))) {
|
||||
if (!isStockit || (value <= (quantityAvailable[item] + itemsAllocated[item]))) {
|
||||
update(item, value, $('#t_' + item).val());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -200,3 +200,11 @@ tr.unavailable {
|
|||
border-color: red;
|
||||
}
|
||||
}
|
||||
|
||||
// ********* Tweaks & fixes
|
||||
|
||||
// need more space for supplier&order information (in German, at least)
|
||||
.dl-horizontal {
|
||||
dt { width: 160px; }
|
||||
dd { margin-left: 170px; }
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ class Admin::OrdergroupsController < Admin::BaseController
|
|||
inherit_resources
|
||||
|
||||
def index
|
||||
@ordergroups = Ordergroup.order('name ASC')
|
||||
@ordergroups = Ordergroup.undeleted.order('name ASC')
|
||||
|
||||
# if somebody uses the search field:
|
||||
unless params[:query].blank?
|
||||
|
@ -15,9 +15,9 @@ class Admin::OrdergroupsController < Admin::BaseController
|
|||
|
||||
def destroy
|
||||
@ordergroup = Ordergroup.find(params[:id])
|
||||
@ordergroup.destroy
|
||||
redirect_to admin_ordergroups_url, :notice => "Bestellgruppe wurde gelöscht"
|
||||
@ordergroup.mark_as_deleted
|
||||
redirect_to admin_ordergroups_url, notice: t('admin.ordergroups.destroy.notice')
|
||||
rescue => error
|
||||
redirect_to admin_ordergroups_url, :alert => "Bestellgruppe konnte nicht gelöscht werden: #{error}"
|
||||
redirect_to admin_ordergroups_url, alert: t('admin.ordergroups.destroy.error')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,8 +13,8 @@ class Admin::WorkgroupsController < Admin::BaseController
|
|||
def destroy
|
||||
@workgroup = Workgroup.find(params[:id])
|
||||
@workgroup.destroy
|
||||
redirect_to admin_workgroups_url, :notice => "Arbeitsgruppe wurde gelöscht"
|
||||
redirect_to admin_workgroups_url, notice: t('admin.workgroups.destroy.notice')
|
||||
rescue => error
|
||||
redirect_to admin_workgroups_url, :alert => "Arbeitsgruppe konnte nicht gelöscht werden: #{error}"
|
||||
redirect_to admin_workgroups_url, alert: t('admin.workgroups.destroy.error')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,17 +5,17 @@ class ArticleCategoriesController < ApplicationController
|
|||
before_filter :authenticate_article_meta
|
||||
|
||||
def create
|
||||
create!(:notice => "Die Kategorie wurde gespeichert") { article_categories_path }
|
||||
create!(:notice => I18n.t('article_categories.create.notice')) { article_categories_path }
|
||||
end
|
||||
|
||||
def update
|
||||
update!(:notice => "Die Kategorie wurde aktualisiert") { article_categories_path }
|
||||
update!(:notice => I18n.t('article_categories.update.notice')) { article_categories_path }
|
||||
end
|
||||
|
||||
def destroy
|
||||
destroy!
|
||||
rescue => error
|
||||
redirect_to article_categories_path, alert: t('controller.article_categories.destroy.error', message: error.message)
|
||||
redirect_to article_categories_path, alert: I18n.t('article_categories.destroy.error', message: error.message)
|
||||
end
|
||||
|
||||
protected
|
||||
|
|
|
@ -20,7 +20,7 @@ class ArticlesController < ApplicationController
|
|||
sort = "article_categories.name, articles.name"
|
||||
end
|
||||
|
||||
@articles = Article.where(supplier_id: @supplier, :type => nil).includes(:article_category).order(sort)
|
||||
@articles = Article.undeleted.where(supplier_id: @supplier, :type => nil).includes(:article_category).order(sort)
|
||||
@articles = @articles.where('articles.name LIKE ?', "%#{params[:query]}%") unless params[:query].nil?
|
||||
|
||||
@articles = @articles.page(params[:page]).per(@per_page)
|
||||
|
@ -64,22 +64,22 @@ class ArticlesController < ApplicationController
|
|||
# Deletes article from database. send error msg, if article is used in a current order
|
||||
def destroy
|
||||
@article = Article.find(params[:id])
|
||||
@article.destroy unless @order = @article.in_open_order # If article is in an active Order, the Order will be returned
|
||||
@article.mark_as_deleted unless @order = @article.in_open_order # If article is in an active Order, the Order will be returned
|
||||
render :layout => false
|
||||
end
|
||||
|
||||
# Renders a form for editing all articles from a supplier
|
||||
def edit_all
|
||||
@articles = @supplier.articles
|
||||
@articles = @supplier.articles.undeleted
|
||||
end
|
||||
|
||||
# Updates all article of specific supplier
|
||||
# deletes all articles from params[outlisted_articles]
|
||||
def update_all
|
||||
invalid_articles = false
|
||||
|
||||
begin
|
||||
Article.transaction do
|
||||
unless params[:articles].blank?
|
||||
invalid_articles = false
|
||||
# Update other article attributes...
|
||||
@articles = Article.find(params[:articles].keys)
|
||||
@articles.each do |article|
|
||||
|
@ -88,52 +88,46 @@ class ArticlesController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
raise "Artikel sind fehlerhaft. Bitte überprüfe Deine Eingaben." if invalid_articles
|
||||
end
|
||||
# delete articles
|
||||
if params[:outlisted_articles]
|
||||
params[:outlisted_articles].keys.each {|id| Article.find(id).destroy }
|
||||
raise ActiveRecord::Rollback if invalid_articles # Rollback all changes
|
||||
end
|
||||
end
|
||||
# Successfully done.
|
||||
redirect_to supplier_articles_path(@supplier), notice: "Alle Artikel und Preise wurden aktalisiert"
|
||||
end
|
||||
|
||||
rescue => e
|
||||
if invalid_articles
|
||||
# An error has occurred, transaction has been rolled back.
|
||||
if params[:sync]
|
||||
flash[:error] = "Es trat ein Fehler beim Aktualisieren des Artikels '#{current_article.name}' auf: #{e.message}"
|
||||
redirect_to(supplier_articles_path(@supplier))
|
||||
else
|
||||
flash.now.alert = e.message
|
||||
render :edit_all
|
||||
end
|
||||
flash.now.alert = I18n.t('articles.controller.error_invalid')
|
||||
render :edit_all
|
||||
else
|
||||
# Successfully done.
|
||||
redirect_to supplier_articles_path(@supplier), notice: I18n.t('articles.controller.update_all.notice')
|
||||
end
|
||||
end
|
||||
|
||||
# makes different actions on selected articles
|
||||
def update_selected
|
||||
raise 'Du hast keine Artikel ausgewählt' if params[:selected_articles].nil?
|
||||
raise I18n.t('articles.controller.error_nosel') if params[:selected_articles].nil?
|
||||
articles = Article.find(params[:selected_articles])
|
||||
|
||||
case params[:selected_action]
|
||||
when 'destroy'
|
||||
articles.each {|a| a.destroy }
|
||||
flash[:notice] = 'Alle gewählten Artikel wurden gelöscht'
|
||||
when 'setNotAvailable'
|
||||
articles.each {|a| a.update_attribute(:availability, false) }
|
||||
flash[:notice] = 'Alle gewählten Artikel wurden auf "nicht verfügbar" gesetzt'
|
||||
when 'setAvailable'
|
||||
articles.each {|a| a.update_attribute(:availability, true) }
|
||||
flash[:notice] = 'Alle gewählten Artikel wurden auf "verfügbar" gesetzt'
|
||||
else
|
||||
flash[:alert] = 'Keine Aktion ausgewählt!'
|
||||
Article.transaction do
|
||||
case params[:selected_action]
|
||||
when 'destroy'
|
||||
articles.each(&:mark_as_deleted)
|
||||
flash[:notice] = I18n.t('articles.controller.update_sel.notice_destroy')
|
||||
when 'setNotAvailable'
|
||||
articles.each {|a| a.update_attribute(:availability, false) }
|
||||
flash[:notice] = I18n.t('articles.controller.update_sel.notice_unavail')
|
||||
when 'setAvailable'
|
||||
articles.each {|a| a.update_attribute(:availability, true) }
|
||||
flash[:notice] = I18n.t('articles.controller.update_sel.notice_avail')
|
||||
else
|
||||
flash[:alert] = I18n.t('articles.controller.update_sel.notice_noaction')
|
||||
end
|
||||
end
|
||||
# action succeded
|
||||
redirect_to supplier_articles_url(@supplier, :per_page => params[:per_page])
|
||||
|
||||
|
||||
rescue => error
|
||||
redirect_to supplier_articles_url(@supplier, :per_page => params[:per_page]),
|
||||
:alert => "Ein Fehler ist aufgetreten: #{error}"
|
||||
:alert => I18n.t('errors.general_msg', :msg => error)
|
||||
end
|
||||
|
||||
# lets start with parsing articles from uploaded file, yeah
|
||||
|
@ -166,13 +160,13 @@ class ArticlesController < ApplicationController
|
|||
:tax => row[:tax])
|
||||
# stop parsing, when an article isn't valid
|
||||
unless article.valid?
|
||||
raise article.errors.full_messages.join(", ") + " ..in line " + (articles.index(row) + 2).to_s
|
||||
raise I18n.t('articles.controller.error_parse', :msg => article.errors.full_messages.join(", "), :line => (articles.index(row) + 2).to_s)
|
||||
end
|
||||
@articles << article
|
||||
end
|
||||
flash.now[:notice] = "#{@articles.size} articles are parsed successfully."
|
||||
flash.now[:notice] = I18n.t('articles.controller.parse_upload.notice', :count => @articles.size)
|
||||
rescue => error
|
||||
redirect_to upload_supplier_articles_path(@supplier), :alert => "An error has occurred: #{error.message}"
|
||||
redirect_to upload_supplier_articles_path(@supplier), :alert => I18n.t('errors.general_msg', :msg => error.message)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -187,14 +181,14 @@ class ArticlesController < ApplicationController
|
|||
invalid_articles = true unless article.save
|
||||
end
|
||||
|
||||
raise "Artikel sind fehlerhaft" if invalid_articles
|
||||
raise I18n.t('articles.controller.error_invalid') if invalid_articles
|
||||
end
|
||||
# Successfully done.
|
||||
redirect_to supplier_articles_path(@supplier), notice: "Es wurden #{@articles.size} neue Artikel gespeichert."
|
||||
redirect_to supplier_articles_path(@supplier), notice: I18n.t('articles.controller.create_from_upload.notice', :count => @articles.size)
|
||||
|
||||
rescue => error
|
||||
# An error has occurred, transaction has been rolled back.
|
||||
flash.now[:error] = "An error occured: #{error.message}"
|
||||
flash.now[:error] = I18n.t('errors.general_msg', :msg => error.message)
|
||||
render :parse_upload
|
||||
end
|
||||
end
|
||||
|
@ -221,14 +215,43 @@ class ArticlesController < ApplicationController
|
|||
def sync
|
||||
# check if there is an shared_supplier
|
||||
unless @supplier.shared_supplier
|
||||
redirect_to supplier_articles_url(@supplier), :alert => "#{@supplier.name} ist nicht mit einer externen Datenbank verknüpft."
|
||||
redirect_to supplier_articles_url(@supplier), :alert => I18n.t('articles.controller.sync.shared_alert', :supplier => @supplier.name)
|
||||
end
|
||||
# sync articles against external database
|
||||
@updated_articles, @outlisted_articles = @supplier.sync_all
|
||||
# convert to db-compatible-string
|
||||
@updated_articles.each {|a, b| a.shared_updated_on = a.shared_updated_on.to_formatted_s(:db)}
|
||||
if @updated_articles.empty? && @outlisted_articles.empty?
|
||||
redirect_to supplier_articles_path(@supplier), :notice => "Der Katalog ist aktuell."
|
||||
redirect_to supplier_articles_path(@supplier), :notice => I18n.t('articles.controller.sync.notice')
|
||||
end
|
||||
end
|
||||
|
||||
# Updates, deletes articles when sync form is submitted
|
||||
def update_synchronized
|
||||
begin
|
||||
Article.transaction do
|
||||
# delete articles
|
||||
if params[:outlisted_articles]
|
||||
Article.find(params[:outlisted_articles].keys).each(&:mark_as_deleted)
|
||||
end
|
||||
|
||||
# Update articles
|
||||
params[:articles].each do |id, attrs|
|
||||
Article.find(id).update_attributes! attrs
|
||||
end
|
||||
end
|
||||
|
||||
# Successfully done.
|
||||
redirect_to supplier_articles_path(@supplier), notice: I18n.t('articles.controller.update_sync.notice')
|
||||
|
||||
rescue ActiveRecord::RecordInvalid => invalid
|
||||
# An error has occurred, transaction has been rolled back.
|
||||
redirect_to supplier_articles_path(@supplier),
|
||||
alert: I18n.t('articles.controller.error_update', :article => invalid.record.name, :msg => invalid.record.errors.full_messages)
|
||||
|
||||
rescue => error
|
||||
redirect_to supplier_articles_path(@supplier),
|
||||
alert: I18n.t('errors.general_msg', :msg => error.message)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -35,7 +35,7 @@ class DeliveriesController < ApplicationController
|
|||
|
||||
respond_to do |format|
|
||||
if @delivery.save
|
||||
flash[:notice] = 'Lieferung wurde erstellt. Bitte nicht vergessen die Rechnung anzulegen!'
|
||||
flash[:notice] = I18n.t('deliveries.create.notice')
|
||||
format.html { redirect_to([@supplier,@delivery]) }
|
||||
format.xml { render :xml => @delivery, :status => :created, :location => @delivery }
|
||||
else
|
||||
|
@ -54,7 +54,7 @@ class DeliveriesController < ApplicationController
|
|||
|
||||
respond_to do |format|
|
||||
if @delivery.update_attributes(params[:delivery])
|
||||
flash[:notice] = 'Lieferung wurde aktualisiert.'
|
||||
flash[:notice] = I18n.t('deliveries.update.notice')
|
||||
format.html { redirect_to([@supplier,@delivery]) }
|
||||
format.xml { head :ok }
|
||||
else
|
||||
|
@ -68,7 +68,7 @@ class DeliveriesController < ApplicationController
|
|||
@delivery = Delivery.find(params[:id])
|
||||
@delivery.destroy
|
||||
|
||||
flash[:notice] = "Lieferung wurde gelöscht."
|
||||
flash[:notice] = I18n.t('deliveries.destroy.notice')
|
||||
respond_to do |format|
|
||||
format.html { redirect_to(supplier_deliveries_url(@supplier)) }
|
||||
format.xml { head :ok }
|
||||
|
|
|
@ -6,7 +6,7 @@ class FeedbackController < ApplicationController
|
|||
def create
|
||||
if params[:message].present?
|
||||
Mailer.feedback(current_user, params[:message]).deliver
|
||||
redirect_to root_url, :notice => "Das Feedback wurde erfolgreich verschickt. Vielen Dank!"
|
||||
redirect_to root_url, notice: t('feedback.create.notice')
|
||||
else
|
||||
render :action => 'new'
|
||||
end
|
||||
|
|
|
@ -7,10 +7,10 @@ class Finance::BalancingController < Finance::BaseController
|
|||
|
||||
def new
|
||||
@order = Order.find(params[:order_id])
|
||||
flash.now.alert = "Achtung, Bestellung wurde schon abgerechnet" if @order.closed?
|
||||
flash.now.alert = t('finance.balancing.new.alert') if @order.closed?
|
||||
@comments = @order.comments
|
||||
|
||||
@articles = @order.order_articles.ordered.includes(:order, :article_price,
|
||||
@articles = @order.order_articles.ordered.includes(:article, :article_price,
|
||||
group_order_articles: {group_order: :ordergroup})
|
||||
|
||||
sort_param = params['sort'] || 'name'
|
||||
|
@ -30,6 +30,10 @@ class Finance::BalancingController < Finance::BaseController
|
|||
render layout: false if request.xhr?
|
||||
end
|
||||
|
||||
def update_summary
|
||||
@order = Order.find(params[:id])
|
||||
end
|
||||
|
||||
def edit_note
|
||||
@order = Order.find(params[:id])
|
||||
render :layout => false
|
||||
|
@ -53,19 +57,19 @@ class Finance::BalancingController < Finance::BaseController
|
|||
def close
|
||||
@order = Order.find(params[:id])
|
||||
@order.close!(@current_user)
|
||||
redirect_to finance_root_url, notice: "Bestellung wurde erfolgreich abgerechnet, die Kontostände aktualisiert."
|
||||
redirect_to finance_order_index_url, notice: t('finance.balancing.close.notice')
|
||||
|
||||
rescue => error
|
||||
redirect_to new_finance_order_url(order_id: @order.id), alert: "Ein Fehler ist beim Abrechnen aufgetreten: #{error.message}"
|
||||
redirect_to new_finance_order_url(order_id: @order.id), alert: t('finance.balancing.close.alert', message: error.message)
|
||||
end
|
||||
|
||||
# Close the order directly, without automaticly updating ordergroups account balances
|
||||
def close_direct
|
||||
@order = Order.find(params[:id])
|
||||
@order.close_direct!(@current_user)
|
||||
redirect_to finance_balancing_url, notice: "Bestellung wurde geschlossen."
|
||||
redirect_to finance_order_index_url, notice: t('finance.balancing.close_direct.notice')
|
||||
rescue => error
|
||||
redirect_to finance_balancing_url, alert: "Bestellung kann nicht geschlossen werden: #{error.message}"
|
||||
redirect_to finance_order_index_url, alert: t('finance.balancing.close_direct.alert', message: error.message)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -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 => "Die Transaktion wurde gespeichert."
|
||||
redirect_to finance_ordergroup_transactions_url(@ordergroup), notice: t('finance.financial_transactions.create.notice')
|
||||
rescue ActiveRecord::RecordInvalid => error
|
||||
flash.now[:alert] = error.message
|
||||
render :action => :new
|
||||
|
@ -51,9 +51,9 @@ class Finance::FinancialTransactionsController < ApplicationController
|
|||
Ordergroup.find(trans[:ordergroup_id]).add_financial_transaction!(trans[:amount], params[:note], @current_user)
|
||||
end
|
||||
end
|
||||
redirect_to finance_ordergroups_url, notice: "Alle Transaktionen wurden gespeichert."
|
||||
redirect_to finance_ordergroups_url, notice: t('finance.create_collection.create.notice')
|
||||
rescue => error
|
||||
redirect_to finance_new_transaction_collection_url, alert: "Ein Fehler ist aufgetreten: " + error.to_s
|
||||
redirect_to finance_new_transaction_collection_url, alert: t('finance.create_collection.create.alert', error: error.to_s)
|
||||
end
|
||||
|
||||
protected
|
||||
|
|
|
@ -22,7 +22,7 @@ class Finance::InvoicesController < ApplicationController
|
|||
@invoice = Invoice.new(params[:invoice])
|
||||
|
||||
if @invoice.save
|
||||
flash[:notice] = "Rechnung wurde erstellt."
|
||||
flash[:notice] = I18n.t('finance.create.notice')
|
||||
if @invoice.order
|
||||
# Redirect to balancing page
|
||||
redirect_to new_finance_order_url(order_id: @invoice.order.id)
|
||||
|
@ -38,7 +38,7 @@ class Finance::InvoicesController < ApplicationController
|
|||
@invoice = Invoice.find(params[:id])
|
||||
|
||||
if @invoice.update_attributes(params[:invoice])
|
||||
redirect_to [:finance, @invoice], notice: "Rechnung wurde aktualisiert."
|
||||
redirect_to [:finance, @invoice], notice: I18n.t('finance.update.notice')
|
||||
else
|
||||
render :edit
|
||||
end
|
||||
|
|
|
@ -26,7 +26,7 @@ class Finance::OrderArticlesController < ApplicationController
|
|||
@order = Order.find(params[:order_id])
|
||||
@order_article = OrderArticle.find(params[:id])
|
||||
begin
|
||||
@order_article.update_article_and_price!(params[:article], params[:article_price], params[:order_article])
|
||||
@order_article.update_article_and_price!(params[:order_article], params[:article], params[:article_price])
|
||||
rescue
|
||||
render action: :edit
|
||||
end
|
||||
|
|
|
@ -12,7 +12,7 @@ class Finance::OrdergroupsController < Finance::BaseController
|
|||
sort = "name"
|
||||
end
|
||||
|
||||
@ordergroups = Ordergroup.order(sort)
|
||||
@ordergroups = Ordergroup.undeleted.order(sort)
|
||||
@ordergroups = @ordergroups.where('name LIKE ?', "%#{params[:query]}%") unless params[:query].nil?
|
||||
|
||||
@ordergroups = @ordergroups.page(params[:page]).per(@per_page)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class Foodcoop::OrdergroupsController < ApplicationController
|
||||
|
||||
def index
|
||||
@ordergroups = Ordergroup.order('name DESC')
|
||||
@ordergroups = Ordergroup.undeleted.order('name DESC')
|
||||
|
||||
unless params[:name].blank? # Search by name
|
||||
@ordergroups = @ordergroups.where('name LIKE ?', "%#{params[:name]}%")
|
||||
|
|
|
@ -14,7 +14,7 @@ class Foodcoop::WorkgroupsController < ApplicationController
|
|||
def update
|
||||
@workgroup = Workgroup.find(params[:id])
|
||||
if @workgroup.update_attributes(params[:workgroup])
|
||||
redirect_to foodcoop_workgroups_url, :notice => "Arbeitsgruppe wurde aktualisiert"
|
||||
redirect_to foodcoop_workgroups_url, :notice => I18n.t('workgroups.update.notice')
|
||||
else
|
||||
render :action => 'edit'
|
||||
end
|
||||
|
|
|
@ -20,12 +20,12 @@ class GroupOrdersController < ApplicationController
|
|||
@group_order = GroupOrder.new(params[:group_order])
|
||||
begin
|
||||
@group_order.save_ordering!
|
||||
redirect_to group_order_url(@group_order), :notice => 'Die Bestellung wurde gespeichert.'
|
||||
redirect_to group_order_url(@group_order), :notice => I18n.t('group_orders.create.notice')
|
||||
rescue ActiveRecord::StaleObjectError
|
||||
redirect_to group_orders_url, :alert => 'In der Zwischenzeit hat jemand anderes auch bestellt, daher konnte die Bestellung nicht aktualisiert werden.'
|
||||
redirect_to group_orders_url, :alert => I18n.t('group_orders.create.error_stale')
|
||||
rescue => exception
|
||||
logger.error('Failed to update order: ' + exception.message)
|
||||
redirect_to group_orders_url, :alert => 'Die Bestellung konnte nicht aktualisiert werden, da ein Fehler auftrat.'
|
||||
redirect_to group_orders_url, :alert => I18n.t('group_orders.create.error_general')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -41,12 +41,12 @@ class GroupOrdersController < ApplicationController
|
|||
@group_order.attributes = params[:group_order]
|
||||
begin
|
||||
@group_order.save_ordering!
|
||||
redirect_to group_order_url(@group_order), :notice => 'Die Bestellung wurde gespeichert.'
|
||||
redirect_to group_order_url(@group_order), :notice => I18n.t('group_orders.update.notice')
|
||||
rescue ActiveRecord::StaleObjectError
|
||||
redirect_to group_orders_url, :alert => 'In der Zwischenzeit hat jemand anderes auch bestellt, daher konnte die Bestellung nicht aktualisiert werden.'
|
||||
redirect_to group_orders_url, :alert => I18n.t('group_orders.update.error_stale')
|
||||
rescue => exception
|
||||
logger.error('Failed to update order: ' + exception.message)
|
||||
redirect_to group_orders_url, :alert => 'Die Bestellung konnte nicht aktualisiert werden, da ein Fehler auftrat.'
|
||||
redirect_to group_orders_url, :alert => I18n.t('group_orders.update.error_general')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -69,7 +69,7 @@ class GroupOrdersController < ApplicationController
|
|||
def ensure_ordergroup_member
|
||||
@ordergroup = @current_user.ordergroup
|
||||
if @ordergroup.nil?
|
||||
redirect_to root_url, :alert => "Du bist kein Mitglieder einer Bestellgruppe."
|
||||
redirect_to root_url, :alert => I18n.t('group_orders.errors.no_member')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -77,7 +77,7 @@ class GroupOrdersController < ApplicationController
|
|||
@order = Order.find((params[:order_id] || params[:group_order][:order_id]),
|
||||
:include => [:supplier, :order_articles])
|
||||
unless @order.open?
|
||||
flash[:notice] = 'Diese Bestellung ist bereits abgeschlossen.'
|
||||
flash[:notice] = I18n.t('group_orders.error_closed')
|
||||
redirect_to :action => 'index'
|
||||
end
|
||||
end
|
||||
|
@ -85,7 +85,7 @@ class GroupOrdersController < ApplicationController
|
|||
def ensure_my_group_order
|
||||
@group_order = @ordergroup.group_orders.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
redirect_to group_orders_url, alert: 'Fehlerhafte URL, das ist nicht Deine Bestellung.'
|
||||
redirect_to group_orders_url, alert: I18n.t('group_orders.errors.notfound')
|
||||
end
|
||||
|
||||
def enough_apples?
|
||||
|
|
|
@ -16,7 +16,7 @@ class HomeController < ApplicationController
|
|||
|
||||
def update_profile
|
||||
if @current_user.update_attributes(params[:user])
|
||||
redirect_to my_profile_url, notice: 'Änderungen wurden gespeichert.'
|
||||
redirect_to my_profile_url, notice: I18n.t('home.changes_saved')
|
||||
else
|
||||
render :profile
|
||||
end
|
||||
|
@ -45,7 +45,7 @@ class HomeController < ApplicationController
|
|||
@financial_transactions = @financial_transactions.where("note LIKE ?", "%#{params[:query]}%") if params[:query].present?
|
||||
|
||||
else
|
||||
redirect_to root_path, :alert => "Leider bist Du kein Mitglied einer Bestellgruppe"
|
||||
redirect_to root_path, :alert => I18n.t('home.no_ordergroups')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -54,9 +54,9 @@ class HomeController < ApplicationController
|
|||
membership = Membership.find(params[:membership_id])
|
||||
if membership.user == current_user
|
||||
membership.destroy
|
||||
flash[:notice] = "Du bist jetzt kein Mitglied der Gruppe #{membership.group.name} mehr."
|
||||
flash[:notice] = I18n.t('home.ordergroup_cancelled', :group => membership.group.name)
|
||||
else
|
||||
flash[:error] = "Ein Problem ist aufgetreten."
|
||||
flash[:error] = I18n.t('errors.general')
|
||||
end
|
||||
redirect_to my_profile_path
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class InvitesController < ApplicationController
|
||||
|
||||
before_filter :authenticate_membership_or_admin, :only => [:new]
|
||||
#TODO: auhtorize also for create action.
|
||||
#TODO: authorize also for create action.
|
||||
|
||||
def new
|
||||
@invite = Invite.new(:user => @current_user, :group => @group)
|
||||
|
@ -14,7 +14,7 @@ class InvitesController < ApplicationController
|
|||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
redirect_to back_or_default_path, notice: "Benutzerin wurde erfolgreich eingeladen."
|
||||
redirect_to back_or_default_path, notice: I18n.t('invites.success')
|
||||
end
|
||||
format.js { render layout: false }
|
||||
end
|
||||
|
|
|
@ -10,6 +10,10 @@ 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
|
||||
end
|
||||
|
||||
if (user = User.find_by_email(params[:user][:email]))
|
||||
user.reset_password_token = user.new_random_password(16)
|
||||
user.reset_password_expires = Time.now.advance(:days => 2)
|
||||
|
@ -18,7 +22,7 @@ class LoginController < ApplicationController
|
|||
logger.debug("Sent password reset email to #{user.email}.")
|
||||
end
|
||||
end
|
||||
redirect_to login_url, :notice => "Wenn Deine E-Mail hier registiert ist bekommst Du jetzt eine Nachricht mit einem Passwort-Zurücksetzen-Link."
|
||||
redirect_to login_url, :notice => I18n.t('login.controller.reset_password.notice')
|
||||
end
|
||||
|
||||
# Set a new password with a token from the password reminder email.
|
||||
|
@ -34,7 +38,7 @@ class LoginController < ApplicationController
|
|||
@user.reset_password_token = nil
|
||||
@user.reset_password_expires = nil
|
||||
@user.save
|
||||
redirect_to login_url, :notice => "Dein Passwort wurde aktualisiert. Du kannst Dich jetzt anmelden."
|
||||
redirect_to login_url, :notice => I18n.t('login.controller.update_password.notice')
|
||||
else
|
||||
render :new_password
|
||||
end
|
||||
|
@ -43,27 +47,23 @@ class LoginController < ApplicationController
|
|||
# For invited users.
|
||||
def accept_invitation
|
||||
@invite = Invite.find_by_token(params[:token])
|
||||
if (@invite.nil? || @invite.expires_at < Time.now)
|
||||
flash[:error] = "Deine Einladung ist nicht (mehr) gültig."
|
||||
render :action => 'login'
|
||||
if @invite.nil? || @invite.expires_at < Time.now
|
||||
redirect_to login_url, alert: I18n.t('login.controller.error_invite_invalid')
|
||||
elsif @invite.group.nil?
|
||||
flash[:error] = "Die Gruppe, in die Du eingeladen wurdest, existiert leider nicht mehr."
|
||||
render :action => 'login'
|
||||
elsif (request.post?)
|
||||
redirect_to login_url, alert: I18n.t('login.controller.error_group_invalid')
|
||||
elsif request.post?
|
||||
User.transaction do
|
||||
@user = User.new(params[:user])
|
||||
@user.email = @invite.email
|
||||
if @user.save
|
||||
Membership.new(:user => @user, :group => @invite.group).save!
|
||||
@invite.destroy
|
||||
redirect_to login_url, notice: "Herzlichen Glückwunsch, Dein Account wurde erstellt. Du kannst Dich nun einloggen."
|
||||
redirect_to login_url, notice: I18n.t('login.controller.accept_invitation.notice')
|
||||
end
|
||||
end
|
||||
else
|
||||
@user = User.new(:email => @invite.email)
|
||||
end
|
||||
rescue
|
||||
flash[:error] = "Ein Fehler ist aufgetreten. Bitte erneut versuchen."
|
||||
end
|
||||
|
||||
protected
|
||||
|
@ -71,8 +71,7 @@ class LoginController < ApplicationController
|
|||
def validate_token
|
||||
@user = User.find_by_id_and_reset_password_token(params[:id], params[:token])
|
||||
if (@user.nil? || @user.reset_password_expires < Time.now)
|
||||
flash.now.error = "Ungültiger oder abgelaufener Token. Bitte versuch es erneut."
|
||||
render :action => 'forgot_password'
|
||||
redirect_to forgot_password_url, alert: I18n.t('login.controller.error_token_invalid')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,6 +8,9 @@ class MessagesController < ApplicationController
|
|||
# Creates a new message object.
|
||||
def new
|
||||
@message = Message.new(params[:message])
|
||||
if @message.reply_to and not @message.reply_to.is_readable_for?(current_user)
|
||||
redirect_to new_message_url, alert: 'Nachricht ist privat!'
|
||||
end
|
||||
end
|
||||
|
||||
# Creates a new message.
|
||||
|
@ -15,7 +18,7 @@ class MessagesController < ApplicationController
|
|||
@message = @current_user.send_messages.new(params[:message])
|
||||
if @message.save
|
||||
Resque.enqueue(UserNotifier, FoodsoftConfig.scope, 'message_deliver', @message.id)
|
||||
redirect_to messages_url, :notice => "Nachricht ist gespeichert und wird versendet."
|
||||
redirect_to messages_url, :notice => I18n.t('messages.create.notice')
|
||||
else
|
||||
render :action => 'new'
|
||||
end
|
||||
|
@ -24,5 +27,8 @@ class MessagesController < ApplicationController
|
|||
# Shows a single message.
|
||||
def show
|
||||
@message = Message.find(params[:id])
|
||||
unless @message.is_readable_for?(current_user)
|
||||
redirect_to messages_url, alert: 'Nachricht ist privat!'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -62,7 +62,7 @@ class OrdersController < ApplicationController
|
|||
@order = Order.new(params[:order])
|
||||
@order.created_by = current_user
|
||||
if @order.save
|
||||
flash[:notice] = "Die Bestellung wurde erstellt."
|
||||
flash[:notice] = I18n.t('orders.create.notice')
|
||||
redirect_to @order
|
||||
else
|
||||
logger.debug "[debug] order errors: #{@order.errors.messages}"
|
||||
|
@ -80,7 +80,7 @@ class OrdersController < ApplicationController
|
|||
def update
|
||||
@order = Order.find params[:id]
|
||||
if @order.update_attributes params[:order]
|
||||
flash[:notice] = "Die Bestellung wurde aktualisiert."
|
||||
flash[:notice] = I18n.t('orders.update.notice')
|
||||
redirect_to :action => 'show', :id => @order
|
||||
else
|
||||
render :action => 'edit'
|
||||
|
@ -97,7 +97,7 @@ class OrdersController < ApplicationController
|
|||
def finish
|
||||
order = Order.find(params[:id])
|
||||
order.finish!(@current_user)
|
||||
redirect_to order, notice: "Die Bestellung wurde beendet."
|
||||
redirect_to order, notice: I18n.t('orders.finish.notice')
|
||||
end
|
||||
|
||||
# Renders the fax-text-file
|
||||
|
@ -106,14 +106,14 @@ class OrdersController < ApplicationController
|
|||
order = Order.find(params[:id])
|
||||
supplier = order.supplier
|
||||
contact = FoodsoftConfig[:contact].symbolize_keys
|
||||
text = "Bestellung für" + " #{FoodsoftConfig[:name]}"
|
||||
text += "\n" + "Kundennummer" + ": #{supplier.customer_number}" unless supplier.customer_number.blank?
|
||||
text += "\n" + "Liefertag" + ": "
|
||||
text += "\n\n#{supplier.name}\n#{supplier.address}\nFAX: #{supplier.fax}\n\n"
|
||||
text += "****** " + "Versandadresse" + "\n\n"
|
||||
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" + 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 += "****** " + I18n.t('orders.fax.to_address') + "\n\n"
|
||||
text += "#{FoodsoftConfig[:name]}\n#{contact[:street]}\n#{contact[:zip_code]} #{contact[:city]}\n\n"
|
||||
text += "****** " + "Artikel" + "\n\n"
|
||||
text += "Nummer" + " " + "Menge" + " " + "Name" + "\n"
|
||||
text += "****** " + I18n.t('orders.fax.articles') + "\n\n"
|
||||
text += I18n.t('orders.fax.number') + " " + I18n.t('orders.fax.amount') + " " + I18n.t('orders.fax.name') + "\n"
|
||||
# now display all ordered articles
|
||||
order.order_articles.ordered.all(:include => [:article, :article_price]).each do |oa|
|
||||
number = oa.article.order_number
|
||||
|
|
|
@ -17,7 +17,7 @@ class PagesController < ApplicationController
|
|||
elsif params[:id]
|
||||
page = Page.find_by_id(params[:id])
|
||||
if page.nil?
|
||||
flash[:error] = "Seite existiert nicht!"
|
||||
flash[:error] = I18n.t('pages.cshow.error_noexist')
|
||||
redirect_to all_pages_path and return
|
||||
else
|
||||
redirect_to wiki_page_path(page.permalink) and return
|
||||
|
@ -29,7 +29,7 @@ class PagesController < ApplicationController
|
|||
elsif @page.redirect?
|
||||
page = Page.find_by_id(@page.redirect)
|
||||
unless page.nil?
|
||||
flash[:notice] = "Weitergeleitet von #{@page.title} ..."
|
||||
flash[:notice] = I18n.t('pages.cshow.redirect_notice', :page => @page.title)
|
||||
redirect_to wiki_page_path(page.permalink)
|
||||
end
|
||||
end
|
||||
|
@ -57,7 +57,7 @@ class PagesController < ApplicationController
|
|||
render :action => 'new'
|
||||
else
|
||||
if @page.save
|
||||
flash[:notice] = 'Seite wurde angelegt.'
|
||||
flash[:notice] = I18n.t('pages.create.notice')
|
||||
redirect_to(wiki_page_path(@page.permalink))
|
||||
else
|
||||
render :action => "new"
|
||||
|
@ -76,7 +76,7 @@ class PagesController < ApplicationController
|
|||
if @page.save
|
||||
@page.parent_id = parent_id if (!params[:parent_id].blank? \
|
||||
and params[:parent_id] != @page_id)
|
||||
flash[:notice] = 'Seite wurde aktualisiert.'
|
||||
flash[:notice] = I18n.t('pages.update.notice')
|
||||
redirect_to wiki_page_path(@page.permalink)
|
||||
else
|
||||
render :action => "edit"
|
||||
|
@ -84,7 +84,7 @@ class PagesController < ApplicationController
|
|||
end
|
||||
|
||||
rescue ActiveRecord::StaleObjectError
|
||||
flash[:error] = "Achtung, die Seite wurde gerade von jemand anderes bearbeitet. Bitte versuche es erneut."
|
||||
flash[:error] = I18n.t('pages.error_stale_object')
|
||||
redirect_to wiki_page_path(@page.permalink)
|
||||
end
|
||||
|
||||
|
@ -92,7 +92,7 @@ class PagesController < ApplicationController
|
|||
@page = Page.find(params[:id])
|
||||
@page.destroy
|
||||
|
||||
flash[:notice] = "Die Seite '#{@page.title}' und alle Unterseiten wurden erfolgreich gelöscht."
|
||||
flash[:notice] = I18n.t('pages.destroy.notice', :page => @page.title)
|
||||
redirect_to wiki_path
|
||||
end
|
||||
|
||||
|
|
|
@ -17,15 +17,15 @@ class SessionsController < ApplicationController
|
|||
else
|
||||
redirect_to_url = root_url
|
||||
end
|
||||
redirect_to redirect_to_url, :notice => "Logged in!"
|
||||
redirect_to redirect_to_url, :notice => I18n.t('sessions.logged_in')
|
||||
else
|
||||
flash.now.alert = "Invalid email or password"
|
||||
flash.now.alert = I18n.t('sessions.login_invalid')
|
||||
render "new"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
session[:user_id] = nil
|
||||
redirect_to login_url, :notice => "Logged out!"
|
||||
redirect_to login_url, :notice => I18n.t('sessions.logged_out')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,15 +7,15 @@ class StockTakingsController < ApplicationController
|
|||
|
||||
def new
|
||||
@stock_taking = StockTaking.new
|
||||
StockArticle.all.each { |a| @stock_taking.stock_changes.build(:stock_article => a) }
|
||||
StockArticle.undeleted.each { |a| @stock_taking.stock_changes.build(:stock_article => a) }
|
||||
end
|
||||
|
||||
def create
|
||||
create!(:notice => "Inventur wurde erfolgreich angelegt.")
|
||||
create!(:notice => I18n.t('stock_takings.create.notice'))
|
||||
end
|
||||
|
||||
def update
|
||||
update!(:notice => "Inventur wurde aktualisiert.")
|
||||
update!(:notice => I18n.t('stock_takings.update.notice'))
|
||||
end
|
||||
|
||||
def fill_new_stock_article_form
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class StockitController < ApplicationController
|
||||
|
||||
def index
|
||||
@stock_articles = StockArticle.includes(:supplier, :article_category).
|
||||
@stock_articles = StockArticle.undeleted.includes(:supplier, :article_category).
|
||||
order('suppliers.name, article_categories.name, articles.name')
|
||||
end
|
||||
|
||||
|
@ -12,7 +12,7 @@ class StockitController < ApplicationController
|
|||
def create
|
||||
@stock_article = StockArticle.new(params[:stock_article])
|
||||
if @stock_article.save
|
||||
redirect_to stock_articles_path, :notice => "Lagerartikel wurde gespeichert."
|
||||
redirect_to stock_articles_path, :notice => I18n.t('stockit.stock_create.notice')
|
||||
else
|
||||
render :action => 'new'
|
||||
end
|
||||
|
@ -25,7 +25,7 @@ class StockitController < ApplicationController
|
|||
def update
|
||||
@stock_article = StockArticle.find(params[:id])
|
||||
if @stock_article.update_attributes(params[:stock_article])
|
||||
redirect_to stock_articles_path, :notice => "Lagerartikel wurde gespeichert."
|
||||
redirect_to stock_articles_path, :notice => I18n.t('stockit.stock_update.notice')
|
||||
else
|
||||
render :action => 'edit'
|
||||
end
|
||||
|
@ -33,11 +33,11 @@ class StockitController < ApplicationController
|
|||
|
||||
def destroy
|
||||
@article = StockArticle.find(params[:id])
|
||||
@article.destroy
|
||||
@article.mark_as_deleted
|
||||
render :layout => false
|
||||
rescue => error
|
||||
render :partial => "destroy_fail", :layout => false,
|
||||
:locals => { :fail_msg => "Ein Fehler ist aufgetreten: " + error.message }
|
||||
:locals => { :fail_msg => I18n.t('errors.general_msg', :msg => error.message) }
|
||||
end
|
||||
|
||||
#TODO: Fix this!!
|
||||
|
|
|
@ -4,7 +4,7 @@ class SuppliersController < ApplicationController
|
|||
helper :deliveries
|
||||
|
||||
def index
|
||||
@suppliers = Supplier.order(:name)
|
||||
@suppliers = Supplier.undeleted.order(:name)
|
||||
@deliveries = Delivery.recent
|
||||
end
|
||||
|
||||
|
@ -18,7 +18,7 @@ class SuppliersController < ApplicationController
|
|||
def new
|
||||
if params[:shared_supplier_id]
|
||||
shared_supplier = SharedSupplier.find(params[:shared_supplier_id])
|
||||
@supplier = shared_supplier.build_supplier(shared_supplier.attributes)
|
||||
@supplier = shared_supplier.build_supplier(shared_supplier.autofill_attributes)
|
||||
else
|
||||
@supplier = Supplier.new
|
||||
end
|
||||
|
@ -27,7 +27,7 @@ class SuppliersController < ApplicationController
|
|||
def create
|
||||
@supplier = Supplier.new(params[:supplier])
|
||||
if @supplier.save
|
||||
flash[:notice] = "Lieferant wurde erstellt"
|
||||
flash[:notice] = I18n.t('suppliers.create.notice')
|
||||
redirect_to suppliers_path
|
||||
else
|
||||
render :action => 'new'
|
||||
|
@ -41,7 +41,7 @@ class SuppliersController < ApplicationController
|
|||
def update
|
||||
@supplier = Supplier.find(params[:id])
|
||||
if @supplier.update_attributes(params[:supplier])
|
||||
flash[:notice] = 'Lieferant wurde aktualisiert'
|
||||
flash[:notice] = I18n.t('suppliers.update.notice')
|
||||
redirect_to @supplier
|
||||
else
|
||||
render :action => 'edit'
|
||||
|
@ -50,11 +50,11 @@ class SuppliersController < ApplicationController
|
|||
|
||||
def destroy
|
||||
@supplier = Supplier.find(params[:id])
|
||||
@supplier.destroy
|
||||
flash[:notice] = "Lieferant wurde gelöscht"
|
||||
@supplier.mark_as_deleted
|
||||
flash[:notice] = I18n.t('suppliers.destroy.notice')
|
||||
redirect_to suppliers_path
|
||||
rescue => e
|
||||
flash[:error] = "Ein Fehler ist aufgetreten: " + e.message
|
||||
flash[:error] = I18n.t('errors.general_msg', :msg => e.message)
|
||||
redirect_to @supplier
|
||||
end
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ class TasksController < ApplicationController
|
|||
def create
|
||||
@task = Task.new(params[:task])
|
||||
if @task.save
|
||||
redirect_to tasks_url, :notice => "Aufgabe wurde erstellt"
|
||||
redirect_to tasks_url, :notice => I18n.t('tasks.create.notice')
|
||||
else
|
||||
render :template => "tasks/new"
|
||||
end
|
||||
|
@ -38,7 +38,7 @@ class TasksController < ApplicationController
|
|||
@task = Task.find(params[:id])
|
||||
@task.attributes=(params[:task])
|
||||
if @task.errors.empty? && @task.save
|
||||
flash[:notice] = "Aufgabe wurde aktualisiert"
|
||||
flash[:notice] = I18n.t('tasks.update.notice')
|
||||
if @task.workgroup
|
||||
redirect_to workgroup_tasks_url(workgroup_id: @task.workgroup_id)
|
||||
else
|
||||
|
@ -56,7 +56,7 @@ class TasksController < ApplicationController
|
|||
task.destroy
|
||||
task.update_ordergroup_stats(user_ids)
|
||||
|
||||
redirect_to tasks_url, :notice => "Aufgabe wurde gelöscht"
|
||||
redirect_to tasks_url, :notice => I18n.t('tasks.destroy.notice')
|
||||
end
|
||||
|
||||
# assign current_user to the task and set the assignment to "accepted"
|
||||
|
@ -68,7 +68,7 @@ class TasksController < ApplicationController
|
|||
else
|
||||
task.assignments.create(:user => current_user, :accepted => true)
|
||||
end
|
||||
redirect_to user_tasks_path, :notice => "Du hast die Aufgabe übernommen"
|
||||
redirect_to user_tasks_path, :notice => I18n.t('tasks.accept.notice')
|
||||
end
|
||||
|
||||
# deletes assignment between current_user and given task
|
||||
|
@ -79,7 +79,7 @@ class TasksController < ApplicationController
|
|||
|
||||
def set_done
|
||||
Task.find(params[:id]).update_attribute :done, true
|
||||
redirect_to tasks_url, :notice => "Aufgabenstatus wurde aktualisiert"
|
||||
redirect_to tasks_url, :notice => I18n.t('tasks.set_done.notice')
|
||||
end
|
||||
|
||||
# Shows all tasks, which are already done
|
||||
|
@ -91,7 +91,7 @@ class TasksController < ApplicationController
|
|||
def workgroup
|
||||
@group = Group.find(params[:workgroup_id])
|
||||
if @group.is_a? Ordergroup
|
||||
redirect_to tasks_url, :alert => "Keine Arbeitsgruppe gefunden"
|
||||
redirect_to tasks_url, :alert => I18n.t('tasks.error_not_found')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,11 +2,12 @@
|
|||
class OrderByArticles < OrderPdf
|
||||
|
||||
def filename
|
||||
"Bestellung #{@order.name}-#{@order.ends.to_date} - Artikelsortierung.pdf"
|
||||
I18n.t('documents.order_by_articles.filename', :name => @order.name, :date => @order.ends.to_date) + '.pdf'
|
||||
end
|
||||
|
||||
def title
|
||||
"Artikelsortierung der Bestellung: #{@order.name}, beendet am #{@order.ends.strftime('%d.%m.%Y')}"
|
||||
I18n.t('documents.order_by_articles.title', :name => @order.name,
|
||||
:date => @order.ends.strftime(I18n.t('date.formats.default')))
|
||||
end
|
||||
|
||||
def body
|
||||
|
@ -14,7 +15,7 @@ class OrderByArticles < OrderPdf
|
|||
text "#{order_article.article.name} (#{order_article.article.unit} | #{order_article.price.unit_quantity.to_s} | #{number_with_precision(order_article.price.fc_price, precision: 2)})",
|
||||
style: :bold, size: 10
|
||||
rows = []
|
||||
rows << %w(Bestellgruppe Menge Preis)
|
||||
rows << I18n.t('documents.order_by_articles.rows')
|
||||
for goa in order_article.group_order_articles
|
||||
rows << [goa.group_order.ordergroup.name,
|
||||
goa.result,
|
||||
|
@ -30,4 +31,4 @@ class OrderByArticles < OrderPdf
|
|||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,11 +2,12 @@
|
|||
class OrderByGroups < OrderPdf
|
||||
|
||||
def filename
|
||||
"Bestellung #{@order.name}-#{@order.ends.to_date} - Gruppensortierung.pdf"
|
||||
I18n.t('documents.order_by_groups.filename', :name => @order.name, :date => @order.ends.to_date) + '.pdf'
|
||||
end
|
||||
|
||||
def title
|
||||
"Gruppensortierung der Bestellung: #{@order.name}, beendet am #{@order.ends.strftime('%d.%m.%Y')}"
|
||||
I18n.t('documents.order_by_groups.title', :name => @order.name,
|
||||
:date => @order.ends.strftime(I18n.t('date.formats.default')))
|
||||
end
|
||||
|
||||
def body
|
||||
|
@ -16,7 +17,7 @@ class OrderByGroups < OrderPdf
|
|||
|
||||
total = 0
|
||||
rows = []
|
||||
rows << %w(Artikel Menge Preis GebGr Einheit Summe) # Table Header
|
||||
rows << I18n.t('documents.order_by_groups.rows') # Table Header
|
||||
|
||||
group_order_articles = group_order.group_order_articles.ordered
|
||||
group_order_articles.each do |goa|
|
||||
|
@ -30,7 +31,7 @@ class OrderByGroups < OrderPdf
|
|||
goa.order_article.article.unit,
|
||||
number_with_precision(sub_total, precision: 2)]
|
||||
end
|
||||
rows << [ "Summe", nil, nil, nil, nil, number_with_precision(total, precision: 2)]
|
||||
rows << [ I18n.t('documents.order_by_groups.sum'), nil, nil, nil, nil, number_with_precision(total, precision: 2)]
|
||||
|
||||
table rows, column_widths: [250,50,50,50,50,50], cell_style: {size: 8, overflow: :shrink_to_fit} do |table|
|
||||
# borders
|
||||
|
@ -48,4 +49,4 @@ class OrderByGroups < OrderPdf
|
|||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
class OrderFax < OrderPdf
|
||||
|
||||
def filename
|
||||
"Bestellung #{@order.name}-#{@order.ends.to_date} - Fax.pdf"
|
||||
I18n.t('documents.order_fax.filename', :name => @order.name, :date => @order.ends.to_date) + '.pdf'
|
||||
end
|
||||
|
||||
def title
|
||||
|
@ -14,42 +14,40 @@ class OrderFax < OrderPdf
|
|||
|
||||
# From paragraph
|
||||
bounding_box [margin_box.right-200,margin_box.top], width: 200 do
|
||||
text FoodsoftConfig[:name], align: :right
|
||||
text FoodsoftConfig[:name], size: 9, align: :right
|
||||
move_down 5
|
||||
text contact[:street], align: :right
|
||||
text contact[:street], size: 9, align: :right
|
||||
move_down 5
|
||||
text "#{contact[:zip_code]} #{contact[:city]}", align: :right
|
||||
text "#{contact[:zip_code]} #{contact[:city]}", size: 9, align: :right
|
||||
move_down 5
|
||||
if @order.supplier.customer_number != ''
|
||||
text "Kundennummer: #{@order.supplier.customer_number}", align: :right
|
||||
end
|
||||
move_down 10
|
||||
text contact[:phone], size: 9, align: :right
|
||||
text "#{I18n.t('simple_form.labels.supplier.customer_number')}: #{@order.supplier.try(:customer_number)}", size: 9, align: :right
|
||||
move_down 5
|
||||
text contact[:email], size: 9, align: :right
|
||||
text "#{I18n.t('simple_form.labels.supplier.phone')}: #{contact[:phone]}", size: 9, align: :right
|
||||
move_down 5
|
||||
text "#{I18n.t('simple_form.labels.supplier.email')}: #{contact[:email]}", size: 9, align: :right
|
||||
end
|
||||
|
||||
# Recipient
|
||||
bounding_box [margin_box.left,margin_box.top-60], width: 200 do
|
||||
text @order.name
|
||||
move_down 5
|
||||
text @order.supplier.address
|
||||
text @order.supplier.try(:address).to_s
|
||||
move_down 5
|
||||
text "Fax: " + @order.supplier.fax
|
||||
text "#{I18n.t('simple_form.labels.supplier.fax')}: #{@order.supplier.try(:fax)}"
|
||||
end
|
||||
|
||||
move_down 5
|
||||
text Date.today.strftime('%d.%m.%Y'), align: :right
|
||||
text Date.today.strftime(I18n.t('date.formats.default')), align: :right
|
||||
|
||||
move_down 10
|
||||
text "Lieferdatum:"
|
||||
text "#{I18n.t('simple_form.labels.delivery.delivered_on')}:"
|
||||
move_down 10
|
||||
text "Ansprechpartner: " + @order.supplier.contact_person
|
||||
text "#{I18n.t('simple_form.labels.supplier.contact_person')}: #{@order.supplier.try(:contact_person)}"
|
||||
move_down 10
|
||||
|
||||
# Articles
|
||||
data = [["BestellNr.", "Menge","Name", "Gebinde", "Einheit","Preis/Einheit"]]
|
||||
data = @order.order_articles.ordered.all(include: :article).collect do |a|
|
||||
data = [I18n.t('documents.order_fax.rows')]
|
||||
data += @order.order_articles.ordered.all(include: :article).collect do |a|
|
||||
[a.article.order_number,
|
||||
a.units_to_order,
|
||||
a.article.name,
|
||||
|
|
|
@ -4,22 +4,23 @@ class OrderMatrix < OrderPdf
|
|||
MAX_ARTICLES_PER_PAGE = 16 # How many order_articles shoud written on a page
|
||||
|
||||
def filename
|
||||
"Bestellung #{@order.name}-#{@order.ends.to_date} - Sortiermatrix.pdf"
|
||||
I18n.t('documents.order_matrix.filename', :name => @order.name, :date => @order.ends.to_date) + '.pdf'
|
||||
end
|
||||
|
||||
def title
|
||||
"Sortiermatrix der Bestellung: #{@order.name}, beendet am #{@order.ends.strftime('%d.%m.%Y')}"
|
||||
I18n.t('documents.order_matrix.title', :name => @order.name,
|
||||
:date => @order.ends.strftime(I18n.t('date.formats.default')))
|
||||
end
|
||||
|
||||
def body
|
||||
order_articles = @order.order_articles.ordered
|
||||
|
||||
text "Artikelübersicht", style: :bold
|
||||
text I18n.t('documents.order_matrix.heading'), style: :bold
|
||||
move_down 5
|
||||
text "Insgesamt #{order_articles.size} Artikel", size: 8
|
||||
text I18n.t('documents.order_matrix.total', :count => order_articles.size), size: 8
|
||||
move_down 10
|
||||
|
||||
order_articles_data = [%w(Artikel Einheit Gebinde FC-Preis Menge)]
|
||||
order_articles_data = [I18n.t('documents.order_matrix.rows')]
|
||||
|
||||
order_articles.each do |a|
|
||||
order_articles_data << [a.article.name,
|
||||
|
@ -83,4 +84,4 @@ class OrderMatrix < OrderPdf
|
|||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -58,7 +58,7 @@ module ApplicationHelper
|
|||
nil
|
||||
end
|
||||
html_options = {
|
||||
:title => "Nach #{text} sortieren",
|
||||
:title => I18n.t('helpers.application.sort_by', text: text),
|
||||
:remote => remote,
|
||||
:class => class_name
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ module ApplicationHelper
|
|||
|
||||
# Returns the weekday. 0 is sunday, 1 is monday and so on
|
||||
def weekday(dayNumber)
|
||||
weekdays = ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"]
|
||||
weekdays = I18n.t('date.day_names')
|
||||
return weekdays[dayNumber]
|
||||
end
|
||||
|
||||
|
@ -103,9 +103,9 @@ module ApplicationHelper
|
|||
|
||||
def icon(name, options={})
|
||||
icons = {
|
||||
:delete => { :file => 'b_drop.png', :alt => 'Löschen'},
|
||||
:edit => { :file => 'b_edit.png', :alt => 'Bearbeiten'},
|
||||
:members => { :file => 'b_users.png', :alt => 'Mitlglieder bearbeiten'}
|
||||
:delete => { :file => 'b_drop.png', :alt => I18n.t('ui.delete')},
|
||||
:edit => { :file => 'b_edit.png', :alt => I18n.t('ui.edit')},
|
||||
:members => { :file => 'b_users.png', :alt => I18n.t('helpers.application.edit_user')}
|
||||
}
|
||||
options[:alt] ||= icons[name][:alt]
|
||||
options[:title] ||= icons[name][:title]
|
||||
|
@ -126,16 +126,16 @@ module ApplicationHelper
|
|||
|
||||
def format_roles(record)
|
||||
roles = []
|
||||
roles << 'Admin' if record.role_admin?
|
||||
roles << 'Finanzen' if record.role_finance?
|
||||
roles << 'Lieferanten' if record.role_suppliers?
|
||||
roles << 'Artikel' if record.role_article_meta?
|
||||
roles << 'Bestellung' if record.role_orders?
|
||||
roles << I18n.t('helpers.application.role_admin') if record.role_admin?
|
||||
roles << I18n.t('helpers.application.role_finance') if record.role_finance?
|
||||
roles << I18n.t('helpers.application.role_suppliers') if record.role_suppliers?
|
||||
roles << I18n.t('helpers.application.role_article_meta') if record.role_article_meta?
|
||||
roles << I18n.t('helpers.application.role_orders') if record.role_orders?
|
||||
roles.join(', ')
|
||||
end
|
||||
|
||||
def link_to_gmaps(address)
|
||||
link_to h(address), "http://maps.google.de/?q=#{h(address)}", :title => "Show it on google maps",
|
||||
link_to h(address), "http://maps.google.com/?q=#{h(address)}", :title => I18n.t('helpers.application.show_google_maps'),
|
||||
:target => "_blank"
|
||||
end
|
||||
|
||||
|
@ -143,7 +143,7 @@ module ApplicationHelper
|
|||
# checks for nil (useful for relations)
|
||||
def link_to_user_message_if_valid(user)
|
||||
user.nil? ? '??' : link_to(user.nick, new_message_path('message[mail_to]' => user.id),
|
||||
:title => 'Nachricht schreiben')
|
||||
:title => I18n.t('helpers.application.write_message'))
|
||||
end
|
||||
|
||||
def bootstrap_flash
|
||||
|
@ -152,7 +152,7 @@ module ApplicationHelper
|
|||
type = :success if type == :notice
|
||||
type = :error if type == :alert
|
||||
text = content_tag(:div,
|
||||
content_tag(:button, raw("×"), :class => "close", "data-dismiss" => "alert") +
|
||||
content_tag(:button, I18n.t('ui.marks.close').html_safe, :class => "close", "data-dismiss" => "alert") +
|
||||
message, :class => "alert fade in alert-#{type}")
|
||||
flash_messages << text if message
|
||||
end
|
||||
|
|
|
@ -3,15 +3,15 @@ module DeliveriesHelper
|
|||
def link_to_invoice(delivery)
|
||||
if delivery.invoice
|
||||
link_to number_to_currency(delivery.invoice.amount), [:finance, delivery.invoice],
|
||||
title: "Rechnung anzeigen"
|
||||
title: I18n.t('helpers.deliveries.show_invoice')
|
||||
else
|
||||
link_to "Rechnung anlegen", new_finance_invoice_path(supplier_id: delivery.supplier.id, delivery_id: delivery.id),
|
||||
link_to I18n.t('helpers.deliveries.new_invoice'), new_finance_invoice_path(supplier_id: delivery.supplier.id, delivery_id: delivery.id),
|
||||
class: 'btn btn-mini'
|
||||
end
|
||||
end
|
||||
|
||||
def stock_articles_for_select(supplier)
|
||||
supplier.stock_articles.map {|a| ["#{a.name} (#{number_to_currency a.price}/#{a.unit})", a.id] }
|
||||
supplier.stock_articles.undeleted.reorder('articles.name ASC').map {|a| ["#{a.name} (#{number_to_currency a.price}/#{a.unit})", a.id] }
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -15,6 +15,6 @@ module MessagesHelper
|
|||
link_text = content_tag :id, nil, class: 'icon-envelope'
|
||||
link_text << " #{options[:text]}" if options[:text].present?
|
||||
link_to(link_text.html_safe, new_message_path(message: messages_params), class: 'btn',
|
||||
title: 'Nachricht verschicken')
|
||||
title: I18n.t('helpers.submit.message.create'))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,13 +6,13 @@ module OrdersHelper
|
|||
end
|
||||
|
||||
def order_pdf(order, document, text)
|
||||
link_to text, order_path(order, document: document, format: :pdf), title: "PDF erstellen"
|
||||
link_to text, order_path(order, document: document, format: :pdf), title: I18n.t('helpers.orders.order_pdf')
|
||||
end
|
||||
|
||||
def options_for_suppliers_to_select
|
||||
options = [["Lieferantin/Lager auswählen"]]
|
||||
options = [[I18n.t('helpers.orders.option_choose')]]
|
||||
options += Supplier.all.map {|s| [ s.name, url_for(action: "new", supplier_id: s)] }
|
||||
options += [["Lager", url_for(action: 'new', supplier_id: 0)]]
|
||||
options += [[I18n.t('helpers.orders.option_stock'), url_for(action: 'new', supplier_id: 0)]]
|
||||
options_for_select(options)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,7 +10,7 @@ module TasksHelper
|
|||
def highlighted_required_users(task)
|
||||
unless task.enough_users_assigned?
|
||||
content_tag :span, task.still_required_users, class: 'badge badge-important',
|
||||
title: "Es fehlen #{task.still_required_users} Mitstreiterinnen!"
|
||||
title: I18n.t('helpers.tasks.required_users', :count => task.still_required_users)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -26,7 +26,7 @@ class Mailer < ActionMailer::Base
|
|||
@link = new_password_url(id: @user.id, token: @user.reset_password_token)
|
||||
|
||||
mail :to => @user.email,
|
||||
:subject => "[#{FoodsoftConfig[:name]}] Neues Passwort für/ New password for #{@user.nick}"
|
||||
:subject => "[#{FoodsoftConfig[:name]}] " + I18n.t('mailer.reset_password.subject', :username => @user.nick)
|
||||
end
|
||||
|
||||
# Sends an invite email.
|
||||
|
@ -36,7 +36,7 @@ class Mailer < ActionMailer::Base
|
|||
@link = accept_invitation_url(token: @invite.token)
|
||||
|
||||
mail :to => @invite.email,
|
||||
:subject => "Einladung in die Foodcoop #{FoodsoftConfig[:name]} - Invitation to the Foodcoop"
|
||||
:subject => I18n.t('mailer.invite.subject')
|
||||
end
|
||||
|
||||
# Notify user of upcoming task.
|
||||
|
@ -46,7 +46,7 @@ class Mailer < ActionMailer::Base
|
|||
@task = task
|
||||
|
||||
mail :to => user.email,
|
||||
:subject => "[#{FoodsoftConfig[:name]}] Aufgaben werden fällig!"
|
||||
:subject => "[#{FoodsoftConfig[:name]}] " + I18n.t('mailer.upcoming_tasks.subject')
|
||||
end
|
||||
|
||||
# Sends order result for specific Ordergroup
|
||||
|
@ -56,7 +56,7 @@ class Mailer < ActionMailer::Base
|
|||
@group_order = group_order
|
||||
|
||||
mail :to => user.email,
|
||||
:subject => "[#{FoodsoftConfig[:name]}] Bestellung beendet: #{group_order.order.name}"
|
||||
:subject => "[#{FoodsoftConfig[:name]}] " + I18n.t('mailer.order_result.subject', :name => group_order.order.name)
|
||||
end
|
||||
|
||||
# Notify user if account balance is less than zero
|
||||
|
@ -66,7 +66,7 @@ class Mailer < ActionMailer::Base
|
|||
@transaction = transaction
|
||||
|
||||
mail :to => user.email,
|
||||
:subject => "[#{FoodsoftConfig[:name]}] Gruppenkonto im Minus"
|
||||
:subject => "[#{FoodsoftConfig[:name]}] " + I18n.t('mailer.negative_balance')
|
||||
end
|
||||
|
||||
def feedback(user, feedback)
|
||||
|
@ -78,7 +78,7 @@ class Mailer < ActionMailer::Base
|
|||
:from => "#{user.nick} <#{user.email}>",
|
||||
:sender => FoodsoftConfig[:notification]["sender_address"],
|
||||
:errors_to => FoodsoftConfig[:notification]["sender_address"],
|
||||
:subject => "[Foodsoft] Feeback von #{user.email}"
|
||||
:subject => "[#{FoodsoftConfig[:name]}] " + I18n.t('mailer.feedback.subject', :email => user.email)
|
||||
end
|
||||
|
||||
def not_enough_users_assigned(task, user)
|
||||
|
@ -87,7 +87,7 @@ class Mailer < ActionMailer::Base
|
|||
@user = user
|
||||
|
||||
mail :to => user.email,
|
||||
:subject => "[#{FoodsoftConfig[:name]}] \"#{task.name}\" braucht noch Leute!"
|
||||
:subject => "[#{FoodsoftConfig[:name]}] " + I18n.t('mailer.not_enough_users_assigned.subject', :task => task.name)
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -1,24 +1,25 @@
|
|||
# encoding: utf-8
|
||||
class Article < ActiveRecord::Base
|
||||
acts_as_paranoid # Avoid deleting the article for consistency of order-results
|
||||
extend ActiveSupport::Memoizable # Ability to cache method results. Use memoize :expensive_method
|
||||
|
||||
# Replace numeric seperator with database format
|
||||
localize_input_of :price, :tax, :deposit
|
||||
|
||||
# Associations
|
||||
belongs_to :supplier, :with_deleted => true
|
||||
belongs_to :supplier
|
||||
belongs_to :article_category
|
||||
has_many :article_prices, :order => "created_at DESC"
|
||||
|
||||
scope :available, :conditions => {:availability => true}
|
||||
scope :undeleted, -> { where(deleted_at: nil) }
|
||||
scope :available, -> { undeleted.where(availability: true) }
|
||||
scope :not_in_stock, :conditions => {:type => nil}
|
||||
|
||||
# Validations
|
||||
validates_presence_of :name, :unit, :price, :tax, :deposit, :unit_quantity, :supplier_id, :article_category
|
||||
validates_length_of :name, :in => 4..60
|
||||
validates_length_of :unit, :in => 2..15
|
||||
validates_numericality_of :price, :unit_quantity, :greater_than => 0
|
||||
validates_numericality_of :price, :greater_than_or_equal_to => 0
|
||||
validates_numericality_of :unit_quantity, :greater_than => 0
|
||||
validates_numericality_of :deposit, :tax
|
||||
validates_uniqueness_of :name, :scope => [:supplier_id, :deleted_at, :type]
|
||||
|
||||
|
@ -49,6 +50,11 @@ class Article < ActiveRecord::Base
|
|||
end
|
||||
memoize :in_open_order
|
||||
|
||||
# Returns true if the article has been ordered in the given order at least once
|
||||
def ordered_in_order?(order)
|
||||
order.order_articles.where(article_id: id).where('quantity > 0').one?
|
||||
end
|
||||
|
||||
# this method checks, if the shared_article has been changed
|
||||
# unequal attributes will returned in array
|
||||
# if only the timestamps differ and the attributes are equal,
|
||||
|
@ -136,11 +142,20 @@ class Article < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
def deleted?
|
||||
deleted_at.present?
|
||||
end
|
||||
|
||||
def mark_as_deleted
|
||||
check_article_in_use
|
||||
update_column :deleted_at, Time.now
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Checks if the article is in use before it will deleted
|
||||
def check_article_in_use
|
||||
raise self.name.to_s + " kann nicht gelöscht werden. Der Artikel befindet sich in einer laufenden Bestellung!" if self.in_open_order
|
||||
raise I18n.t('articles.model.error_in_use', :article => self.name.to_s) if self.in_open_order
|
||||
end
|
||||
|
||||
# Create an ArticlePrice, when the price-attr are changed.
|
||||
|
|
|
@ -8,7 +8,7 @@ class ArticleCategory < ActiveRecord::Base
|
|||
protected
|
||||
|
||||
def check_for_associated_articles
|
||||
raise I18n.t('activerecord.errors.has_many_left', collection: Article.model_name.human) if articles.exists?
|
||||
raise I18n.t('activerecord.errors.has_many_left', collection: Article.model_name.human) if articles.undeleted.exists?
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
class ArticlePrice < ActiveRecord::Base
|
||||
|
||||
belongs_to :article, :with_deleted => true
|
||||
belongs_to :article
|
||||
has_many :order_articles
|
||||
|
||||
validates_presence_of :price, :tax, :deposit, :unit_quantity
|
||||
validates_numericality_of :price, :unit_quantity, :greater_than => 0
|
||||
validates_numericality_of :price, :greater_than_or_equal_to => 0
|
||||
validates_numericality_of :unit_quantity, :greater_than => 0
|
||||
validates_numericality_of :deposit, :tax
|
||||
|
||||
localize_input_of :price, :tax, :deposit
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class Delivery < ActiveRecord::Base
|
||||
|
||||
belongs_to :supplier, :with_deleted => true
|
||||
belongs_to :supplier
|
||||
has_one :invoice
|
||||
has_many :stock_changes, :dependent => :destroy
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# financial transactions are the foodcoop internal financial transactions
|
||||
# only ordergroups have an account balance and are happy to transfer money
|
||||
class FinancialTransaction < ActiveRecord::Base
|
||||
belongs_to :ordergroup, :with_deleted => true
|
||||
belongs_to :ordergroup
|
||||
belongs_to :user
|
||||
|
||||
validates_presence_of :amount, :note, :user_id, :ordergroup_id
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
# Groups organize the User.
|
||||
# A Member gets the roles from the Group
|
||||
class Group < ActiveRecord::Base
|
||||
has_many :memberships, :dependent => :destroy
|
||||
has_many :memberships
|
||||
has_many :users, :through => :memberships
|
||||
|
||||
validates :name, :presence => true, :length => {:in => 1..25}
|
||||
|
||||
attr_reader :user_tokens
|
||||
|
||||
|
||||
scope :undeleted, -> { where(deleted_at: nil) }
|
||||
|
||||
# Returns true if the given user if is an member of this group.
|
||||
def member?(user)
|
||||
memberships.find_by_user_id(user.id)
|
||||
|
@ -21,7 +23,19 @@ class Group < ActiveRecord::Base
|
|||
def user_tokens=(ids)
|
||||
self.user_ids = ids.split(",")
|
||||
end
|
||||
|
||||
|
||||
def deleted?
|
||||
deleted_at.present?
|
||||
end
|
||||
|
||||
def mark_as_deleted
|
||||
# TODO: Checks for participating in not closed orders
|
||||
transaction do
|
||||
memberships.destroy_all
|
||||
# TODO: What should happen to users?
|
||||
update_column :deleted_at, Time.now
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ class GroupOrder < ActiveRecord::Base
|
|||
attr_accessor :group_order_articles_attributes
|
||||
|
||||
belongs_to :order
|
||||
belongs_to :ordergroup, :with_deleted => true
|
||||
belongs_to :ordergroup
|
||||
has_many :group_order_articles, :dependent => :destroy
|
||||
has_many :order_articles, :through => :group_order_articles
|
||||
belongs_to :updated_by, :class_name => "User", :foreign_key => "updated_by_user_id"
|
||||
|
|
|
@ -27,7 +27,7 @@ class Invite < ActiveRecord::Base
|
|||
# Custom validation: check that email does not already belong to a registered user.
|
||||
def email_not_already_registered
|
||||
unless User.find_by_email(self.email).nil?
|
||||
errors.add(:email, 'ist bereits in Verwendung. Person ist schon Mitglied der Foodcoop.')
|
||||
errors.add(:email, I18n.t('invites.errors.already_member'))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class Invoice < ActiveRecord::Base
|
||||
|
||||
belongs_to :supplier, :with_deleted => true
|
||||
belongs_to :supplier
|
||||
belongs_to :delivery
|
||||
belongs_to :order
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ class Membership < ActiveRecord::Base
|
|||
before_destroy :check_last_admin
|
||||
|
||||
# messages
|
||||
ERR_NO_ADMIN_MEMBER_DELETE = "Mitgliedschaft kann nicht beendet werden. Du bist die letzte Administratorin"
|
||||
ERR_NO_ADMIN_MEMBER_DELETE = I18n.t('model.membership.no_admin_delete')
|
||||
|
||||
protected
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ class Message < ActiveRecord::Base
|
|||
belongs_to :sender, :class_name => "User", :foreign_key => "sender_id"
|
||||
|
||||
serialize :recipients_ids, Array
|
||||
attr_accessor :sent_to_all, :group_id, :recipient_tokens
|
||||
attr_accessor :sent_to_all, :group_id, :recipient_tokens, :reply_to
|
||||
|
||||
scope :pending, where(:email_state => 0)
|
||||
scope :sent, where(:email_state => 1)
|
||||
|
@ -46,11 +46,11 @@ class Message < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def reply_to=(message_id)
|
||||
message = Message.find(message_id)
|
||||
add_recipients([message.sender])
|
||||
self.subject = "Re: #{message.subject}"
|
||||
self.body = "#{message.sender.nick} schrieb am #{I18n.l(message.created_at, :format => :short)}:\n"
|
||||
message.body.each_line{ |l| self.body += "> #{l}" }
|
||||
@reply_to = Message.find(message_id)
|
||||
add_recipients([@reply_to.sender])
|
||||
self.subject = I18n.t('messages.model.reply_subject', :subject => @reply_to.subject)
|
||||
self.body = I18n.t('messages.model.reply_header', :user => @reply_to.sender.nick, :when => I18n.l(@reply_to.created_at, :format => :short)) + "\n"
|
||||
@reply_to.body.each_line{ |l| self.body += I18n.t('messages.model.reply_indent', :line => l) }
|
||||
end
|
||||
|
||||
def mail_to=(user_id)
|
||||
|
@ -64,7 +64,7 @@ class Message < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def sender_name
|
||||
system_message? ? 'Foodsoft' : sender.nick rescue "??"
|
||||
system_message? ? I18n.t('layouts.foodsoft') : sender.nick rescue "??"
|
||||
end
|
||||
|
||||
def recipients
|
||||
|
@ -83,6 +83,10 @@ class Message < ActiveRecord::Base
|
|||
end
|
||||
update_attribute(:email_state, 1)
|
||||
end
|
||||
|
||||
def is_readable_for?(user)
|
||||
!private || sender == user || recipients_ids.include?(user.id)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ class Order < ActiveRecord::Base
|
|||
has_one :invoice
|
||||
has_many :comments, :class_name => "OrderComment", :order => "created_at"
|
||||
has_many :stock_changes
|
||||
belongs_to :supplier, :with_deleted => true
|
||||
belongs_to :supplier
|
||||
belongs_to :updated_by, :class_name => 'User', :foreign_key => 'updated_by_user_id'
|
||||
belongs_to :created_by, :class_name => 'User', :foreign_key => 'created_by_user_id'
|
||||
|
||||
|
@ -38,9 +38,11 @@ class Order < ActiveRecord::Base
|
|||
|
||||
def articles_for_ordering
|
||||
if stockit?
|
||||
# make sure to include those articles which are no longer available
|
||||
# but which have already been ordered in this stock order
|
||||
StockArticle.available.all(:include => :article_category,
|
||||
:order => 'article_categories.name, articles.name').reject{ |a|
|
||||
a.quantity_available <= 0
|
||||
a.quantity_available <= 0 and not a.ordered_in_order?(self)
|
||||
}.group_by { |a| a.article_category.name }
|
||||
else
|
||||
supplier.articles.available.all.group_by { |a| a.article_category.name }
|
||||
|
@ -113,25 +115,25 @@ class Order < ActiveRecord::Base
|
|||
def sum(type = :gross)
|
||||
total = 0
|
||||
if type == :net || type == :gross || type == :fc
|
||||
for oa in order_articles.ordered.all(:include => [:article,:article_price])
|
||||
for oa in order_articles.ordered.includes(:article, :article_price)
|
||||
quantity = oa.units_to_order * oa.price.unit_quantity
|
||||
case type
|
||||
when :net
|
||||
total += quantity * oa.price.price
|
||||
when :gross
|
||||
total += quantity * oa.price.gross_price
|
||||
when :fc
|
||||
total += quantity * oa.price.fc_price
|
||||
when :net
|
||||
total += quantity * oa.price.price
|
||||
when :gross
|
||||
total += quantity * oa.price.gross_price
|
||||
when :fc
|
||||
total += quantity * oa.price.fc_price
|
||||
end
|
||||
end
|
||||
elsif type == :groups || type == :groups_without_markup
|
||||
for go in group_orders.all(:include => :group_order_articles)
|
||||
for goa in go.group_order_articles.all(:include => [:order_article])
|
||||
for go in group_orders.includes(group_order_articles: {order_article: [:article, :article_price]})
|
||||
for goa in go.group_order_articles
|
||||
case type
|
||||
when :groups
|
||||
total += goa.result * goa.order_article.price.fc_price
|
||||
when :groups_without_markup
|
||||
total += goa.result * goa.order_article.price.gross_price
|
||||
when :groups
|
||||
total += goa.result * goa.order_article.price.fc_price
|
||||
when :groups_without_markup
|
||||
total += goa.result * goa.order_article.price.gross_price
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -156,7 +158,7 @@ class Order < ActiveRecord::Base
|
|||
goa.save_results!
|
||||
# Delete no longer required order-history (group_order_article_quantities) and
|
||||
# TODO: Do we need articles, which aren't ordered? (units_to_order == 0 ?)
|
||||
goa.group_order_article_quantities.clear
|
||||
#goa.group_order_article_quantities.clear
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -174,8 +176,9 @@ class Order < ActiveRecord::Base
|
|||
|
||||
# Sets order.status to 'close' and updates all Ordergroup.account_balances
|
||||
def close!(user)
|
||||
raise "Bestellung wurde schon abgerechnet" if closed?
|
||||
transaction_note = "Bestellung: #{name}, bis #{ends.strftime('%d.%m.%Y')}"
|
||||
raise I18n.t('orders.model.error_closed') if closed?
|
||||
transaction_note = I18n.t('orders.model.notice_close', :name => name,
|
||||
:ends => ends.strftime(I18n.t('date.formats.default')))
|
||||
|
||||
gos = group_orders.all(:include => :ordergroup) # Fetch group_orders
|
||||
gos.each { |group_order| group_order.update_price! } # Update prices of group_orders
|
||||
|
@ -199,18 +202,18 @@ class Order < ActiveRecord::Base
|
|||
|
||||
# Close the order directly, without automaticly updating ordergroups account balances
|
||||
def close_direct!(user)
|
||||
raise "Bestellung wurde schon abgerechnet" if closed?
|
||||
raise I18n.t('orders.model.error_closed') if closed?
|
||||
update_attributes! state: 'closed', updated_by: user
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def starts_before_ends
|
||||
errors.add(:ends, "muss nach dem Bestellstart liegen (oder leer bleiben)") if (ends && starts && ends <= starts)
|
||||
errors.add(:ends, I18n.t('articles.model.error_starts_before_ends')) if (ends && starts && ends <= starts)
|
||||
end
|
||||
|
||||
def include_articles
|
||||
errors.add(:articles, "Es muss mindestens ein Artikel ausgewählt sein") if article_ids.empty?
|
||||
errors.add(:articles, I18n.t('articles.model.error_nosel')) if article_ids.empty?
|
||||
end
|
||||
|
||||
def save_order_articles
|
||||
|
|
|
@ -4,7 +4,7 @@ class OrderArticle < ActiveRecord::Base
|
|||
attr_reader :update_current_price
|
||||
|
||||
belongs_to :order
|
||||
belongs_to :article, :with_deleted => true
|
||||
belongs_to :article
|
||||
belongs_to :article_price
|
||||
has_many :group_order_articles, :dependent => :destroy
|
||||
|
||||
|
@ -93,7 +93,7 @@ class OrderArticle < ActiveRecord::Base
|
|||
end
|
||||
|
||||
# Updates order_article and belongings during balancing process
|
||||
def update_article_and_price!(article_attributes, price_attributes, order_article_attributes)
|
||||
def update_article_and_price!(order_article_attributes, article_attributes, price_attributes = nil)
|
||||
OrderArticle.transaction do
|
||||
# Updates self
|
||||
self.update_attributes!(order_article_attributes)
|
||||
|
@ -102,20 +102,22 @@ class OrderArticle < ActiveRecord::Base
|
|||
article.update_attributes!(article_attributes)
|
||||
|
||||
# Updates article_price belonging to current order article
|
||||
article_price.attributes = price_attributes
|
||||
if article_price.changed?
|
||||
# Updates also price attributes of article if update_current_price is selected
|
||||
if update_current_price
|
||||
article.update_attributes!(price_attributes)
|
||||
self.article_price = article.article_prices.first # Assign new created article price to order article
|
||||
else
|
||||
# Creates a new article_price if neccessary
|
||||
# Set created_at timestamp to order ends, to make sure the current article price isn't changed
|
||||
create_article_price!(price_attributes.merge(created_at: order.ends)) and save
|
||||
end
|
||||
if price_attributes.present?
|
||||
article_price.attributes = price_attributes
|
||||
if article_price.changed?
|
||||
# Updates also price attributes of article if update_current_price is selected
|
||||
if update_current_price
|
||||
article.update_attributes!(price_attributes)
|
||||
self.article_price = article.article_prices.first # Assign new created article price to order article
|
||||
else
|
||||
# Creates a new article_price if neccessary
|
||||
# Set created_at timestamp to order ends, to make sure the current article price isn't changed
|
||||
create_article_price!(price_attributes.merge(created_at: order.ends)) and save
|
||||
end
|
||||
|
||||
# Updates ordergroup values
|
||||
update_ordergroup_prices
|
||||
# Updates ordergroup values
|
||||
update_ordergroup_prices
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -134,7 +136,7 @@ class OrderArticle < ActiveRecord::Base
|
|||
private
|
||||
|
||||
def article_and_price_exist
|
||||
errors.add(:article, "muss angegeben sein und einen aktuellen Preis haben") if !(article = Article.find(article_id)) || article.fc_price.nil?
|
||||
errors.add(:article, I18n.t('model.order_article.error_price')) if !(article = Article.find(article_id)) || article.fc_price.nil?
|
||||
end
|
||||
|
||||
# Associate with current article price if created in a finished order
|
||||
|
@ -146,7 +148,10 @@ class OrderArticle < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def update_ordergroup_prices
|
||||
group_order_articles.each { |goa| goa.group_order.update_price! }
|
||||
# updates prices of ALL ordergroups - these are actually too many
|
||||
# in case of performance issues, update only ordergroups, which ordered this article
|
||||
# CAUTION: in after_destroy callback related records (e.g. group_order_articles) are already non-existent
|
||||
order.group_orders.each { |go| go.update_price! }
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -8,14 +8,13 @@ class Ordergroup < Group
|
|||
|
||||
APPLE_MONTH_AGO = 6 # How many month back we will count tasks and orders sum
|
||||
|
||||
acts_as_paranoid # Avoid deleting the ordergroup for consistency of order-results
|
||||
serialize :stats
|
||||
|
||||
has_many :financial_transactions
|
||||
has_many :group_orders
|
||||
has_many :orders, :through => :group_orders
|
||||
|
||||
validates_numericality_of :account_balance, :message => 'ist keine gültige Zahl'
|
||||
validates_numericality_of :account_balance, :message => I18n.t('ordergroups.model.invalid_balance')
|
||||
validate :uniqueness_of_name, :uniqueness_of_members
|
||||
|
||||
after_create :update_stats!
|
||||
|
@ -103,7 +102,7 @@ class Ordergroup < Group
|
|||
# Make sure, that a user can only be in one ordergroup
|
||||
def uniqueness_of_members
|
||||
users.each do |user|
|
||||
errors.add :user_tokens, "#{user.nick} ist schon in einer anderen Bestellgruppe" if user.groups.where(:type => 'Ordergroup').size > 1
|
||||
errors.add :user_tokens, I18n.t('ordergroups.model.error_single_group', :user => user.nick) if user.groups.where(:type => 'Ordergroup').size > 1
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -116,6 +115,16 @@ class Ordergroup < Group
|
|||
errors.add :name, message
|
||||
end
|
||||
end
|
||||
|
||||
# Make sure, the name is uniq, add usefull message if uniq group is already deleted
|
||||
def uniqueness_of_name
|
||||
id = new_record? ? '' : self.id
|
||||
group = Ordergroup.where('groups.id != ? AND groups.name = ?', id, name).first
|
||||
if group.present?
|
||||
message = group.deleted? ? :taken_with_deleted : :taken
|
||||
errors.add :name, message
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ class Page < ActiveRecord::Base
|
|||
unless old_title.blank?
|
||||
Page.create :redirect => id,
|
||||
:title => old_title,
|
||||
:body => "Weiterleitung auf [[#{title}]]..",
|
||||
:body => I18n.t('model.page.redirect', :title => title),
|
||||
:permalink => Page.permalink(old_title),
|
||||
:updated_by => updated_by
|
||||
end
|
||||
|
|
|
@ -7,6 +7,12 @@ class SharedSupplier < ActiveRecord::Base
|
|||
|
||||
has_one :supplier
|
||||
has_many :shared_articles, :foreign_key => :supplier_id
|
||||
|
||||
|
||||
# These set of attributes are used to autofill attributes of new supplier,
|
||||
# when created by import from shared supplier feature.
|
||||
def autofill_attributes
|
||||
whitelist = %w(name address phone fax email url delivery_days note)
|
||||
attributes.select { |k,_v| whitelist.include?(k) }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
# encoding: utf-8
|
||||
class StockArticle < Article
|
||||
acts_as_paranoid
|
||||
|
||||
|
||||
has_many :stock_changes
|
||||
|
||||
scope :available, :conditions => "quantity > 0"
|
||||
scope :available, -> { undeleted.where'quantity > 0' }
|
||||
|
||||
before_destroy :check_quantity
|
||||
|
||||
|
@ -23,10 +22,15 @@ class StockArticle < Article
|
|||
available.collect { |a| a.quantity * a.gross_price }.sum
|
||||
end
|
||||
|
||||
def mark_as_deleted
|
||||
check_quantity
|
||||
super
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def check_quantity
|
||||
raise "#{name} kann nicht gelöscht werden. Der Lagerbestand ist nicht null." unless quantity == 0
|
||||
raise I18n.t('stockit.check.not_empty', :name => name) unless quantity == 0
|
||||
end
|
||||
|
||||
# Overwrite Price history of Article. For StockArticles isn't it necessary.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class StockChange < ActiveRecord::Base
|
||||
belongs_to :delivery
|
||||
belongs_to :order
|
||||
belongs_to :stock_article, with_deleted: true
|
||||
belongs_to :stock_article
|
||||
|
||||
validates_presence_of :stock_article_id, :quantity
|
||||
validates_numericality_of :quantity
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# encoding: utf-8
|
||||
class Supplier < ActiveRecord::Base
|
||||
acts_as_paranoid # Avoid deleting the supplier for consistency of order-results
|
||||
|
||||
has_many :articles, :dependent => :destroy, :conditions => {:type => nil},
|
||||
has_many :articles, :conditions => {:type => nil},
|
||||
:include => [:article_category], :order => 'article_categories.name, articles.name'
|
||||
has_many :stock_articles, :include => [:article_category], :order => 'article_categories.name, articles.name'
|
||||
has_many :orders
|
||||
|
@ -20,13 +20,15 @@ class Supplier < ActiveRecord::Base
|
|||
validates_length_of :address, :in => 8..50
|
||||
validate :uniqueness_of_name
|
||||
|
||||
scope :undeleted, -> { where(deleted_at: nil) }
|
||||
|
||||
# sync all articles with the external database
|
||||
# returns an array with articles(and prices), which should be updated (to use in a form)
|
||||
# also returns an array with outlisted_articles, which should be deleted
|
||||
def sync_all
|
||||
updated_articles = Array.new
|
||||
outlisted_articles = Array.new
|
||||
for article in articles
|
||||
for article in articles.undeleted
|
||||
# try to find the associated shared_article
|
||||
shared_article = article.shared_article
|
||||
|
||||
|
@ -65,12 +67,23 @@ class Supplier < ActiveRecord::Base
|
|||
return [updated_articles, outlisted_articles]
|
||||
end
|
||||
|
||||
def deleted?
|
||||
deleted_at.present?
|
||||
end
|
||||
|
||||
def mark_as_deleted
|
||||
transaction do
|
||||
update_column :deleted_at, Time.now
|
||||
articles.each(&:mark_as_deleted)
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Make sure, the name is uniq, add usefull message if uniq group is already deleted
|
||||
def uniqueness_of_name
|
||||
id = new_record? ? '' : self.id
|
||||
supplier = Supplier.with_deleted.where('suppliers.id != ? AND suppliers.name = ?', id, name).first
|
||||
supplier = Supplier.where('suppliers.id != ? AND suppliers.name = ?', id, name).first
|
||||
if supplier.present?
|
||||
message = supplier.deleted? ? :taken_with_deleted : :taken
|
||||
errors.add :name, message
|
||||
|
|
|
@ -75,13 +75,10 @@ class Task < ActiveRecord::Base
|
|||
# and makes the users responsible for the task
|
||||
# TODO: check for maximal number of users
|
||||
def user_list=(ids)
|
||||
list = ids.split(",")
|
||||
list = ids.split(",").map(&:to_i)
|
||||
new_users = (list - users.collect(&:id)).uniq
|
||||
old_users = users.reject { |user| list.include?(user.id) }
|
||||
|
||||
logger.debug "[debug] New users: #{new_users}"
|
||||
logger.debug "Old users: #{old_users}"
|
||||
|
||||
self.class.transaction do
|
||||
# delete old assignments
|
||||
if old_users.any?
|
||||
|
@ -93,7 +90,7 @@ class Task < ActiveRecord::Base
|
|||
if user.blank?
|
||||
errors.add(:user_list)
|
||||
else
|
||||
if id == current_user_id
|
||||
if id == current_user_id.to_i
|
||||
# current_user will accept, when he puts himself to the list of users
|
||||
self.assignments.build :user => user, :accepted => true
|
||||
else
|
||||
|
|
|
@ -44,13 +44,13 @@ class User < ActiveRecord::Base
|
|||
# returns the User-settings and the translated description
|
||||
def self.setting_keys
|
||||
{
|
||||
"notify.orderFinished" => 'Informier mich über meine Bestellergebnisse (nach Ende der Bestellung).',
|
||||
"notify.negativeBalance" => 'Informiere mich, falls meine Bestellgruppe ins Minus rutscht.',
|
||||
"notify.upcoming_tasks" => 'Erinnere mich an anstehende Aufgaben.',
|
||||
"messages.sendAsEmail" => 'Bekomme Nachrichten als Emails.',
|
||||
"profile.phoneIsPublic" => 'Telefon ist für Mitglieder sichtbar',
|
||||
"profile.emailIsPublic" => 'E-Mail ist für Mitglieder sichtbar',
|
||||
"profile.nameIsPublic" => 'Name ist für Mitglieder sichtbar'
|
||||
"notify.orderFinished" => I18n.t('model.user.notify.order_finished'),
|
||||
"notify.negativeBalance" => I18n.t('model.user.notify.negative_balance'),
|
||||
"notify.upcoming_tasks" => I18n.t('model.user.notify.upcoming_tasks'),
|
||||
"messages.sendAsEmail" => I18n.t('model.user.notify.send_as_email'),
|
||||
"profile.phoneIsPublic" => I18n.t('model.user.notify.phone_is_public'),
|
||||
"profile.emailIsPublic" => I18n.t('model.user.notify.email_is_public'),
|
||||
"profile.nameIsPublic" => I18n.t('model.user.notify.name_is_public')
|
||||
}
|
||||
end
|
||||
# retuns the default setting for a NEW user
|
||||
|
@ -132,7 +132,7 @@ class User < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def ordergroup_name
|
||||
ordergroup ? ordergroup.name : "keine Bestellgruppe"
|
||||
ordergroup ? ordergroup.name : I18n.t('model.user.no_ordergroup')
|
||||
end
|
||||
|
||||
# returns true if user is a member of a given group
|
||||
|
|
|
@ -15,7 +15,8 @@ class Workgroup < Group
|
|||
before_destroy :check_last_admin_group
|
||||
|
||||
def self.weekdays
|
||||
[["Montag", "1"], ["Dienstag", "2"], ["Mittwoch","3"],["Donnerstag","4"],["Freitag","5"],["Samstag","6"],["Sonntag","0"]]
|
||||
days = I18n.t('date.day_names')
|
||||
(0..days.length-1).map {|i| [days[i], i.to_s]}
|
||||
end
|
||||
|
||||
# Returns an Array with date-objects to represent the next weekly-tasks
|
||||
|
@ -55,7 +56,7 @@ class Workgroup < Group
|
|||
# Check before destroy a group, if this is the last group with admin role
|
||||
def check_last_admin_group
|
||||
if role_admin && Workgroup.where(:role_admin => true).size == 1
|
||||
raise "Die letzte Gruppe mit Admin-Rechten darf nicht gelöscht werden"
|
||||
raise I18n.t('workgroups.error_last_admin_group')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -63,7 +64,7 @@ class Workgroup < Group
|
|||
# Return an error if this is the last group with admin role and role_admin should set to false
|
||||
def last_admin_on_earth
|
||||
if !role_admin && !Workgroup.where('role_admin = ? AND id != ?', true, id).exists?
|
||||
errors.add(:role_admin, "Der letzten Gruppe mit Admin-Rechten darf die Admin-Rolle nicht entzogen werden")
|
||||
errors.add(:role_admin, I18n.t('workgroups.error_last_admin_role'))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,43 +1,43 @@
|
|||
- title "Administration"
|
||||
- title t '.title'
|
||||
|
||||
%p
|
||||
%i Hier kannst Du die Gruppen und Benutzerinnen der Foodsoft verwalten.
|
||||
%i= t '.first_paragraph'
|
||||
.row-fluid
|
||||
.span6
|
||||
%section
|
||||
%h2 Neuste Benutzerinnen
|
||||
%h2= t '.newest_users'
|
||||
%table.table.table-striped
|
||||
%thead
|
||||
%tr
|
||||
%th Benutzername
|
||||
%th Name
|
||||
%th Erstellt am
|
||||
%th= t '.username'
|
||||
%th= t '.name'
|
||||
%th= t '.created_at'
|
||||
- for user in @users
|
||||
%tr{:class => cycle('even','odd', :name => 'users')}
|
||||
%td= link_to user.nick, [:admin, user]
|
||||
%td=h user.name
|
||||
%td= format_date(user.created_on)
|
||||
= link_to 'Alle Benutzerinnen', admin_users_path
|
||||
= link_to t('.all_users'), admin_users_path
|
||||
|
|
||||
= link_to "Neue Benutzerin", new_admin_user_path, class: 'btn btn-primary btn-small'
|
||||
= link_to t('.new_user'), new_admin_user_path, class: 'btn btn-primary btn-small'
|
||||
.span6
|
||||
%section
|
||||
%h2 Neuste Gruppen
|
||||
%h2= t '.newest_groups'
|
||||
%table.table.table-striped
|
||||
%thead
|
||||
%tr
|
||||
%th Gruppenname
|
||||
%th Typ
|
||||
%th Mitglieder
|
||||
%th= t '.groupname'
|
||||
%th= t '.type'
|
||||
%th= t '.members'
|
||||
- for group in @groups
|
||||
%tr{:class => cycle('even','odd', :name => 'groups')}
|
||||
%td= link_to group.name, [:admin, group]
|
||||
%td= group.class.model_name.human
|
||||
%td= group.users.size
|
||||
= link_to 'Alle Bestellgruppen', admin_ordergroups_path
|
||||
= link_to t('.all_ordergroups'), admin_ordergroups_path
|
||||
|
|
||||
= link_to "Neue Bestellgruppe", new_admin_ordergroup_path, class: 'btn btn-primary btn-small'
|
||||
= link_to t('.new_ordergroup'), new_admin_ordergroup_path, class: 'btn btn-primary btn-small'
|
||||
|
|
||||
= link_to 'Alle Arbeitsgruppen', admin_workgroups_path
|
||||
= link_to t('.all_workgroups'), admin_workgroups_path
|
||||
|
|
||||
= link_to "Neue Arbeitsgruppe", new_admin_workgroup_path, class: 'btn btn-primary btn-small'
|
||||
= link_to t('.new_workgroup'), new_admin_workgroup_path, class: 'btn btn-primary btn-small'
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
- unless @ordergroup.new_record?
|
||||
%p
|
||||
Neue Mitglieder kannst du
|
||||
= link_to "hier", new_invite_path(id: @ordergroup.id), remote: true
|
||||
einladen.
|
||||
%p= t('.first_paragraph', url: link_to(t('.here'), new_invite_path(id: @ordergroup.id), remote: true)).html_safe
|
||||
= simple_form_for [:admin, @ordergroup] do |f|
|
||||
= render :layout => 'shared/group_form_fields', :locals => {:f => f} do
|
||||
= f.input :contact_person
|
||||
|
@ -11,4 +8,4 @@
|
|||
= f.input :ignore_apple_restriction
|
||||
.form-actions
|
||||
= f.button :submit
|
||||
= link_to "oder abbrechen", :back
|
||||
= link_to t('ui.or_cancel'), :back
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
%table.table.table-striped
|
||||
%thead
|
||||
%tr
|
||||
%th Name
|
||||
%th Kontakt
|
||||
%th Adresse
|
||||
%th Mitglieder
|
||||
%th Aktionen
|
||||
%th= t '.name'
|
||||
%th= t '.contact'
|
||||
%th= t '.address'
|
||||
%th= t '.members'
|
||||
%th= t 'admin.actions'
|
||||
%tbody
|
||||
- for ordergroup in @ordergroups
|
||||
%tr{:class => cycle('even','odd', :name => 'groups')}
|
||||
|
@ -17,6 +17,6 @@
|
|||
%td= link_to_gmaps ordergroup.contact_address
|
||||
%td= ordergroup.users.size
|
||||
%td
|
||||
= link_to "Bearbeiten", edit_admin_ordergroup_path(ordergroup), class: 'btn btn-mini'
|
||||
= link_to "Löschen", [:admin, ordergroup], :confirm => "Willst du #{ordergroup.name} wirklich löschen?",
|
||||
:method => :delete, class: 'btn btn-mini btn-danger'
|
||||
= link_to t('ui.edit'), edit_admin_ordergroup_path(ordergroup), class: 'btn btn-mini'
|
||||
= link_to t('ui.delete'), [:admin, ordergroup], :confirm => t('admin.confirm', name: ordergroup.name),
|
||||
:method => :delete, class: 'btn btn-mini btn-danger'
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
- title "Bestellgruppe bearbeiten"
|
||||
- title t '.title'
|
||||
|
||||
= render :partial => 'form'
|
||||
= render 'form'
|
|
@ -1,25 +1,15 @@
|
|||
- title "Bestellgruppen"
|
||||
- title t('.title')
|
||||
|
||||
- content_for :actionbar do
|
||||
= link_to "Neue Bestellgruppe anlegen", new_admin_ordergroup_path, class: 'btn btn-primary'
|
||||
= link_to t('.new_ordergroup'), new_admin_ordergroup_path, class: 'btn btn-primary'
|
||||
|
||||
- content_for :sidebar do
|
||||
%p
|
||||
Hier kannst du
|
||||
= link_to 'neue Bestellgruppen', new_admin_ordergroup_path
|
||||
anlegen, Gruppen bearbeiten und löschen.
|
||||
%p
|
||||
Beachte dabei den <em>Unterschied zwischen Gruppe und Bestellgruppe</em>:
|
||||
Eine Bestellgruppe hat ein Konto und kann Essen bestellen. In einer
|
||||
%em= link_to 'Arbeitsgruppe', admin_workgroups_path
|
||||
(z.b. 'Soritiergruppe')
|
||||
koordinieren sich die Mitglieder mittels Aufgaben und Nachrichten.
|
||||
Nutzer_innen können immer nur einer Bestellgruppe, aber beliebig vielen anderen Gruppen angehören.
|
||||
|
||||
%p= t('.first_paragraph', url: link_to(t('.new_ordergroups'), new_admin_ordergroup_path)).html_safe
|
||||
%p= t('.second_paragraph', url: link_to(t('.workgroup'), admin_workgroups_path)).html_safe
|
||||
.well.well-small
|
||||
= form_tag admin_ordergroups_path, :method => :get, :remote => true,
|
||||
'data-submit-onchange' => true, class: 'form-search' do
|
||||
= text_field_tag :query, params[:query], class: 'input-medium search-query',
|
||||
placeholder: 'Name ...'
|
||||
placeholder: t('admin.search_placeholder')
|
||||
#ordergroups
|
||||
= render "ordergroups"
|
|
@ -1,3 +1,3 @@
|
|||
- title "Bestellgruppe anlegen"
|
||||
- title t '.title'
|
||||
|
||||
= render 'form'
|
|
@ -1,6 +1,6 @@
|
|||
- title "Bestellgruppe #{@ordergroup.name}"
|
||||
- title t '.title', name: @ordergroup.name
|
||||
|
||||
%section= render 'shared/group', group: @ordergroup
|
||||
= link_to 'Gruppe/Mitglieder bearbeiten', edit_admin_ordergroup_path(@ordergroup), class: 'btn'
|
||||
= link_to 'Löschen', [:admin, @ordergroup], :confirm => 'Bist Du sicher?', :method => :delete, class: 'btn btn-danger'
|
||||
= link_to 'Nachricht senden', new_message_path(:message => {:group_id => @ordergroup.id}), class: 'btn'
|
||||
= link_to t('ui.edit'), edit_admin_ordergroup_path(@ordergroup), class: 'btn'
|
||||
= link_to t('ui.delete'), [:admin, @ordergroup], :confirm => t('.confirm'), :method => :delete, class: 'btn btn-danger'
|
||||
= link_to t('.send_message'), new_message_path(:message => {:group_id => @ordergroup.id}), class: 'btn'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
= simple_form_for([:admin, @user]) do |f|
|
||||
= render :partial => 'shared/user_form_fields', :locals => {:f => f}
|
||||
= render 'shared/user_form_fields', f: f
|
||||
.form-actions
|
||||
= f.submit
|
||||
= link_to 'oder abbrechen', :back
|
||||
= link_to t('ui.or_cancel'), :back
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
%table.table.table-striped
|
||||
%thead
|
||||
%tr
|
||||
%th Login
|
||||
%th Name
|
||||
%th Email
|
||||
%th Zugriff auf
|
||||
%th Letzter login
|
||||
%th(colspan="2") Aktionen
|
||||
%th= t '.login'
|
||||
%th= t '.name'
|
||||
%th= t '.email'
|
||||
%th= t 'admin.access_to'
|
||||
%th= t '.last_login'
|
||||
%th(colspan="2")= t 'admin.actions'
|
||||
%tbody
|
||||
- for user in @users
|
||||
%tr
|
||||
|
@ -18,6 +18,6 @@
|
|||
%td= user.email
|
||||
%td= format_roles(user)
|
||||
%td= format_time(user.last_login)
|
||||
%td= link_to 'Bearbeiten', edit_admin_user_path(user), class: 'btn btn-mini'
|
||||
%td= link_to 'Löschen', [:admin, user], :confirm => "Willst du #{user.name} wirklich löschen?",
|
||||
%td= link_to t('ui.edit'), edit_admin_user_path(user), class: 'btn btn-mini'
|
||||
%td= link_to t('ui.delete'), [:admin, user], :confirm => t('admin.confirm', name: user.name),
|
||||
:method => :delete, class: 'btn btn-danger btn-mini'
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
- title "Benutzerin bearbeiten"
|
||||
- title t '.title'
|
||||
|
||||
= render 'form'
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
- title "Admin/Benutzerinnen"
|
||||
- title t '.title'
|
||||
|
||||
- content_for :actionbar do
|
||||
= link_to 'Neue Benutzerin anlegen', new_admin_user_path, class: 'btn btn-primary'
|
||||
= link_to t('.new_user'), new_admin_user_path, class: 'btn btn-primary'
|
||||
|
||||
- content_for :sidebar do
|
||||
%p
|
||||
Hier kannst du Benutzer_innen #{link_to 'neu Anlegen', new_admin_user_path},
|
||||
bearbeiten und natürlich auch löschen.
|
||||
%p= t('.first_paragraph', url: link_to(t('.new_users'), new_admin_user_path)).html_safe
|
||||
|
||||
.well.well-small
|
||||
= form_tag admin_users_path, :method => :get, :remote => true,
|
||||
'data-submit-onchange' => true, class: 'form-search' do
|
||||
= text_field_tag :user_name, params[:user_name], class: 'input-medium search-query',
|
||||
placeholder: 'Name ...'
|
||||
placeholder: t('admin.search_placeholder')
|
||||
|
||||
#users
|
||||
= render "users"
|
|
@ -1,3 +1,3 @@
|
|||
- title "Neue Benutzerin anlegen"
|
||||
- title t '.title'
|
||||
|
||||
= render 'form'
|
|
@ -3,37 +3,37 @@
|
|||
.row-fluid
|
||||
.span3
|
||||
.well
|
||||
%h4 Person
|
||||
%p Mitglied seit #{distance_of_time_in_words(Time.now, @user.created_on)}
|
||||
%h4= t '.person'
|
||||
%p= t '.member_since', time: distance_of_time_in_words(Time.now, @user.created_on)
|
||||
%dl
|
||||
%dt Nick
|
||||
%dt= t '.nick'
|
||||
%dd= @user.nick
|
||||
%dt Name
|
||||
%dt= t '.name'
|
||||
%dd= h @user.name
|
||||
%dt Email
|
||||
%dt= t '.email'
|
||||
%dd= @user.email
|
||||
%dt Telefon
|
||||
%dt= t '.phone'
|
||||
%dd= @user.phone
|
||||
%dt Zugriff auf
|
||||
%dt= t 'admin.access_to'
|
||||
%dd= format_roles(@user)
|
||||
.span5
|
||||
.well
|
||||
%h4 Einstellungen
|
||||
%h4= t '.preference'
|
||||
%table.table
|
||||
- for setting in User::setting_keys.keys
|
||||
%tr
|
||||
%td= User::setting_keys[setting]
|
||||
%td= @user.settings[setting] == '1' ? 'ja' : 'nein'
|
||||
%td= @user.settings[setting] == '1' ? t('simple_form.yes') : t('simple_form.no')
|
||||
.span3
|
||||
.well
|
||||
%h4 Gruppenabos
|
||||
%h4= t '.groupabos'
|
||||
%ul.unstyled
|
||||
- for membership in Membership.find_all_by_user_id(@user.id)
|
||||
%li= link_to(membership.group.name, [:admin, membership.group])
|
||||
|
||||
%hr/
|
||||
%p
|
||||
= link_to 'Bearbeiten', edit_admin_user_path(@user), class: 'btn'
|
||||
= link_to 'Löschen', [:admin, @user], :confirm => "Willst du #{@user.first_name} wirklich rausschmeißen?",
|
||||
= link_to t('ui.edit'), edit_admin_user_path(@user), class: 'btn'
|
||||
= link_to t('ui.delete'), [:admin, @user], :confirm => t('.confirm', user: @user.first_name),
|
||||
:method => :delete, class: 'btn btn-danger'
|
||||
= link_to "Nachricht senden", new_message_path(:message => {:mail_to => @user.id}), class: 'btn'
|
||||
= link_to t('.send_message'), new_message_path(:message => {:mail_to => @user.id}), class: 'btn'
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
%p
|
||||
Neue Mitglieder kannst du
|
||||
= link_to "hier", new_invite_path(id: @workgroup.id)
|
||||
einladen.
|
||||
%p= t('.first_paragraph', url: link_to(t('.here'), new_invite_path(id: @workgroup.id), remote: true)).html_safe
|
||||
= simple_form_for [:admin, @workgroup] do |f|
|
||||
= render :layout => 'shared/group_form_fields', :locals => {:f => f} do
|
||||
%h4 Zugriff auf
|
||||
%h4= t 'admin.access_to'
|
||||
= f.input :role_admin
|
||||
= f.input :role_finance
|
||||
= f.input :role_suppliers
|
||||
|
@ -12,4 +9,4 @@
|
|||
= f.input :role_orders
|
||||
.form-actions
|
||||
= f.button :submit
|
||||
= link_to "oder abbrechen", :back
|
||||
= link_to t('ui.or_cancel'), :back
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
%table.table.table-striped
|
||||
%thead
|
||||
%tr
|
||||
%th Name
|
||||
%th Mitglieder
|
||||
%th Zugriff auf
|
||||
%th Aktionen
|
||||
%th= t '.name'
|
||||
%th= t '.members'
|
||||
%th= t 'admin.access_to'
|
||||
%th= t 'admin.actions'
|
||||
%tbody
|
||||
- for workgroup in @workgroups
|
||||
%tr
|
||||
|
@ -15,6 +15,6 @@
|
|||
%td= workgroup.users.size
|
||||
%td= format_roles(workgroup)
|
||||
%td
|
||||
= link_to "Bearbeiten", edit_admin_workgroup_path(workgroup), class: 'btn btn-mini'
|
||||
= link_to "Löschen", [:admin, workgroup], :confirm => 'Willst du ' + workgroup.name + ' wirklich löschen?',
|
||||
= link_to t('ui.edit'), edit_admin_workgroup_path(workgroup), class: 'btn btn-mini'
|
||||
= link_to t('ui.delete'), [:admin, workgroup], :confirm => t('admin.confirm', name: workgroup.name),
|
||||
:method => :delete, class: 'btn btn-mini btn-danger'
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
- title "Arbeitsgruppe bearbeiten"
|
||||
- title t '.title'
|
||||
|
||||
= render 'form'
|
|
@ -1,24 +1,15 @@
|
|||
- title "Arbeitsgruppen"
|
||||
- title t '.title'
|
||||
|
||||
- content_for :actionbar do
|
||||
= link_to "Neue Arbeitsgruppe anlegen", new_admin_workgroup_path, class: 'btn btn-primary'
|
||||
= link_to t('.new_workgroup'), new_admin_workgroup_path, class: 'btn btn-primary'
|
||||
|
||||
- content_for :sidebar do
|
||||
%p
|
||||
Hier kannst du
|
||||
= link_to 'neue Arbeitsgruppen', new_admin_workgroup_path
|
||||
anlegen, Gruppen bearbeiten und löschen.
|
||||
%p
|
||||
Beachte dabei den <strong>Unterschied zwischen Gruppe und Bestellgruppe</strong>:
|
||||
Eine #{link_to 'Bestellgruppe', '/admin/ordergroups'}
|
||||
hat ein Konto und kann Essen bestellen. In einer Arbeitsgruppe (z.b. 'Soritiergruppe')
|
||||
koordinieren sich die Mitglieder mittels Aufgaben und Nachrichten.
|
||||
Nutzer_innen können immer nur einer Bestellgruppe, aber beliebig vielen anderen Gruppen angehören.
|
||||
|
||||
%p= t('.first_paragraph', url: link_to(t('.new_workgroups'), new_admin_workgroup_path)).html_safe
|
||||
%p= t('.second_paragraph', url: link_to(t('.ordergroup'), admin_ordergroups_path)).html_safe
|
||||
.well.well-small
|
||||
= form_tag admin_workgroups_path, :method => :get, :remote => true,
|
||||
'data-submit-onchange' => true, class: 'form-search' do
|
||||
= text_field_tag :query, params[:query], class: 'input-medium search-query',
|
||||
placeholder: 'Name ...'
|
||||
placeholder: t('admin.search_placeholder')
|
||||
#workgroups
|
||||
= render "workgroups"
|
|
@ -1,3 +1,3 @@
|
|||
- title "Arbeitsgruppe anlegen"
|
||||
- title t '.title'
|
||||
|
||||
= render 'form'
|
|
@ -1,6 +1,6 @@
|
|||
- title "Arbeitsgruppe #{@workgroup.name}"
|
||||
- title t '.title', name: @workgroup.name
|
||||
|
||||
%section= render :partial => 'shared/group', :locals => { :group => @workgroup }
|
||||
= link_to 'Gruppe/Mitglieder bearbeiten', edit_admin_workgroup_path(@workgroup), class: 'btn'
|
||||
= link_to 'Löschen', [:admin, @workgroup], :confirm => 'Bist Du sicher?', :method => :delete, class: 'btn btn-danger'
|
||||
= link_to_new_message(message_params: {group_id: @workgroup.id})
|
||||
%section= render 'shared/group', group: @workgroup
|
||||
= link_to t('ui.edit'), edit_admin_workgroup_path(@workgroup), class: 'btn'
|
||||
= link_to t('ui.delete'), [:admin, @workgroup], :confirm => t('.confirm'), :method => :delete, class: 'btn btn-danger'
|
||||
= link_to_new_message(message_params: {group_id: @workgroup.id})
|
||||
|
|
|
@ -3,4 +3,4 @@
|
|||
= f.input :description
|
||||
.form-actions
|
||||
= f.submit class: 'btn'
|
||||
= link_to 'oder abbrechen', article_categories_path
|
||||
= link_to t('ui.or_cancel'), article_categories_path
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
- title "Kategorie ändern"
|
||||
- title t('.title')
|
||||
|
||||
= render 'form'
|
||||
= render 'form'
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
- title "Artikelkategorien"
|
||||
- title t('.title')
|
||||
|
||||
%p= link_to "Neue Kategorie anlegen", new_article_category_path, class: 'btn btn-primary'
|
||||
%p= link_to t('.new'), new_article_category_path, class: 'btn btn-primary'
|
||||
|
||||
%table.table.table-striped
|
||||
%thead
|
||||
%tr
|
||||
%th Name
|
||||
%th Beschreibung
|
||||
%th= t('simple_form.labels.article_category.name')
|
||||
%th= t('simple_form.labels.article_category.description')
|
||||
%th
|
||||
%tbody
|
||||
- @article_categories.each do |article_category|
|
||||
|
@ -14,6 +14,6 @@
|
|||
%td= article_category.name
|
||||
%td= article_category.description
|
||||
%td
|
||||
= link_to "Bearbeiten", edit_article_category_path(article_category), class: 'btn btn-mini'
|
||||
= link_to "Löschen", article_category, :method => :delete, :confirm => 'Are you sure?',
|
||||
= link_to t('ui.edit'), edit_article_category_path(article_category), class: 'btn btn-mini'
|
||||
= link_to t('ui.delete'), article_category, :method => :delete, :confirm => t('.confirm_delete'),
|
||||
class: 'btn btn-mini btn-danger'
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
- title "Neue Kategorie anlegen"
|
||||
- title t('.title')
|
||||
|
||||
= render 'form'
|
||||
= render 'form'
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
%td= truncate(article.note, :length => 11)
|
||||
%td= article.unit_quantity
|
||||
%td{:class => "currency"}
|
||||
%acronym{:title => "zuletzt geändert: #{format_date(article.updated_at)} | Brutto: #{number_to_currency(article.gross_price)}"}
|
||||
%acronym{:title => t('.last_update', last_update: format_date(article.updated_at), gross_price: number_to_currency(article.gross_price))}
|
||||
= number_to_currency(article.price)
|
||||
%td= number_to_percentage(article.tax) if article.tax != 0
|
||||
%td= number_to_currency(article.deposit) if article.deposit != 0
|
||||
%td= link_to "Bearbeiten", edit_supplier_article_path(@supplier, article),
|
||||
%td= link_to t('ui.edit'), edit_supplier_article_path(@supplier, article),
|
||||
:remote => true, class: 'btn btn-mini'
|
||||
%td= link_to "Löschen", [@supplier, article],
|
||||
:method => :delete, :confirm => 'Bist du sicher?', :remote => true, class: 'btn btn-mini btn-danger'
|
||||
%td= link_to t('ui.delete'), [@supplier, article],
|
||||
:method => :delete, :confirm => t('.confirm_delete'), :remote => true, class: 'btn btn-mini btn-danger'
|
||||
|
|
|
@ -6,15 +6,16 @@
|
|||
%thead
|
||||
%tr
|
||||
%th
|
||||
%th= sort_link_helper "Name", "name"
|
||||
%th= sort_link_helper t('simple_form.labels.article.name'), "name"
|
||||
%th
|
||||
%th= sort_link_helper "Kategorie", "category"
|
||||
%th= sort_link_helper "Einheit", "unit"
|
||||
%th= sort_link_helper "Notiz", "note"
|
||||
%th{:style => "width: 4em;"} Gebgr.
|
||||
%th{:style => "width: 5em;"} Preis
|
||||
%th{:style => "width: 3.5em;"} MwSt
|
||||
%th{:style => "width: 4em;"} Pfand
|
||||
%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{:style => "width: 3em;"}
|
||||
|
||||
%tbody#listbody
|
||||
|
@ -27,10 +28,10 @@
|
|||
%td{:colspan => '11'}
|
||||
= check_box_tag :checkall, 1, false, 'data-check-all' => '#articlesInListForm', 'data-ignore-onchange' => true
|
||||
%select{:name => "selected_action", 'data-submit-onchange' => true}
|
||||
%option{:value => '', :selected => 'selected'} Aktion wählen ...
|
||||
%option{:value => "destroy", 'data-confirm' => 'Willst Du wirklich alle gewählten Artikel löschen?'} Artikel löschen
|
||||
%option{:value => "setNotAvailable"} Artikel sind nicht mehr verfügbar
|
||||
%option{:value => "setAvailable"} Artikel sind verfügbar
|
||||
%option{:value => '', :selected => 'selected'}= t '.option_select'
|
||||
%option{:value => "destroy", 'data-confirm' => t('.confirm_delete')}= t '.option_delete'
|
||||
%option{:value => "setNotAvailable"}= t '.option_not_available'
|
||||
%option{:value => "setAvailable"}= t '.option_available'
|
||||
= hidden_field_tag 'supplier_id', @supplier.id
|
||||
|
||||
= pagination_links_remote @articles
|
||||
= pagination_links_remote @articles
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
%tr.edit_inline{:id=> "edit_"+@article.id.to_s}
|
||||
%td{:colspan=>"10"}
|
||||
=h @article.name
|
||||
wird in laufenden Bestellungen verwendet und kann nicht gelöscht werden.
|
||||
Bitte zuerst den Artikel aus den Bestellungen
|
||||
= link_to "entfernen", :controller => 'orders', :action => 'edit', :id => @order
|
||||
|
||||
= t('.note', article: h(@article.name), drop_link: link_to(t('.drop'), :controller => 'orders', :action => 'edit', :id => @order)).html_safe
|
||||
|
|
|
@ -2,18 +2,19 @@
|
|||
%thead
|
||||
%tr
|
||||
%th
|
||||
%acronym{:title => "verfügbar"} verf.
|
||||
%th Name
|
||||
%th Einheit
|
||||
%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 => "Netto!"} Preis
|
||||
%acronym{:title => t('.price_desc')}= t '.price_short'
|
||||
%th
|
||||
%acronym{:title => "Gebindegröße"} GebGr
|
||||
%th Best.Nr.
|
||||
%th Notiz
|
||||
%th Kategorie
|
||||
%th MwSt.
|
||||
%th Pfand
|
||||
%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'
|
||||
%tbody
|
||||
- @articles.each_with_index do |article, index|
|
||||
= fields_for "articles[#{article.id || index}]", article do |form|
|
||||
|
@ -31,4 +32,4 @@
|
|||
%td= form.text_field 'deposit', class: 'input-mini'
|
||||
- unless article.errors.empty?
|
||||
%tr.alert
|
||||
%td(colspan="10")= article.errors.full_messages.join(", ")
|
||||
%td(colspan="10")= article.errors.full_messages.join(", ")
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
= f.hidden_field :shared_updated_on
|
||||
= f.hidden_field :supplier_id
|
||||
.modal-header
|
||||
= button_tag "x", class: 'close', data: {dismiss: 'modal'}
|
||||
%h3 Neuen Artikel einfügen
|
||||
= link_to t('ui.marks.close').html_safe, '#', class: 'close', data: {dismiss: 'modal'}
|
||||
%h3= t '.title'
|
||||
.modal-body
|
||||
= f.input :availability
|
||||
= f.input :name
|
||||
|
@ -19,6 +19,6 @@
|
|||
= f.input :tax
|
||||
= f.input :deposit
|
||||
.modal-footer
|
||||
= button_tag "Schließen", class: 'btn', data: {dismiss: 'modal'}
|
||||
= link_to t('ui.close'), '#', class: 'btn', data: {dismiss: 'modal'}
|
||||
= f.submit class: 'btn btn-primary'
|
||||
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
- if @articles.empty?
|
||||
%p Keine Artikel gefunden
|
||||
%p= t '.not_found'
|
||||
- else
|
||||
= pagination_links_remote @articles, :params => {:search => search_params}
|
||||
%table.table.table-striped
|
||||
%thead
|
||||
%tr
|
||||
%th Name
|
||||
%th Herkunft
|
||||
%th Hersteller
|
||||
%th Notiz
|
||||
%th{:style => "width:4em"} Preis
|
||||
%th Einheit
|
||||
%th GebGröße
|
||||
%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
|
||||
%tbody
|
||||
- for article in @articles
|
||||
|
@ -25,9 +25,8 @@
|
|||
%td= article.unit_quantity
|
||||
%td
|
||||
- logger.debug "[debug] #{article.attributes.inspect}"
|
||||
- if @supplier.articles.where(order_number: article.number).exists?
|
||||
%i.icon-ok
|
||||
schon importiert
|
||||
- if @supplier.articles.undeleted.where(order_number: article.number).exists?
|
||||
%i.icon-ok= t '.already_imported'
|
||||
- else
|
||||
= link_to 'importieren', import_supplier_articles_path(@supplier, :shared_article_id => article.id),
|
||||
= link_to t('.action_import'), import_supplier_articles_path(@supplier, :shared_article_id => article.id),
|
||||
:remote => true, class: 'btn btn-small btn-success'
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
- title "Alle Artikel von #{@supplier.name} bearbeiten" |
|
||||
- title t('.title', supplier: @supplier.name)
|
||||
%p
|
||||
%i
|
||||
Pflichtfelder sind: Name, Einheit, (netto) Preis und Bestellnummer.
|
||||
%i= t '.note'
|
||||
= form_tag(update_all_supplier_articles_path(@supplier)) do
|
||||
= render 'edit_all_table'
|
||||
%br/
|
||||
%i Achtung, alle Artikel werden aktualisiert!
|
||||
%i= t '.warning'
|
||||
.form-actions
|
||||
= submit_tag 'Alle Artikel aktualisieren', class: 'btn btn-primary'
|
||||
= link_to 'oder abbrechen', supplier_articles_path(@supplier)
|
||||
= submit_tag t('.submit'), class: 'btn btn-primary'
|
||||
= link_to t('ui.or_cancel'), supplier_articles_path(@supplier)
|
||||
|
|
|
@ -1,47 +1,48 @@
|
|||
- title "Artikel von #{@supplier.name} (#{@supplier.articles.count})"
|
||||
- title t('.title', supplier: @supplier.name, count: @supplier.articles.undeleted.count)
|
||||
|
||||
.well.well-small
|
||||
.btn-toolbar
|
||||
= form_tag supplier_articles_path(@supplier), method: :get, remote: true, class: 'form-search pull-right',
|
||||
'data-submit-onchange' => true do
|
||||
= text_field_tag :query, params[:query], class: 'input-medium search-query',
|
||||
placeholder: 'Name ...'
|
||||
placeholder: t('.search_placeholder')
|
||||
|
||||
.btn-group
|
||||
= link_to "Neuer Artikel", new_supplier_article_path(@supplier), remote: true, class: 'btn btn-primary'
|
||||
= link_to "Alle bearbeiten", edit_all_supplier_articles_path(@supplier), class: 'btn'
|
||||
= link_to "Artikel hochladen", upload_supplier_articles_path(@supplier), class: 'btn'
|
||||
= link_to t('.new'), new_supplier_article_path(@supplier), remote: true, class: 'btn btn-primary'
|
||||
= link_to t('.edit_all'), edit_all_supplier_articles_path(@supplier), class: 'btn'
|
||||
= link_to t('.upload'), upload_supplier_articles_path(@supplier), class: 'btn'
|
||||
- if current_user.role_orders?
|
||||
= link_to "Bestellung anlegen", new_order_path(supplier_id: @supplier), class: 'btn'
|
||||
= link_to t('.new_order'), new_order_path(supplier_id: @supplier), class: 'btn'
|
||||
|
||||
- unless @supplier.shared_supplier.nil?
|
||||
.btn-group
|
||||
= link_to '#', data: {toggle: 'dropdown'}, class: 'btn btn-success dropdown-toggle' do
|
||||
Externe Datenbank
|
||||
= t '.ext_db.title'
|
||||
%span.caret
|
||||
%ul.dropdown-menu
|
||||
%li= link_to "Suchen/Importieren", "#import", 'data-toggle-this' => '#import'
|
||||
%li= link_to "Synchronisieren", sync_supplier_articles_path(@supplier), method: :post
|
||||
%li= link_to t('.ext_db.import'), "#import", 'data-toggle-this' => '#import'
|
||||
%li= link_to t('.ext_db.sync'), sync_supplier_articles_path(@supplier), method: :post
|
||||
|
||||
.btn-group
|
||||
= link_to '#', data: {toggle: 'dropdown'}, class: 'btn dropdown-toggle' do
|
||||
Lieferant wechseln ..
|
||||
= t '.change_supplier'
|
||||
%span.caret
|
||||
%ul.dropdown-menu
|
||||
- Supplier.where('id != ?', @supplier.id).order('name ASC').each do |supplier|
|
||||
- Supplier.undeleted.where('id != ?', @supplier.id).order('suppliers.name ASC').each do |supplier|
|
||||
%li= link_to supplier.name, supplier_articles_path(supplier), tabindex: -1
|
||||
|
||||
- unless @supplier.shared_supplier.nil?
|
||||
#import.well.well-small(style="display:none;")
|
||||
= form_tag shared_supplier_articles_path(@supplier), method: :get, remote: true, class: 'form-search',
|
||||
'data-submit-onchange' => true do
|
||||
%h3 Artikel importieren
|
||||
= text_field_tag "search[name_contains_all]", "", class: 'input-medium search-query', placeholder: 'Name ...'
|
||||
%h3= t '.import.title'
|
||||
= text_field_tag "search[name_contains_all]", "", class: 'input-medium search-query',
|
||||
placeholder: t('.import.placeholder')
|
||||
%label.checkbox
|
||||
= check_box_tag "search[origin_equals]", "REG", false
|
||||
Nur aus der Region
|
||||
= t '.import.restrict_region'
|
||||
#search_results.clearfix
|
||||
= link_to "Schließen", "#import", 'data-toggle-this' => '#import'
|
||||
= link_to t('ui.close'), "#import", 'data-toggle-this' => '#import'
|
||||
|
||||
= form_tag update_selected_supplier_articles_path(@supplier), id: "articlesInListForm",
|
||||
'data-submit-onchange' => true do
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
- title "#{@supplier.name} / Artikel hochladen"
|
||||
%p
|
||||
%i
|
||||
Bitte überprüfe die eingelesenen Artikel.
|
||||
%br/
|
||||
Achtung, momentan gibt es keine Überprüfung auf doppelte Artikel.
|
||||
- title t('.title', supplier: @supplier.name)
|
||||
%p= t('.body').html_safe
|
||||
|
||||
= form_tag(create_from_upload_supplier_articles_path(@supplier)) do
|
||||
= render 'edit_all_table'
|
||||
.form-actions
|
||||
= submit_tag "Speichere neue Artikel für #{@supplier.name}", class: 'btn btn-primary'
|
||||
= link_to "order abbrechen", upload_supplier_articles_path(@supplier)
|
||||
|
||||
= submit_tag t('.submit', supplier: @supplier.name), class: 'btn btn-primary'
|
||||
= link_to t('ui.or_cancel'), upload_supplier_articles_path(@supplier)
|
||||
|
||||
|
|
|
@ -1,71 +1,70 @@
|
|||
%h1 Artikel mit externer Datenbank synchronisieren
|
||||
- title 'Artikel mit externer Datenbank synchronisieren'
|
||||
|
||||
- form_tag update_all_supplier_articles_path(@supplier, :sync => "1") do
|
||||
%h2 Auslisten ...
|
||||
= form_tag update_synchronized_supplier_articles_path(@supplier) do
|
||||
%h2= t '.outlist.title'
|
||||
%p
|
||||
- unless @outlisted_articles.empty?
|
||||
Folgende Artikel wurden ausgelistet und werden
|
||||
%b gelöscht:
|
||||
= t('.outlist.body').html_safe
|
||||
%ul
|
||||
- for article in @outlisted_articles
|
||||
%li
|
||||
= 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.
|
||||
- else
|
||||
%i Es müssen keine Artikel gelöscht werden.
|
||||
%i= t '.outlist.body_skip'
|
||||
%hr/
|
||||
%h2 Aktualisieren ...
|
||||
%h2= t '.update.title'
|
||||
%p
|
||||
%i
|
||||
%b= @updated_articles.size
|
||||
Artikel müssen aktualisiert werden:
|
||||
%p
|
||||
%i
|
||||
Jeder Artikel wird doppelt angezeigt. Die alten Werte sind grau und die Textfelder sind mit den aktuellen
|
||||
Werten vorausgefüllt.
|
||||
%br/
|
||||
Abweichungen zu den alten Artikeln sind gelb markiert.
|
||||
%table
|
||||
%tr
|
||||
%th Name
|
||||
%th Notiz
|
||||
%th Hersteller
|
||||
%th Herkunft
|
||||
%th Einheit
|
||||
%th GebGr
|
||||
%th Preis
|
||||
%th MwSt.
|
||||
%th Pfand
|
||||
%th Kategorie
|
||||
- @updated_articles.each do |@article, unequal_attributes|
|
||||
- article = Article.find(@article.id)
|
||||
%tr{:style => 'color:grey'}
|
||||
%td= article.name
|
||||
%td= article.note
|
||||
%td= article.manufacturer
|
||||
%td= article.origin
|
||||
%td= article.unit
|
||||
%td= article.unit_quantity
|
||||
%td= article.price
|
||||
%td= article.tax
|
||||
%td= article.deposit
|
||||
%td= article.article_category.name if article.article_category
|
||||
= t '.update.update_msg'
|
||||
= t('.update.body').html_safe
|
||||
%table.table
|
||||
%thead
|
||||
%tr
|
||||
- fields_for 'articles[]', @article do |form|
|
||||
%td{:style => highlight_new(unequal_attributes, :name)}
|
||||
= form.text_field 'name', :size => 0
|
||||
= form.hidden_field 'shared_updated_on'
|
||||
%td{:style => highlight_new(unequal_attributes, :note)}= form.text_field 'note', :size => 15
|
||||
%td{:style => highlight_new(unequal_attributes, :manufacturer)}= form.text_field 'manufacturer', :size => 10
|
||||
%td{:style => highlight_new(unequal_attributes, :origin)}= form.text_field 'origin', :size => 5
|
||||
%td{:style => highlight_new(unequal_attributes, :unit)}= form.text_field 'unit', :size => 5
|
||||
%td{:style => highlight_new(unequal_attributes, :unit_quantity)}= form.text_field 'unit_quantity', :size => 5
|
||||
%td{:style => highlight_new(unequal_attributes, :price)}= form.text_field 'price', :size => 5
|
||||
%td{:style => highlight_new(unequal_attributes, :tax)}= form.text_field 'tax', :size => 4
|
||||
%td{:style => highlight_new(unequal_attributes, :deposit)}= form.text_field 'deposit', :size => 4
|
||||
%td= select 'article[]', 'article_category_id', ArticleCategory.find(:all).collect {|a| [ a.name, a.id ] }, { :include_blank => true }
|
||||
%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'
|
||||
%tbody
|
||||
- @updated_articles.each do |updated_article, attrs|
|
||||
- article = Article.find(updated_article.id)
|
||||
%tr{:style => 'color:grey'}
|
||||
%td= article.name
|
||||
%td= article.note
|
||||
%td= article.manufacturer
|
||||
%td= article.origin
|
||||
%td= article.unit
|
||||
%td= article.unit_quantity
|
||||
%td= article.price
|
||||
%td= article.tax
|
||||
%td= article.deposit
|
||||
%td= article.article_category.name if article.article_category
|
||||
%tr
|
||||
= fields_for 'articles[]', updated_article do |form|
|
||||
%td{:style => highlight_new(attrs, :name)}
|
||||
= form.text_field 'name', :size => 0
|
||||
= form.hidden_field 'shared_updated_on'
|
||||
%td{:style => highlight_new(attrs, :note)}= form.text_field 'note', class: 'input-small'
|
||||
%td{:style => highlight_new(attrs, :manufacturer)}= form.text_field 'manufacturer', class: 'input-small'
|
||||
%td{:style => highlight_new(attrs, :origin)}= form.text_field 'origin', class: 'input-mini'
|
||||
%td{:style => highlight_new(attrs, :unit)}= form.text_field 'unit', class: 'input-mini'
|
||||
%td{:style => highlight_new(attrs, :unit_quantity)}= form.text_field 'unit_quantity', class: 'input-mini'
|
||||
%td{:style => highlight_new(attrs, :price)}= form.text_field 'price', class: 'input-mini'
|
||||
%td{:style => highlight_new(attrs, :tax)}= form.text_field 'tax', class: 'input-mini'
|
||||
%td{:style => highlight_new(attrs, :deposit)}= form.text_field 'deposit', class: 'input-mini'
|
||||
%td= form.select :article_category_id, ArticleCategory.all.map {|a| [ a.name, a.id ] },
|
||||
{include_blank: true}, class: 'input-small'
|
||||
%hr/
|
||||
= hidden_field 'supplier', 'id'
|
||||
= submit_tag 'Alle löschen/aktualisieren'
|
||||
|
|
||||
= link_to 'Abbrechen', supplier_articles_path(@supplier)
|
||||
= submit_tag t('.submit'), class: 'btn btn-primary'
|
||||
= link_to t('ui.or_cancel'), supplier_articles_path(@supplier)
|
||||
|
|
|
@ -1,21 +1,24 @@
|
|||
- title "#{@supplier.name} / Artikel hochladen"
|
||||
%p
|
||||
Die Datei muss eine Textdatei mit der Endung '.csv' sein. Die erste Zeile
|
||||
wird beim Einlesen ignoriert.
|
||||
%br/
|
||||
Die Felder müssen mit einem Semikolon (';') getrennt und der Text mit doppelten
|
||||
Anführungszeichen ("Text...") umklammert werden.
|
||||
%br/
|
||||
Als Zeichensatz wird UTF-8 erwartet. Korrekte Reihenfolge der Spalten:
|
||||
%pre
|
||||
= ["Status (x=ausgelistet)", "Bestellnummer", "Name", "Notiz", "Hersteller", "Herkunft",
|
||||
"Einheit", "Preis(netto)", "MwSt", "Pfand", "Gebindegröße",
|
||||
"Staffelmenge", "Staffelpreis", "Kategorie"].join(" | ")
|
||||
- title t('.title', supplier: @supplier.name)
|
||||
= 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'),
|
||||
t('.fields.season_amount'),
|
||||
t('.fields.season_price'),
|
||||
t('simple_form.labels.article.article_category')].join(" | ")
|
||||
|
||||
= form_for :articles, :url => parse_upload_supplier_articles_path(@supplier),
|
||||
:html => { :multipart => true } do |f|
|
||||
%label(for="articles_file")
|
||||
Bitte wähle eine kompatible Datei aus
|
||||
%label(for="articles_file")= t '.file_label'
|
||||
= f.file_field "file"
|
||||
.form-actions
|
||||
= submit_tag "Datei hochladen", class: 'btn'
|
||||
= submit_tag t('.submit'), class: 'btn'
|
||||
|
|
|
@ -21,28 +21,24 @@
|
|||
Menge
|
||||
= stock_change_form.text_field :quantity, size: 5, autocomplete: 'off'
|
||||
= stock_change_form.hidden_field :_destroy
|
||||
= link_to "Artikel aus Lieferung entfernen", "#", class: 'destroy_stock_change'
|
||||
= link_to t('.remove_article'), "#", class: 'destroy_stock_change'
|
||||
%p
|
||||
= link_to "Lagerartikel der Lieferung hinzufügen", {action: 'add_stock_change', supplier_id: @supplier.id}, remote: true
|
||||
= link_to t('.add_article'), {action: 'add_stock_change', supplier_id: @supplier.id}, remote: true
|
||||
%p
|
||||
%small
|
||||
Ist ein Artikel noch nicht in der Lagerverwaltung, muss er erst
|
||||
#{link_to("neu angelegt", new_stock_article_path)} werden.
|
||||
%small= t('.note_new_article', new_link: link_to(t('.note_new_article_link'), new_stock_article_path)).html_safe
|
||||
%hr/
|
||||
= f.input :delivered_on, as: :date_picker
|
||||
= f.input :note, input_html: {size: '35x4'}
|
||||
.form-actions
|
||||
= f.submit class: 'btn btn-primary'
|
||||
= link_to "oder abbrechen", supplier_deliveries_path(@supplier)
|
||||
= link_to t('ui.or_cancel'), supplier_deliveries_path(@supplier)
|
||||
|
||||
/
|
||||
TODO: Fix this!!
|
||||
.span6
|
||||
%h2 Neuen Lagerartikel anlegen
|
||||
%h2= t '.new_article.title'
|
||||
%p
|
||||
Suche nach Artikeln aus dem
|
||||
%i= @supplier.name
|
||||
Katalog:
|
||||
= t('.new_article.search', supplier: @supplier.name).html_safe + ': '
|
||||
= text_field_tag 'article_name'
|
||||
%hr/
|
||||
#stock_article_form
|
||||
|
|
|
@ -3,4 +3,4 @@
|
|||
= form.select :stock_article_id, stock_articles_for_select(supplier)
|
||||
Menge
|
||||
= form.text_field :quantity, :size => 5, :autocomplete => 'off'
|
||||
= link_to "Artikel aus Lieferung entfernen", "#", :class => 'remove_new_stock_change'
|
||||
= link_to t('.remove_article'), "#", :class => 'remove_new_stock_change'
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue