igmarin
10/17/2014 - 11:16 PM

fac

fac

# == Schema Information
#
# Table name: facturas
#
#  id                   :integer          not null, primary key
#  account_statement_id :integer
#  diverza_client_id    :integer
#  created_at           :datetime(23)
#  updated_at           :datetime(23)
#  file_file_name       :string(255)
#  file_content_type    :string(255)
#  file_file_size       :integer
#  file_updated_at      :datetime(23)
#

class Factura < ActiveRecord::Base
  include ActionView::Helpers::NumberHelper
  belongs_to :account_statement
  belongs_to :diverza_client
  validates :file, presence: true

  default_scope ->{order(created_at: :desc)}

  validates :account_statement_id, :diverza_client_id, presence: true
  validate :validate_emisor, :validate_receptor, :validate_sub_total, :validate_total, :validate_cfdi_client_with_sat_service

  has_attached_file :file,
    path: "#{Rails.root}/public/facturas/:id/:basename.:extension",
    url: "/facturas/:id/:basename.:extension"
  validates_attachment_content_type :file, content_type: %w(text/xml)

  before_validation :parse_file

  private
  def parse_file
    tempfile  = file.queued_for_write[:original]
    doc       = Nokogiri::XML(tempfile)
    parse_xml(doc)
  end

  def parse_xml(doc)
    @emisor         = doc.xpath("//cfdi:Emisor/@rfc").first.text.to_s
    @receptor       = doc.xpath("//cfdi:Receptor/@rfc").first.text.to_s
    @imp_retenidos  = doc.xpath("cfdi:Impuestos/@totalImpuestosRetenidos").first
    @sub_total      = doc.xpath("//cfdi:Comprobante/@subTotal").first.text.to_f
    @total          = doc.xpath("//cfdi:Comprobante/@total").first.text.to_f
    @uuid           = doc.xpath("//cfdi:Complemento/@UUID").first.text.to_s
  end

  def validate_receptor
    errors.add(:validate_receiver, "Diferente Receptor") if @receptor != self.account_statement.issuer
  end

  def validate_emisor
    errors.add(:validate_emisor, "Diferente Emissor") if @emisor != self.account_statement.receiver
  end

  def validate_total
    errors.add(:validate_total, "Diferente Total, factura: #{number_to_currency(@total)}, en estado de cuenta: #{number_to_currency(self.account_statement.net_amount)}") if @total != self.account_statement.net_amount
  end

  def validate_sub_total
    errors.add(:validate_sub_total, "Diferente Sub Total, factura: #{number_to_currency(@sub_total)}, en estado de cuenta: #{number_to_currency(self.account_statement.gross_amount)}") if @sub_total != self.account_statement.gross_amount
  end

  def validate_cfdi_client_with_sat_service
    validacion = CfdiClientSatService.new(@emisor, @receptor, @total.to_s, @uuid)
    errors.add(:validate_cfdi_client_with_sat_service, validacion.resultado_codigo_estatus) if !validacion.is_a_valid_factura?
  end
end