2019-01-13 07:05:54 +01:00
|
|
|
class Invoice < ApplicationRecord
|
2017-10-12 20:50:40 +02:00
|
|
|
include CustomFields
|
2022-02-03 08:37:38 +01:00
|
|
|
include LocalizeInput
|
2009-01-08 16:33:27 +01:00
|
|
|
|
|
|
|
belongs_to :supplier
|
2023-05-12 13:01:12 +02:00
|
|
|
belongs_to :created_by, class_name: 'User', foreign_key: 'created_by_user_id'
|
2020-08-01 02:49:15 +02:00
|
|
|
belongs_to :financial_link, optional: true
|
2020-06-22 17:03:58 +02:00
|
|
|
has_many :deliveries, dependent: :nullify
|
|
|
|
has_many :orders, dependent: :nullify
|
2009-01-08 16:33:27 +01:00
|
|
|
|
2023-05-12 13:01:12 +02:00
|
|
|
validates :supplier_id, presence: true
|
|
|
|
validates :amount, :deposit, :deposit_credit, numericality: true
|
2016-05-06 15:04:58 +02:00
|
|
|
validate :valid_attachment
|
2009-01-08 16:33:27 +01:00
|
|
|
|
2014-02-20 15:04:53 +01:00
|
|
|
scope :unpaid, -> { where(paid_on: nil) }
|
2018-10-11 22:16:50 +02:00
|
|
|
scope :without_financial_link, -> { where(financial_link: nil) }
|
2009-01-10 19:36:58 +01:00
|
|
|
|
2016-05-06 15:04:58 +02:00
|
|
|
attr_accessor :delete_attachment
|
|
|
|
|
2012-04-20 18:33:47 +02:00
|
|
|
# Replace numeric seperator with database format
|
|
|
|
localize_input_of :amount, :deposit, :deposit_credit
|
2009-01-29 21:28:22 +01:00
|
|
|
|
2016-05-06 15:04:58 +02:00
|
|
|
def attachment=(incoming_file)
|
|
|
|
self.attachment_data = incoming_file.read
|
2016-05-25 02:05:55 +02:00
|
|
|
# allow to soft-fail when FileMagic isn't present and removed from Gemfile (e.g. Heroku)
|
2023-05-12 13:01:12 +02:00
|
|
|
self.attachment_mime = defined?(FileMagic) ? FileMagic.new(FileMagic::MAGIC_MIME).buffer(attachment_data) : 'application/octet-stream'
|
2016-05-06 15:04:58 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
def delete_attachment=(value)
|
2023-05-12 13:01:12 +02:00
|
|
|
return unless value == '1'
|
|
|
|
|
|
|
|
self.attachment_data = nil
|
|
|
|
self.attachment_mime = nil
|
2016-05-06 15:04:58 +02:00
|
|
|
end
|
|
|
|
|
2016-02-17 21:07:35 +01:00
|
|
|
def user_can_edit?(user)
|
2023-05-12 13:01:12 +02:00
|
|
|
user.role_finance? || (user.role_invoices? && !paid_on && created_by.try(:id) == user.id)
|
2016-02-17 21:07:35 +01:00
|
|
|
end
|
|
|
|
|
2009-01-29 21:28:22 +01:00
|
|
|
# Amount without deposit
|
|
|
|
def net_amount
|
|
|
|
amount - deposit + deposit_credit
|
|
|
|
end
|
2016-05-06 15:04:58 +02:00
|
|
|
|
2022-02-18 13:03:34 +01:00
|
|
|
def orders_sum
|
|
|
|
orders
|
|
|
|
.joins(order_articles: [:article_price])
|
2023-05-12 13:01:12 +02:00
|
|
|
.sum('COALESCE(order_articles.units_received, order_articles.units_billed, order_articles.units_to_order)' \
|
|
|
|
+ '* article_prices.unit_quantity' \
|
|
|
|
+ '* ROUND((article_prices.price + article_prices.deposit) * (100 + article_prices.tax) / 100, 2)')
|
2022-02-18 13:03:34 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
def orders_transport_sum
|
|
|
|
orders.sum(:transport)
|
|
|
|
end
|
|
|
|
|
|
|
|
def expected_amount
|
|
|
|
return net_amount unless orders.any?
|
|
|
|
|
|
|
|
orders_sum + orders_transport_sum
|
|
|
|
end
|
|
|
|
|
2016-05-06 15:04:58 +02:00
|
|
|
protected
|
|
|
|
|
|
|
|
def valid_attachment
|
2023-05-12 13:01:12 +02:00
|
|
|
return unless attachment_data
|
|
|
|
|
|
|
|
mime = MIME::Type.simplified(attachment_mime)
|
|
|
|
return if ['application/pdf', 'image/jpeg'].include? mime
|
|
|
|
|
|
|
|
errors.add :attachment, I18n.t('model.invoice.invalid_mime', mime: mime)
|
2016-05-06 15:04:58 +02:00
|
|
|
end
|
2009-01-08 16:33:27 +01:00
|
|
|
end
|