Merge branch 'master' into i18n

Conflicts:
	Gemfile
	config/locales/de.yml
	config/locales/en.yml
This commit is contained in:
wvengen 2013-10-09 23:57:43 +02:00
commit 34a4951e28
21 changed files with 382 additions and 70 deletions

View File

@ -19,6 +19,7 @@ end
gem 'jquery-rails'
gem 'select2-rails'
gem 'bootstrap-datepicker-rails'
gem 'rails-assets-listjs', '0.2.0.beta.4' # remember to maintain list.*.js plugins and template engines on update
gem 'i18n-js', git: 'git://github.com/fnando/i18n-js.git' # to avoid US-ASCII js.erb error
gem 'mysql2'

View File

@ -199,6 +199,8 @@ GEM
activesupport (= 3.2.13)
bundler (~> 1.0)
railties (= 3.2.13)
rails-assets-listjs (0.2.0.beta.4)
railties (>= 3.1)
rails-settings-cached (0.2.4)
rails (>= 3.0.0)
railties (3.2.13)
@ -340,6 +342,7 @@ DEPENDENCIES
prawn
quiet_assets
rails (~> 3.2.9)
rails-assets-listjs (= 0.2.0.beta.4)
rails-settings-cached (= 0.2.4)
resque
rspec-core

View File

@ -8,6 +8,10 @@
//= require bootstrap-datepicker/locales/bootstrap-datepicker.de
//= require bootstrap-datepicker/locales/bootstrap-datepicker.nl
//= require jquery.observe_field
//= require list
//= require list.unlist
//= require list.delay
//= require list.reset
//= require rails.validations
//= require i18n
//= require i18n/translations

View File

@ -0,0 +1,50 @@
// for use with listjs 0.2.0
// https://github.com/javve/list.js
(function(window, undefined) {
window.List.prototype.plugins.delay = function(locals, options) {
var list = this;
this.searchTimeout = undefined;
var init = {
start: function(options) {
this.defaults(options);
this.callbacks(options);
this.onload(options);
},
defaults: function(options) {
options.delayedSearchClass = options.delayedSearchClass || 'delayed-search';
options.delayedSearchTime = options.delayedSearchTime || 500;
},
callbacks: function(options) {
$('.' + options.delayedSearchClass, list.listContainer).keyup(list.searchDelayStart);
},
onload: function(options) {
var initialSearchTerm = $('.' + options.delayedSearchClass, list.listContainer).val();
if('' != initialSearchTerm) {
list.search(initialSearchTerm);
}
}
};
this.searchDelayStart = function(searchString, columns) {
// TODO: if keycode corresponds to 'ENTER' ? skip delay
clearTimeout(list.searchTimeout);
list.searchTimeout = window.setTimeout(
function() {list.searchDelayEnd(searchString, columns)},
options.delayedSearchTime
);
$(list.listContainer).trigger('updateComing');
};
this.searchDelayEnd = function(searchString, columns) {
list.search(searchString, columns);
};
init.start(options);
}
})(window);

View File

@ -0,0 +1,42 @@
// for use with listjs 0.2.0
// https://github.com/javve/list.js
(function(window, undefined) {
window.List.prototype.plugins.reset = function(locals, options) {
var list = this;
var init = {
start: function(options) {
this.defaults(options);
this.callbacks(options);
},
defaults: function(options) {
options.highlightClass = options.highlightClass || 'btn-primary';
options.resetSearchClass = options.resetSearchClass || 'reset-search';
options.resettableClass = options.resettableClass || 'resettable';
},
callbacks: function(options) {
$('.' + options.resetSearchClass, list.listContainer).click(list.resetSearch);
list.on('updated', list.highlightResetButton);
$(list.listContainer).on('updateComing', function() {
list.highlightResetButton(false);
});
}
};
this.highlightResetButton = function(highlightEnabled) {
highlightEnabled = (undefined === highlightEnabled) ? (list.searched) : (highlightEnabled);
$('.' + options.resetSearchClass, list.listContainer).toggleClass(options.highlightClass, highlightEnabled);
};
this.resetSearch = function() {
$('.' + options.resettableClass, list.listContainer).val('');
list.search('');
};
init.start(options);
}
})(window);

View File

@ -0,0 +1,124 @@
// for use with listjs 0.2.0
// https://github.com/javve/list.js
/*******************************************************************************
********************************************************************************
The following code is a modification of list.js. It was created by copy-pasting
the original code with the copyright notice below.
********************************************************************************
*******************************************************************************/
/*******************************************************************************
Begin copyright notice of the original code
*******************************************************************************/
/*
ListJS Beta 0.2.0
By Jonny Strömberg (www.jonnystromberg.com, www.listjs.com)
OBS. The API is not frozen. It MAY change!
License (MIT)
Copyright (c) 2011 Jonny Strömberg http://jonnystromberg.com
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
/*******************************************************************************
End copyright notice of the original code
*******************************************************************************/
(function(w, undefined) {
/*******************************************************************************
Begin copy-pasted and modified code
*******************************************************************************/
// * template engine which adds class 'unlisted' instead of removing from DOM
// * especially useful in case of formulars
// * uses jQuery's $
w.List.prototype.templateEngines.unlist = function(list, settings) {
var h = w.ListJsHelpers;
// start with standard engine, override specific methods afterwards
this.superClass = w.List.prototype.templateEngines.standard;
this.superClass(list, settings);
// todo refer to listjs code instead of copy-pasting
var listSource = h.getByClass(settings.listClass, list.listContainer, true);
var templater = this;
var ensure = {
created: function(item) {
if(item.elm === undefined) {
templater.create(item);
}
}
};
var init = {
start: function(options) {
this.defaults(options);
this.callbacks(options);
},
defaults: function(options) {
options.listHeadingsClass = options.listHeadingsClass || 'list-heading';
},
callbacks: function(options) {
list.on('updated', templater.updateListHeadings);
}
};
this.show = function(item) {
ensure.created(item);
listSource.appendChild(item.elm); // append item (or move it to the end)
$(item.elm).removeClass('unlisted');
};
this.hide = function(item) {
ensure.created(item);
$(item.elm).addClass('unlisted');
listSource.appendChild(item.elm);
};
this.clear = function() {
$(listSource.childNodes).addClass('unlisted');
};
this.updateListHeadings = function() {
var headSel = '.' + settings.listHeadingsClass;
$(headSel, listSource).each(function() {
var listedCount = $(this).nextUntil(headSel, ':not(.unlisted)').length;
$(this).toggleClass('unlisted', 0==listedCount);
});
};
init.start(settings);
};
/*******************************************************************************
End copy-pasted and modified code
*******************************************************************************/
})(window);

View File

@ -3,4 +3,5 @@
*= require select2
*= require token-input-bootstrappy
*= require bootstrap-datepicker
*= require list.unlist
*/

View File

@ -238,3 +238,8 @@ tr.unavailable {
margin-bottom: 15px
}
}
// allow buttons as input add-on (with proper height)
.input-append button.add-on {
height: inherit;
}

View File

@ -0,0 +1,3 @@
.list .unlisted:not(.no-unlist) {
display: none;
}

View File

@ -31,6 +31,11 @@ class StockitController < ApplicationController
end
end
def show
@stock_article = StockArticle.find(params[:id])
@stock_changes = @stock_article.stock_changes.order('stock_changes.created_at DESC')
end
def destroy
@article = StockArticle.find(params[:id])
@article.mark_as_deleted
@ -55,9 +60,4 @@ class StockitController < ApplicationController
render :partial => 'form', :locals => {:stock_article => stock_article}
end
def history
@stock_article = StockArticle.undeleted.find(params[:stock_article_id])
@stock_changes = @stock_article.stock_changes.order('stock_changes.created_at DESC').each {|s| s.readonly!}
end
end

View File

@ -6,12 +6,17 @@
setMinimumBalance(#{FoodsoftConfig[:minimum_balance] or 0});
setToleranceBehaviour(#{FoodsoftConfig[:tolerance_is_costly]});
setStockit(#{@order.stockit?});
// create List for search-feature (using list.js, http://listjs.com)
var listjsResetPlugin = ['reset', {highlightClass: 'btn-primary'}];
var listjsDelayPlugin = ['delay', {delayedSearchTime: 500}];
new List(document.body, { valueNames: ['name'], engine: 'unlist', plugins: [listjsResetPlugin, listjsDelayPlugin] });
});
- title t('.title'), false
.row-fluid
.well.pull-left
%button{type: "button", class: "close", data: {dismiss: 'alert'}}= '&times;'.html_safe
%h2= @order.name
%dl.dl-horizontal
- unless @order.note.blank?
@ -34,8 +39,17 @@
%dd= number_to_currency(@ordering_data[:available_funds])
.well.pull-right
%button{type: "button", class: "close", data: {dismiss: 'alert'}}= '&times;'.html_safe
= render 'switch_order', current_order: @order
.row-fluid
.well.clear
.form-search
.input-append
= text_field_tag :article, params[:article], placeholder: t('.search_article'), class: 'search-query delayed-search resettable'
%button.add-on.btn.reset-search{:type => :button, :title => t('.reset_article_search')}
%i.icon.icon-remove
= form_for @group_order do |f|
= f.hidden_field :lock_version
= f.hidden_field :order_id
@ -58,9 +72,9 @@
%th(style="width:20px")= t '.available'
%th#col_required= t '.amount'
%th{style: "width:15px;"}= t '.sum'
%tbody
%tbody.list
- @order.articles_grouped_by_category.each do |category, order_articles|
%tr.article-category
%tr.list-heading.article-category
%td
= category
%i.icon-tag

View File

@ -3,5 +3,6 @@
= form.hidden_field :stock_article_id
= "Menge (#{stock_change.stock_article.quantity_available})"
= form.text_field :quantity, :size => 5, :autocomplete => 'off'
%b= stock_change.stock_article.name
= "(#{number_to_currency(stock_change.stock_article.price)} / #{stock_change.stock_article.unit})"
%span{:data => {:toggle => :tooltip, :title => render(:partial => 'shared/article_price_info', :locals => {:article => stock_change.stock_article})}}
%b= stock_change.stock_article.name
= "(#{number_to_currency(stock_change.stock_article.price)} / #{stock_change.stock_article.unit})"

View File

@ -1,5 +1,20 @@
- title t('.title')
- content_for :javascript do
:javascript
$(function() {
enablePriceTooltips();
});
function enablePriceTooltips(context) {
$('[data-toggle~="tooltip"]', context).tooltip({
animation: false,
html: true,
placement: 'left',
container: 'body'
});
}
- content_for :sidebar do
%p
%i= t('.text_deviations', inv_link: link_to(t('.temp_inventory'), stock_articles_path)).html_safe

View File

@ -1,17 +0,0 @@
- title t('.stock_changes', :article_name => @stock_article.name)
%table.table.table-hover#stock_changes
%thead
%tr
%th= t '.datetime'
%th= t '.reason'
%th= t '.change_quantity'
%th= t '.new_quantity'
%tbody
- reversed_history = @stock_article.quantity_history.reverse
- @stock_changes.each_with_index do |stock_change, index|
%tr
%td= l stock_change.created_at
%td= link_to_stock_change_reason(stock_change)
%td= stock_change.quantity
%td= reversed_history[index]

View File

@ -45,7 +45,7 @@
%tbody
- for article in @stock_articles
%tr{:class => stock_article_classes(article), :id => "stockArticle-#{article.id}"}
%td=h article.name
%td= link_to article.name, article
%td= article.quantity
%td= article.quantity - article.quantity_available
%th= article.quantity_available
@ -56,7 +56,6 @@
%td= article.article_category.name
%td
= link_to t('ui.edit'), edit_stock_article_path(article), class: 'btn btn-mini'
= link_to t('ui.history'), stock_article_history_path(article), class: 'btn btn-mini'
= link_to t('ui.delete'), article, :method => :delete, :confirm => t('.confirm_delete'),
class: 'btn btn-mini btn-danger', :remote => true
%p

View File

@ -0,0 +1,47 @@
- title @stock_article.name
.row-fluid
.span6
%dl.dl-horizontal
%dt= StockArticle.human_attribute_name 'supplier'
%dd= link_to @stock_article.supplier.name, @stock_article.supplier
%dt= StockArticle.human_attribute_name 'name'
%dd= @stock_article.name
%dt= StockArticle.human_attribute_name 'unit'
%dd= @stock_article.unit
%dt= StockArticle.human_attribute_name 'price'
%dd= number_to_currency @stock_article.price
%dt= StockArticle.human_attribute_name 'tax'
%dd= number_to_percentage @stock_article.tax
%dt= StockArticle.human_attribute_name 'deposit'
%dd= number_to_currency @stock_article.deposit
%dt= StockArticle.human_attribute_name 'fc_price'
%dd= number_to_currency @stock_article.fc_price
%dt= StockArticle.human_attribute_name 'article_category'
%dd= @stock_article.article_category.name
%dt= StockArticle.human_attribute_name 'note'
%dd= @stock_article.note
%dt= StockArticle.human_attribute_name 'quantity'
%dd= @stock_article.quantity
%dt= StockArticle.human_attribute_name 'quantity_available'
%dd= @stock_article.quantity_available
.form-actions
= link_to t('ui.edit'), edit_stock_article_path(@stock_article), class: 'btn'
.span6
%h2= t('.stock_changes')
%table.table.table-hover#stock_changes
%thead
%tr
%th= t '.datetime'
%th= t '.reason'
%th= t '.change_quantity'
%th= t '.new_quantity'
%tbody
- reversed_history = @stock_article.quantity_history.reverse
- @stock_changes.each_with_index do |stock_change, index|
%tr
%td= l stock_change.created_at
%td= link_to_stock_change_reason(stock_change)
%td= stock_change.quantity
%td= reversed_history[index]

View File

@ -42,7 +42,10 @@ de:
fc_price: Endpreis
fc_share: FC-Aufschlag
gross_price: Bruttopreis
name: Name
note: Notiz
price: Nettopreis
supplier: Lieferantin
tax: MwSt
unit: Einheit
unit_quantity: Gebindegröße
@ -66,6 +69,8 @@ de:
supplier: Lieferant
stock_article:
price: Nettopreis
quantity: Lagerbestand
quantity_available: Verfügbarer Bestand
supplier:
address: Adresse
contact_person: Ansprechparter_in
@ -839,6 +844,8 @@ de:
new_funds: Neuer Kontostand
note: Notiz
price: Preis
reset_article_search: Suche zurücksetzen
search_article: Artikel suchen...
sum: Summe
sum_amount: ! 'Gesamtbestellmenge bisher:'
supplier: Lieferant
@ -1739,15 +1746,6 @@ de:
title: Lagerartikel bearbeiten
form:
price_hint: Um Chaos zu vermeiden können bis auf weiteres die Preise von angelegten Lagerartikeln nicht mehr verändert werden.
history:
change_quantity: Veränderung
datetime: Zeitpunkt
delivery: Lieferung
new_quantity: Neuer Bestand
order: Bestellung
reason: Ereignis
stock_changes: Verlauf anzeigen für »%{article_name}«
stock_taking: Inventur
index:
article:
article: Artikel
@ -1773,6 +1771,15 @@ de:
new:
search_text: ! 'Suche nache Artikeln aus allen Katalogen:'
title: Neuen Lagerartikel anlegen
show:
change_quantity: Veränderung
datetime: Zeitpunkt
delivery: Lieferung
new_quantity: Neuer Bestand
order: Bestellung
reason: Ereignis
stock_changes: Verlauf des Lagerbestands
stock_taking: Inventur
stock_create:
notice: Lagerartikel wurde gespeichert.
stock_update:
@ -1898,7 +1905,6 @@ de:
close: Schließen
delete: Löschen
edit: Bearbeiten
history: Verlauf anzeigen
marks:
close: ! '&times;'
success: <i class="icon icon-ok"></i>

View File

@ -50,6 +50,7 @@ en:
note: Note
origin: Origin
price: Price
supplier: Supplier
tax: VAT
unit: Unit
unit_quantity: Unit quantity
@ -76,6 +77,8 @@ en:
supplier: Supplier
stock_article:
price: Price
quantity: Quantity
quantity_available: Available quantity
supplier:
address: Address
contact_person: Contact person
@ -858,6 +861,8 @@ en:
new_funds: New account balance
note: Note
price: Price
reset_article_search: Reset search
search_article: Search for article...
sum: Sum
sum_amount: Current amount
supplier: Supplier
@ -1740,15 +1745,6 @@ en:
title: Edit stock articles
form:
price_hint: To avoid choas, it is not possible to edit the prices of already added stock articles until further notice.
history:
change_quantity: Change
datetime: Time
delivery: Delivery
new_quantity: New quantity
order: Order
reason: Reason
stock_changes: Stock quantity changes of %{article_name}
stock_taking: Inventory
index:
article:
article: Article
@ -1774,6 +1770,15 @@ en:
new:
search_text: ! 'Search for articles in all catalogues:'
title: Add new stock article
show:
change_quantity: Change
datetime: Time
delivery: Delivery
new_quantity: New quantity
order: Order
reason: Reason
stock_changes: Stock quantity changes
stock_taking: Inventory
stock_create:
notice: Stock article was created.
stock_update:
@ -1898,7 +1903,6 @@ en:
close: Close
delete: Delete
edit: Edit
history: Show history
marks:
close: ! '&times;'
success: <i class="icon icon-ok"></i>

View File

@ -42,7 +42,10 @@ fr:
fc_price: prix final
fc_share: supplément boufcoop
gross_price: prix brut
name:
note:
price: prix net
supplier:
tax: TVA
unit: unité
unit_quantity: unités par lot
@ -51,6 +54,8 @@ fr:
note: note
stock_article:
price: Prix net
quantity:
quantity_available:
user:
first_name: Prénom
password: Mot de passe
@ -811,6 +816,8 @@ fr:
new_funds: Nouveau solde
note: Note
price: Prix
reset_article_search:
search_article:
sum: Prix total
sum_amount: ! 'Quantité déjà commandée:'
supplier: Fourni par
@ -1738,15 +1745,6 @@ fr:
title: Modifier l'article
form:
price_hint: Pour éviter que ça soit le bazar, les prix des articles en stock ne peuvent plus être modifiés.
history:
change_quantity: Modification
datetime: Temps
delivery: Réapprovisionnement
new_quantity: Nouveau stock
order: Commande
reason: Raison
stock_changes: Afficher l'historique pour "%{article_name}"
stock_taking: Inventaire
index:
article:
article: Article
@ -1772,6 +1770,15 @@ fr:
new:
search_text: ! 'Rechercher des articles dans tous les catalogues:'
title: Ajouter un article au stock
show:
change_quantity: Modification
datetime: Temps
delivery: Réapprovisionnement
new_quantity: Nouveau stock
order: Commande
reason: Raison
stock_changes: Afficher l'historique
stock_taking: Inventaire
stock_create:
notice: L'article a été sauvegardé.
stock_update:
@ -1904,7 +1911,6 @@ fr:
close: Fermer
delete: Supprimer
edit: Modifier
history: Afficher l'historique
marks:
close: ! '&times;'
success: <i class="icon icon-ok"></i>

View File

@ -42,7 +42,10 @@ nl:
fc_price: prijs foodcoop
fc_share: marge foodcoop
gross_price: bruto prijs
name:
note:
price: netto prijs
supplier:
tax: BTW
unit: eenheid
unit_quantity: groothandelseenheid
@ -51,6 +54,8 @@ nl:
note: notitie
stock_article:
price: prijs
quantity:
quantity_available:
user:
first_name: Voornaam
password: Wachtwoord
@ -797,6 +802,8 @@ nl:
new_funds: Nieuw tegoed
note: Notitie
price: Prijs
reset_article_search:
search_article:
sum: Som
sum_amount: ! 'Huidig totaalbedrag:'
supplier: Leverancier
@ -1664,15 +1671,6 @@ nl:
title:
form:
price_hint:
history:
change_quantity:
datetime:
delivery:
new_quantity:
order:
reason:
stock_changes:
stock_taking:
index:
article:
article:
@ -1698,6 +1696,15 @@ nl:
new:
search_text:
title:
show:
change_quantity:
datetime:
delivery:
new_quantity:
order:
reason:
stock_changes:
stock_taking:
stock_create:
notice: Voorraadsartikel is opgeslagen.
stock_update:
@ -1822,7 +1829,6 @@ nl:
close: Sluiten
delete: Verwijder
edit: Bewerk
history:
marks:
close: ! '&times;'
success: <i class="icon icon-ok"></i>

View File

@ -97,8 +97,6 @@ Foodsoft::Application.routes.draw do
get :articles_search
get :fill_new_stock_article_form
end
get :history
end
resources :suppliers do