diff --git a/app/controllers/stockit_controller.rb b/app/controllers/stockit_controller.rb index d555b4c3..2a232a31 100644 --- a/app/controllers/stockit_controller.rb +++ b/app/controllers/stockit_controller.rb @@ -1,8 +1,8 @@ class StockitController < ApplicationController def index - @stock_articles = StockArticle.elements_for_index - @stock_article_selection = StockArticleSelection.new + @stock_articles = StockArticle.includes(:supplier, :article_category). + order('suppliers.name, article_categories.name, articles.name') end def new @@ -32,11 +32,12 @@ class StockitController < ApplicationController end def destroy - StockArticle.find(params[:id]).destroy - redirect_to stock_articles_path + @article = StockArticle.find(params[:id]) + @article.destroy + render :layout => false rescue => error - flash[:error] = "Ein Fehler ist aufgetreten: " + error.message - redirect_to stock_articles_path + render :partial => "destroy_fail", :layout => false, + :locals => { :fail_msg => "Ein Fehler ist aufgetreten: " + error.message } end #TODO: Fix this!! diff --git a/app/controllers/stockit_selections_controller.rb b/app/controllers/stockit_selections_controller.rb deleted file mode 100644 index 6e89b5dc..00000000 --- a/app/controllers/stockit_selections_controller.rb +++ /dev/null @@ -1,61 +0,0 @@ -# encoding: utf-8 -class StockitSelectionsController < ApplicationController - - def index - @stock_article_selections = StockArticleSelection.find(:all, :order => 'created_at DESC') - end - - def show - @stock_article_selection = StockArticleSelection.find(params[:id]) - end - - def create - @stock_article_selection = StockArticleSelection.new(params[:stock_article_selection]) - @stock_article_selection.created_by = current_user - - if @stock_article_selection.save - redirect_to(@stock_article_selection, :notice => 'Löschvorschlag für gewählte Artikel erstellt.') - else - @stock_articles = StockArticle.elements_for_index - render 'stockit/index' - end - end - - def destroy # destroy selection without deleting articles - stock_article_selection = StockArticleSelection.find(params[:id]) - stock_article_selection.destroy - - redirect_to stock_article_selections_path, :notice => 'Löschvorschlag verworfen.' - end - - def articles # destroy articles - stock_article_selection = StockArticleSelection.find(params[:id]) - - destroyed_articles_count = 0 - failed_articles_count = 0 - stock_article_selection.stock_articles.each do |article| - begin - article.destroy - destroyed_articles_count += 1 - rescue => error # recover if article.destroy fails and continue with next article - failed_articles_count += 1 - end - end - - if destroyed_articles_count > 0 - flash[:notice] = "#{destroyed_articles_count} gewählte Artikel gelöscht." - flash[:error] = "#{failed_articles_count} Artikel konnten nicht gelöscht werden." unless 0==failed_articles_count - else - flash[:error] = 'Löschvorgang fehlgeschlagen. Keine Artikel gelöscht.' - end - - redirect_to stock_articles_path - end - - def finished # delete all finished selections - finished_selections = StockArticleSelection.all.select { |sel| sel.deletable_count + sel.nondeletable_count <= 0 } - finished_selections.each { |sel| sel.destroy } - - redirect_to stock_article_selections_path, :notice => 'Alle erledigten Löschvorschläge entfernt.' - end -end diff --git a/app/helpers/stock_article_selections_helper.rb b/app/helpers/stock_article_selections_helper.rb deleted file mode 100644 index 5d9d7737..00000000 --- a/app/helpers/stock_article_selections_helper.rb +++ /dev/null @@ -1,18 +0,0 @@ -# encoding: utf-8 -module StockArticleSelectionsHelper - def article_deletion_classes(article) - className = "label label-success" # usual deletable case, maybe modified below - className = "label label-important" if article.quantity_available > 0 - className = "label" if article.deleted? - - className - end - - def article_deletion_title(article) - myTitle = "Löschbar" # usual deletable case, maybe modified below - myTitle = "Nicht löschbar, da im Lager vorhanden" if article.quantity_available > 0 - myTitle = "Bereits gelöscht" if article.deleted? - - myTitle - end -end diff --git a/app/helpers/stockit_helper.rb b/app/helpers/stockit_helper.rb index c2665a96..2888603c 100644 --- a/app/helpers/stockit_helper.rb +++ b/app/helpers/stockit_helper.rb @@ -1,18 +1,7 @@ -# encoding: utf-8 module StockitHelper def stock_article_classes(article) class_names = [] class_names << "unavailable" if article.quantity_available <= 0 class_names.join(" ") end - - def stock_article_delete_checkbox(article) - if article.quantity_available <= 0 - check_box_tag "stock_article_selection[stock_article_ids][]", article.id, false, - { :id => "checkbox_#{article.id}", :title => 'Zum löschen markieren' } - else - check_box_tag 'checkall', '1', false, - { :disabled => true, :title => 'Verfügbare Artikel können nicht gelöscht werden.', :class => 'unavailable' } - end - end end diff --git a/app/models/group.rb b/app/models/group.rb index c1976830..68cb015c 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -4,7 +4,7 @@ class Group < ActiveRecord::Base has_many :memberships, :dependent => :destroy has_many :users, :through => :memberships - validates :name, :presence => true, :length => {:in => 1..25}, :uniqueness => true + validates :name, :presence => true, :length => {:in => 1..25} attr_reader :user_tokens diff --git a/app/models/ordergroup.rb b/app/models/ordergroup.rb index 3d863834..dbfe3171 100644 --- a/app/models/ordergroup.rb +++ b/app/models/ordergroup.rb @@ -16,7 +16,7 @@ class Ordergroup < Group has_many :orders, :through => :group_orders validates_numericality_of :account_balance, :message => 'ist keine gültige Zahl' - validate :uniqueness_of_members + validate :uniqueness_of_name, :uniqueness_of_members after_create :update_stats! @@ -106,6 +106,16 @@ class Ordergroup < Group errors.add :user_tokens, "#{user.nick} ist schon in einer anderen Bestellgruppe" if user.groups.where(:type => 'Ordergroup').size > 1 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.with_deleted.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 diff --git a/app/models/stock_article.rb b/app/models/stock_article.rb index 478e6c78..6050c8c4 100644 --- a/app/models/stock_article.rb +++ b/app/models/stock_article.rb @@ -22,11 +22,6 @@ class StockArticle < Article def self.stock_value available.collect { |a| a.quantity * a.gross_price }.sum end - - def self.elements_for_index - StockArticle.includes(:supplier, :article_category). - order('suppliers.name, article_categories.name, articles.name') - end protected diff --git a/app/models/stock_article_selection.rb b/app/models/stock_article_selection.rb deleted file mode 100644 index a66c61f2..00000000 --- a/app/models/stock_article_selection.rb +++ /dev/null @@ -1,36 +0,0 @@ -# encoding: utf-8 -class StockArticleSelection < ActiveRecord::Base - - # Associations - has_and_belongs_to_many :stock_articles - belongs_to :created_by, :class_name => 'User', :foreign_key => 'created_by_user_id' - belongs_to :finished_by, :class_name => 'User', :foreign_key => 'finished_by_user_id' - - # Validations - validate :include_stock_articles - - def all_articles - all_articles = stock_article_ids - end - - def deletable_count - stock_articles.select { |a| a.quantity_available<=0 }.length - end - - def nondeletable_count - stock_articles.select { |a| a.quantity_available>0 }.length - end - - def deleted_count - stock_articles.only_deleted.count - end - - protected - - def include_stock_articles - errors.add(:stock_articles, "Es muss mindestens ein Lagerartikel ausgewählt sein.") if stock_articles.empty? - end - - private - -end diff --git a/app/models/supplier.rb b/app/models/supplier.rb index 05dbeb6c..384c5973 100644 --- a/app/models/supplier.rb +++ b/app/models/supplier.rb @@ -12,15 +12,13 @@ class Supplier < ActiveRecord::Base attr_accessible :name, :address, :phone, :phone2, :fax, :email, :url, :contact_person, :customer_number, :delivery_days, :order_howto, :note, :shared_supplier_id, :min_order_quantity - validates :name, :presence => true, :length => { :in => 4..30 }, :uniqueness => true + validates :name, :presence => true, :length => { :in => 4..30 } validates :phone, :presence => true, :length => { :in => 8..20 } validates :address, :presence => true, :length => { :in => 8..50 } validates_length_of :order_howto, :note, maximum: 250 -# validates_length_of :name, :in => 4..30 -# validates_uniqueness_of :name - validates_length_of :phone, :in => 8..20 validates_length_of :address, :in => 8..50 + validate :uniqueness_of_name # sync all articles with the external database # returns an array with articles(and prices), which should be updated (to use in a form) @@ -66,5 +64,17 @@ class Supplier < ActiveRecord::Base end return [updated_articles, outlisted_articles] 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 + if supplier.present? + message = supplier.deleted? ? :taken_with_deleted : :taken + errors.add :name, message + end + end end diff --git a/app/models/workgroup.rb b/app/models/workgroup.rb index 5b201932..5a5855e7 100644 --- a/app/models/workgroup.rb +++ b/app/models/workgroup.rb @@ -5,6 +5,7 @@ class Workgroup < Group # returns all non-finished tasks has_many :open_tasks, :class_name => 'Task', :conditions => ['done = ?', false], :order => 'due_date ASC' + validates_uniqueness_of :name validates_presence_of :task_name, :weekday, :task_required_users, :next_weekly_tasks_number, :if => :weekly_task validates_numericality_of :next_weekly_tasks_number, :greater_than => 0, :less_than => 21, :only_integer => true, @@ -61,7 +62,7 @@ class Workgroup < Group # add validation check on update # 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 => true, :id.ne => id).empty? + 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") end end diff --git a/app/views/stockit/_destroy_fail.js.haml b/app/views/stockit/_destroy_fail.js.haml new file mode 100644 index 00000000..a9601900 --- /dev/null +++ b/app/views/stockit/_destroy_fail.js.haml @@ -0,0 +1,5 @@ +-# please polish the following line if you know how, same in view destroy +var errorDiv = $('
x
'); + +errorDiv.append(document.createTextNode('#{j(fail_msg)}')); +$('div.container-fluid').prepend(errorDiv); diff --git a/app/views/stockit/destroy.js.haml b/app/views/stockit/destroy.js.haml new file mode 100644 index 00000000..66d6d70d --- /dev/null +++ b/app/views/stockit/destroy.js.haml @@ -0,0 +1,14 @@ +-# please polish the following line if you know how, same in partial _destroy_fail +var successDiv = $('
x
'); + +successDiv.append(document.createTextNode('Artikel #{j(@article.name)} gelöscht.')); +$('div.container-fluid').prepend(successDiv); + +-# WARNING: If you try to use the escape j(...) here, an error occurs: +-# Ein Fehler ist aufgetreten: undefined method `gsub' for 50:Fixnum +-# However, it should work without without escaping. +-# Note that article names which are purely numeric, e.g. 12345, are escaped correctly (see above). + +$('#stockArticle-#{@article.id}').remove(); + +-# WARNING: Do not use a simple .fadeOut() above, because it conflicts with the show/hide function of unavailable articles. diff --git a/app/views/stockit/index.html.haml b/app/views/stockit/index.html.haml index 89063bd7..c69c1689 100644 --- a/app/views/stockit/index.html.haml +++ b/app/views/stockit/index.html.haml @@ -2,7 +2,7 @@ - content_for :javascript do :javascript $(function() { - $('tr.unavailable,input.unavailable,div.unavailable').hide(); + $('tr.unavailable').hide(); }) .well.well-small @@ -12,7 +12,7 @@ Ansichtsoptionen %span.caret %ul.dropdown-menu - %li= link_to "Nicht verfügbare Artikel zeigen/verstecken", "#", 'data-toggle-this' => 'tr.unavailable,input.unavailable,div.unavailable', tabindex: -1 + %li= link_to "Nicht verfügbare Artikel zeigen/verstecken", "#", 'data-toggle-this' => 'tr.unavailable', tabindex: -1 .btn-group = link_to_if @current_user.role_orders?, "Lagerbestellung online stellen", new_order_path(supplier_id: 0), @@ -20,7 +20,6 @@ = link_to "Neuen Lagerartikel anlegen", new_stock_article_path, class: 'btn' = link_to "Inventur anlegen", new_stock_taking_path, class: 'btn' = link_to "Inventurübersicht", stock_takings_path, class: 'btn' - = link_to 'Löschvorschläge', stock_article_selections_path, class: 'btn' .btn-group = link_to '#', data: {toggle: 'dropdown'}, class: 'btn dropdown-toggle' do @@ -30,44 +29,36 @@ - Supplier.all.each do |supplier| %li= link_to supplier.name, new_supplier_delivery_path(supplier), tabindex: -1 -= form_for @stock_article_selection do |form| - - if @stock_article_selection.errors.has_key?(:stock_articles) - .alert.alert-error - = @stock_article_selection.errors.get(:stock_articles).join(" ") - %table.table.table-hover#articles - %thead - %tr - %th= check_box_tag 'checkall', '1', false, - { 'data-check-all' => 'table#articles tr.unavailable', :title => 'Alle löschbaren Artikel', :class => 'unavailable' } - %th Artikel - %th im Lager - %th davon bestellt - %th verfügbar - %th Einheit - %th Preis - %th MwSt - %th Lieferantin - %th Kategorie - %th - %tbody - - for article in @stock_articles - %tr{:class => stock_article_classes(article)} - %td= stock_article_delete_checkbox(article) - %td=h article.name - %td= article.quantity - %td= article.quantity - article.quantity_available - %th= article.quantity_available - %td= article.unit - %td= article.price - %td= number_to_percentage article.tax - %td= link_to article.supplier.name, article.supplier - %td= article.article_category.name - %td - = link_to "Bearbeiten", edit_stock_article_path(article), class: 'btn btn-mini' - = link_to "Löschen", article, :method => :delete, :confirm => "Bist Du sicher?", - class: 'btn btn-mini btn-danger' - .form-actions.unavailable - = submit_tag "Artikel zum Löschen vormerken", { :class => 'unavailable btn' } +%table.table.table-hover#articles + %thead + %tr + %th Artikel + %th im Lager + %th davon bestellt + %th verfügbar + %th Einheit + %th Preis + %th MwSt + %th Lieferantin + %th Kategorie + %th + %tbody + - for article in @stock_articles + %tr{:class => stock_article_classes(article), :id => "stockArticle-#{article.id}"} + %td=h article.name + %td= article.quantity + %td= article.quantity - article.quantity_available + %th= article.quantity_available + %td= article.unit + %td= article.price + %td= number_to_percentage article.tax + %td= link_to article.supplier.name, article.supplier + %td= article.article_category.name + %td + = link_to "Bearbeiten", edit_stock_article_path(article), class: 'btn btn-mini' + = link_to "Löschen", article, :method => :delete, :confirm => "Bist Du sicher?", + class: 'btn btn-mini btn-danger', :remote => true + %p Aktueller Lagerwert: = number_to_currency StockArticle.stock_value diff --git a/app/views/stockit_selections/_overview.html.haml b/app/views/stockit_selections/_overview.html.haml deleted file mode 100644 index 5663fb4c..00000000 --- a/app/views/stockit_selections/_overview.html.haml +++ /dev/null @@ -1,26 +0,0 @@ - -%table.table.table-hover - %tr - %th Artikel - %th Zusammenfassung - %th Erstellt am - %th Erstellt von - %th Optionen - - - stock_article_selections.each do |stock_article_selection| - %tr - %td - - for article in stock_article_selection.stock_articles.with_deleted - %span{:class => article_deletion_classes(article), :title => article_deletion_title(article)}= article.name - %td - %span{:class => 'label label-success'}= "#{stock_article_selection.deletable_count} Löschbar" - %span{:class => 'label'}= "#{stock_article_selection.deleted_count} Gelöscht" - %span{:class => 'label label-important'}= "#{stock_article_selection.nondeletable_count} Nicht löschbar" - %td= format_date(stock_article_selection.created_at) - %td= link_to_user_message_if_valid stock_article_selection.created_by - %td - = link_to 'Anzeigen', stock_article_selection, class: 'btn btn-small' - = link_to "Artikel löschen", articles_stock_article_selection_path(stock_article_selection), :method => :delete, - :confirm => 'Diesen Löschvorschlag wirklich ausführen und markierte Artikel löschen?', class: 'btn btn-small btn-danger' - = link_to "Verwerfen", stock_article_selection, :method => :delete, - :confirm => 'Diesen Löschvorschlag wirklich verwerfen?', class: 'btn btn-small' diff --git a/app/views/stockit_selections/index.html.haml b/app/views/stockit_selections/index.html.haml deleted file mode 100644 index f189f2ca..00000000 --- a/app/views/stockit_selections/index.html.haml +++ /dev/null @@ -1,25 +0,0 @@ -- title "Löschvorschläge für Lagerartikel" - -.well.well-small - .btn-toolbar - .btn-group - = link_to "Lager anzeigen", stock_articles_path, class: 'btn' - = link_to "Aufräumen", finished_stock_article_selections_path, :method => 'delete', - :confirm => 'Wirklich alle erledigten Löschvorschläge entfernen?', class: 'btn' - -.well - %h2 Ausstehende Löschvorschläge - - open_selections = @stock_article_selections.select { |sel| sel.deletable_count + sel.nondeletable_count > 0 } - - if open_selections.length == 0 - %p Es gibt keine ausstehenden Löschvorschläge. - %ul - %li= link_to "Löschvorschlag erstellen", stock_articles_path - - else - = render :partial => 'overview', :locals => {:stock_article_selections => open_selections} - -%h2 Erledigte Löschvorschläge -- finished_selections = @stock_article_selections.select { |sel| sel.deletable_count + sel.nondeletable_count <= 0 } -- if finished_selections.length == 0 - %p Es gibt keine erledigten Löschvorschläge. -- else - = render :partial => 'overview', :locals => {:stock_article_selections => finished_selections} diff --git a/app/views/stockit_selections/show.html.haml b/app/views/stockit_selections/show.html.haml deleted file mode 100644 index 9434421b..00000000 --- a/app/views/stockit_selections/show.html.haml +++ /dev/null @@ -1,25 +0,0 @@ -- title "Löschvorschlag für #{@stock_article_selection.stock_articles.count} Lagerartikel" - -.well.well-small - .btn-toolbar - .btn-group - = link_to "Lager anzeigen", stock_articles_path, class: 'btn' - = link_to 'Alle Löschvorschläge anzeigen', stock_article_selections_path, class: 'btn' - -%dl - %dt Löschvorschlag vom: - %dd= format_time(@stock_article_selection.created_at) - %dt Erstellt durch: - %dd= link_to_user_message_if_valid(@stock_article_selection.created_by) - %dt Zu löschende Artikel - - for article in @stock_article_selection.stock_articles.with_deleted - %dd - %span{:class => article_deletion_classes(article), :title => article_deletion_title(article)}= article.name - - -%p - = link_to 'Artikel löschen', articles_stock_article_selection_path(@stock_article_selection), :method => :delete, - :confirm => 'Diesen Löschvorschlag wirklich ausführen und markierte Artikel löschen?', class: 'btn btn-danger' - = link_to 'Verwerfen', @stock_article_selection, :method => :delete, - :confirm => 'Diesen Löschvorschlag wirklich verwerfen?', class: 'btn' - = link_to 'Alle Löschvorschläge anzeigen', stock_article_selections_path, class: 'btn' diff --git a/config/locales/de.yml b/config/locales/de.yml index 213c3c97..6f6d108a 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -143,6 +143,7 @@ de: odd: muss ungerade sein record_invalid: ! 'Gültigkeitsprüfung ist fehlgeschlagen: %{errors}' taken: ist bereits vergeben + taken_with_deleted: ist bereits vergeben (eine gelöschte Gruppe) too_long: ist zu lang (nicht mehr als %{count} Zeichen) too_short: ist zu kurz (nicht weniger als %{count} Zeichen) wrong_length: hat die falsche Länge (muss genau %{count} Zeichen haben) diff --git a/config/routes.rb b/config/routes.rb index 6e108cce..aa8e0e29 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -89,18 +89,6 @@ Foodsoft::Application.routes.draw do post :add_stock_article end end - - resources :stock_article_selections, :controller => 'stockit_selections', - :only => [ :create, :show, :index, :destroy ], :path => "/stock_articles/selections" do - member do - delete 'articles' - end - - collection do - delete 'finished' - end - end - resources :stock_articles, :to => 'stockit' do collection do diff --git a/db/migrate/20130112121840_create_stock_article_selections.rb b/db/migrate/20130112121840_create_stock_article_selections.rb deleted file mode 100644 index 2ead9008..00000000 --- a/db/migrate/20130112121840_create_stock_article_selections.rb +++ /dev/null @@ -1,18 +0,0 @@ -class CreateStockArticleSelections < ActiveRecord::Migration - def up - create_table :stock_article_selections do |t| - t.integer :created_by_user_id - t.timestamps - end - - create_table :stock_article_selections_stock_articles, :id => false do |t| - t.integer :stock_article_id - t.integer :stock_article_selection_id - end - end - - def down - drop_table :stock_article_selections - drop_table :stock_article_selections_stock_articles - end -end diff --git a/db/schema.rb b/db/schema.rb index bec2b950..188ea83b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130112121840) do +ActiveRecord::Schema.define(:version => 20121230142516) do create_table "article_categories", :force => true do |t| t.string "name", :default => "", :null => false @@ -268,17 +268,6 @@ ActiveRecord::Schema.define(:version => 20130112121840) do add_index "pages", ["permalink"], :name => "index_pages_on_permalink" add_index "pages", ["title"], :name => "index_pages_on_title" - create_table "stock_article_selections", :force => true do |t| - t.integer "created_by_user_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "stock_article_selections_stock_articles", :id => false, :force => true do |t| - t.integer "stock_article_id" - t.integer "stock_article_selection_id" - end - create_table "stock_changes", :force => true do |t| t.integer "delivery_id" t.integer "order_id"