class Invoice < ApplicationRecord include CustomFields belongs_to :supplier belongs_to :created_by, :class_name => 'User', :foreign_key => 'created_by_user_id' belongs_to :financial_link, optional: true has_many :deliveries, dependent: :nullify has_many :orders, dependent: :nullify validates_presence_of :supplier_id validates_numericality_of :amount, :deposit, :deposit_credit validate :valid_attachment scope :unpaid, -> { where(paid_on: nil) } scope :without_financial_link, -> { where(financial_link: nil) } attr_accessor :delete_attachment # Replace numeric seperator with database format localize_input_of :amount, :deposit, :deposit_credit def attachment=(incoming_file) self.attachment_data = incoming_file.read # allow to soft-fail when FileMagic isn't present and removed from Gemfile (e.g. Heroku) self.attachment_mime = defined?(FileMagic) ? FileMagic.new(FileMagic::MAGIC_MIME).buffer(self.attachment_data) : 'application/octet-stream' end def delete_attachment=(value) if value == '1' self.attachment_data = nil self.attachment_mime = nil end end def user_can_edit?(user) user.role_finance? || (user.role_invoices? && !self.paid_on && self.created_by.try(:id) == user.id) end # Amount without deposit def net_amount amount - deposit + deposit_credit end def orders_sum orders .joins(order_articles: [:article_price]) .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)") end def orders_transport_sum orders.sum(:transport) end def expected_amount return net_amount unless orders.any? orders_sum + orders_transport_sum end protected def valid_attachment if attachment_data mime = MIME::Type.simplified(attachment_mime) unless ['application/pdf', 'image/jpeg'].include? mime errors.add :attachment, I18n.t('model.invoice.invalid_mime', :mime => mime) end end end end