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
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue