snappler_contable_multicurrency 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/MIT-LICENSE +20 -0
 - data/README.md +398 -0
 - data/Rakefile +39 -0
 - data/app/helpers/snappler_contable_helper.rb +42 -0
 - data/app/models/ledger_account.rb +217 -0
 - data/app/models/ledger_account_activo.rb +8 -0
 - data/app/models/ledger_account_pasivo.rb +6 -0
 - data/app/models/ledger_account_patrimonio_neto.rb +6 -0
 - data/app/models/ledger_account_relation.rb +8 -0
 - data/app/models/ledger_account_resultado_negativo.rb +6 -0
 - data/app/models/ledger_account_resultado_positivo.rb +6 -0
 - data/app/models/ledger_currency.rb +5 -0
 - data/app/models/ledger_entry.rb +7 -0
 - data/app/models/ledger_move.rb +76 -0
 - data/lib/generators/snappler_contable/initializer_generator.rb +11 -0
 - data/lib/generators/snappler_contable/migrate_generator.rb +25 -0
 - data/lib/generators/snappler_contable/new_currency_generator.rb +23 -0
 - data/lib/generators/snappler_contable/templates/snappler_contable_add_currencies.rb +20 -0
 - data/lib/generators/snappler_contable/templates/snappler_contable_app_ledger_accounts.rb +48 -0
 - data/lib/generators/snappler_contable/templates/snappler_contable_migrate.rb +68 -0
 - data/lib/generators/snappler_contable/templates/snappler_contable_new_currency.rb +14 -0
 - data/lib/snappler_contable/ext/string.rb +5 -0
 - data/lib/snappler_contable/railtie.rb +4 -0
 - data/lib/snappler_contable/snappler_contable.rb +154 -0
 - data/lib/snappler_contable/version.rb +3 -0
 - data/lib/snappler_contable_multicurrency.rb +14 -0
 - data/lib/tasks/snappler_contable_tasks.rake +4 -0
 - data/spec/internal/config/database_example.yml +8 -0
 - data/spec/internal/config/initializers/snappler_contable.rb +8 -0
 - data/spec/internal/config/routes.rb +3 -0
 - data/spec/internal/db/schema.rb +64 -0
 - data/spec/internal/public/favicon.ico +0 -0
 - data/spec/models/ledger_account_spec.rb +308 -0
 - data/spec/spec_helper.rb +75 -0
 - metadata +84 -0
 
| 
         @@ -0,0 +1,42 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module SnapplerContableHelper
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              #---------------------------------------------------------------
         
     | 
| 
      
 4 
     | 
    
         
            +
              def print_accounts_tree
         
     | 
| 
      
 5 
     | 
    
         
            +
                accounts = SnapplerContable.root_accounts
         
     | 
| 
      
 6 
     | 
    
         
            +
                html_return = '<style>#account_list b{float: right;}#account_list li{border-bottom: 1px dashed;}#account_list ul{padding-left: 15px;}#account_list b .column{display: inline-block;text-align: center;width: 150px;}</style>'
         
     | 
| 
      
 7 
     | 
    
         
            +
                html_return += '<div id="account_list">'
         
     | 
| 
      
 8 
     | 
    
         
            +
                html_return += print_accounts(accounts)
         
     | 
| 
      
 9 
     | 
    
         
            +
                html_return += '</div>'
         
     | 
| 
      
 10 
     | 
    
         
            +
                html_return.html_safe
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              def print_accounts(accounts)
         
     | 
| 
      
 14 
     | 
    
         
            +
                html_return = "<ul>"
         
     | 
| 
      
 15 
     | 
    
         
            +
                accounts.each do |account|
         
     | 
| 
      
 16 
     | 
    
         
            +
                  html_return += print_account(account)
         
     | 
| 
      
 17 
     | 
    
         
            +
                end 
         
     | 
| 
      
 18 
     | 
    
         
            +
                html_return += "</ul>"
         
     | 
| 
      
 19 
     | 
    
         
            +
                return html_return
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              def print_account(account)
         
     | 
| 
      
 23 
     | 
    
         
            +
                if(account.child_ledger_accounts.empty?)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  return "<li>#{account.name} <b>#{number_to_all_currency account.balance}</b></li>"
         
     | 
| 
      
 25 
     | 
    
         
            +
                else
         
     | 
| 
      
 26 
     | 
    
         
            +
                  return %{<li>#{account.name} <b>#{number_to_all_currency account.balance}</b></li>
         
     | 
| 
      
 27 
     | 
    
         
            +
                  <ul>
         
     | 
| 
      
 28 
     | 
    
         
            +
                  #{print_accounts(account.child_ledger_accounts)}
         
     | 
| 
      
 29 
     | 
    
         
            +
                  </ul>
         
     | 
| 
      
 30 
     | 
    
         
            +
                }
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
              def number_to_all_currency(hash, reject_zero=false)
         
     | 
| 
      
 35 
     | 
    
         
            +
                hash.reject!{|x,y| y.zero?} if reject_zero
         
     | 
| 
      
 36 
     | 
    
         
            +
                hash.empty? ? '-' : hash.map{|key,val| number_to_currency(val, unit: t(key, scope: 'ledger_currency'), format: "%u %n") }.collect{|x| "<span class='column'>#{x}</span>" }.join()
         
     | 
| 
      
 37 
     | 
    
         
            +
              end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,217 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class LedgerAccount < ActiveRecord::Base
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                #--------------------------------------------- RELATIONS
         
     | 
| 
      
 6 
     | 
    
         
            +
                belongs_to :owner, polymorphic: true, optional: true
         
     | 
| 
      
 7 
     | 
    
         
            +
                belongs_to :master_ledger_account, class_name: "LedgerAccount", optional: true
         
     | 
| 
      
 8 
     | 
    
         
            +
                has_many :child_ledger_accounts, class_name: "LedgerAccount", foreign_key: "master_ledger_account_id"
         
     | 
| 
      
 9 
     | 
    
         
            +
                has_many :ledger_moves, dependent: :destroy
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                has_many :father_relations, class_name: "LedgerAccountRelation", foreign_key: :ledger_account_child_id, dependent: :destroy
         
     | 
| 
      
 12 
     | 
    
         
            +
                has_many :fathers, through: :father_relations, source: :ledger_account_father
         
     | 
| 
      
 13 
     | 
    
         
            +
                has_many :child_relations, class_name: "LedgerAccountRelation", foreign_key: :ledger_account_father_id
         
     | 
| 
      
 14 
     | 
    
         
            +
                has_many :childs, through: :child_relations, source: :ledger_account_child
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                #--------------------------------------------- VALIDATIONS
         
     | 
| 
      
 17 
     | 
    
         
            +
                validates :name, presence: true
         
     | 
| 
      
 18 
     | 
    
         
            +
                validates :code_name, uniqueness: true
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                #--------------------------------------------- CALLBACKS
         
     | 
| 
      
 21 
     | 
    
         
            +
                after_create :set_ledger_account_relations
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                #--------------------------------------------- SCOPES
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                #--------------------------------------------- METHODS
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                #devuelve la cuenta (de clase)
         
     | 
| 
      
 29 
     | 
    
         
            +
                def self.get(value)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  find_by(code_name: value.to_s.snp_underscore)
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                #--------------------
         
     | 
| 
      
 34 
     | 
    
         
            +
                #Crea las relaciones de la cuenta con sus padres, todos los niveles
         
     | 
| 
      
 35 
     | 
    
         
            +
                #se va mandando recursivamente la cuenta creada a sus padres
         
     | 
| 
      
 36 
     | 
    
         
            +
                def set_ledger_account_relations
         
     | 
| 
      
 37 
     | 
    
         
            +
                  if master_ledger_account.present?
         
     | 
| 
      
 38 
     | 
    
         
            +
                    master_ledger_account.add_relation_child(self)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                def add_relation_child(account)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  self.childs << account
         
     | 
| 
      
 44 
     | 
    
         
            +
                  if master_ledger_account.present?
         
     | 
| 
      
 45 
     | 
    
         
            +
                    master_ledger_account.add_relation_child(account)
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
                #-----------------------------------
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                #-----------------------------------
         
     | 
| 
      
 51 
     | 
    
         
            +
                #Agrega una cuenta hija, con o sin relacion con un objeto
         
     | 
| 
      
 52 
     | 
    
         
            +
                def add_child(name, code_name, owner=nil)
         
     | 
| 
      
 53 
     | 
    
         
            +
                  if persisted?
         
     | 
| 
      
 54 
     | 
    
         
            +
                    if owner.nil?
         
     | 
| 
      
 55 
     | 
    
         
            +
                      self.class.create(name: name, code_name: code_name, master_ledger_account: self)    
         
     | 
| 
      
 56 
     | 
    
         
            +
                    else
         
     | 
| 
      
 57 
     | 
    
         
            +
                      self.class.create(name: name, master_ledger_account: self, owner: owner, code_name: "#{code_name}_#{owner.class.name.underscore}_#{owner.id}")
         
     | 
| 
      
 58 
     | 
    
         
            +
                    end
         
     | 
| 
      
 59 
     | 
    
         
            +
                  else
         
     | 
| 
      
 60 
     | 
    
         
            +
                    errores = ["La instancia debe estar persistida para poder agregar una cuenta hija."]
         
     | 
| 
      
 61 
     | 
    
         
            +
                    errores << "La cuenta '#{name}' no se pudo persistir porque sus campos no cumplen la validacion de LedgerAccount." if errors.any?
         
     | 
| 
      
 62 
     | 
    
         
            +
                    raise errores.join(' ')
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
                end
         
     | 
| 
      
 65 
     | 
    
         
            +
                #-----------------------------------
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                def to_s
         
     | 
| 
      
 68 
     | 
    
         
            +
                  name
         
     | 
| 
      
 69 
     | 
    
         
            +
                end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                def name
         
     | 
| 
      
 72 
     | 
    
         
            +
                  internal_name
         
     | 
| 
      
 73 
     | 
    
         
            +
                end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                def name=(value)
         
     | 
| 
      
 76 
     | 
    
         
            +
                  self.internal_name = value
         
     | 
| 
      
 77 
     | 
    
         
            +
                  self.code_name = value.snp_underscore if code_name.blank?
         
     | 
| 
      
 78 
     | 
    
         
            +
                end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                def root?
         
     | 
| 
      
 81 
     | 
    
         
            +
                  master_ledger_account.nil?
         
     | 
| 
      
 82 
     | 
    
         
            +
                end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                def has_ledger_moves?
         
     | 
| 
      
 85 
     | 
    
         
            +
                  ledger_moves.any?
         
     | 
| 
      
 86 
     | 
    
         
            +
                end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                def balance(params={}, format_value=true)
         
     | 
| 
      
 90 
     | 
    
         
            +
                  from_date    = params[:from]
         
     | 
| 
      
 91 
     | 
    
         
            +
                  to_date      = params[:to]
         
     | 
| 
      
 92 
     | 
    
         
            +
                  balance_hash = {}
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                  if from_date.nil? && to_date.nil?
         
     | 
| 
      
 95 
     | 
    
         
            +
                    SnapplerContable.used_currencies.each do |c|
         
     | 
| 
      
 96 
     | 
    
         
            +
                      balance_hash[c.to_sym] = self.send("normal_balance_#{c.downcase}", format_value)
         
     | 
| 
      
 97 
     | 
    
         
            +
                    end
         
     | 
| 
      
 98 
     | 
    
         
            +
                  elsif from_date.present? && to_date.present?
         
     | 
| 
      
 99 
     | 
    
         
            +
                    SnapplerContable.used_currencies.each do |c|
         
     | 
| 
      
 100 
     | 
    
         
            +
                      balance_hash[c.to_sym] = self.send("balance_from_to_#{c.downcase}", format_value, from_date, to_date)
         
     | 
| 
      
 101 
     | 
    
         
            +
                    end
         
     | 
| 
      
 102 
     | 
    
         
            +
                  elsif from_date.present?
         
     | 
| 
      
 103 
     | 
    
         
            +
                    SnapplerContable.used_currencies.each do |c|
         
     | 
| 
      
 104 
     | 
    
         
            +
                      balance_hash[c.to_sym] = self.send("balance_from_#{c.downcase}", format_value, from_date)
         
     | 
| 
      
 105 
     | 
    
         
            +
                    end
         
     | 
| 
      
 106 
     | 
    
         
            +
                  else
         
     | 
| 
      
 107 
     | 
    
         
            +
                    SnapplerContable.used_currencies.each do |c|
         
     | 
| 
      
 108 
     | 
    
         
            +
                      balance_hash[c.to_sym] = self.send("balance_to_#{c.downcase}", format_value, to_date)
         
     | 
| 
      
 109 
     | 
    
         
            +
                    end
         
     | 
| 
      
 110 
     | 
    
         
            +
                  end
         
     | 
| 
      
 111 
     | 
    
         
            +
                  return balance_hash
         
     | 
| 
      
 112 
     | 
    
         
            +
                end
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
                SnapplerContable.used_currencies.each do |c|
         
     | 
| 
      
 116 
     | 
    
         
            +
                  c = c.downcase # ARS => ars
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                  #Metodo que en base a los parametros, busca saldo en cache o por rango de fecha
         
     | 
| 
      
 119 
     | 
    
         
            +
                  define_method "balance_#{c}" do |params={}, format_value=true|
         
     | 
| 
      
 120 
     | 
    
         
            +
                    from_date    = params[:from]
         
     | 
| 
      
 121 
     | 
    
         
            +
                    to_date      = params[:to]
         
     | 
| 
      
 122 
     | 
    
         
            +
                    if from_date.nil? && to_date.nil?
         
     | 
| 
      
 123 
     | 
    
         
            +
                      self.send("normal_balance_#{c}", format_value)
         
     | 
| 
      
 124 
     | 
    
         
            +
                    elsif from_date.present? && to_date.present?
         
     | 
| 
      
 125 
     | 
    
         
            +
                      self.send("balance_from_to_#{c}", format_value, from_date, to_date)
         
     | 
| 
      
 126 
     | 
    
         
            +
                    elsif from_date.present?
         
     | 
| 
      
 127 
     | 
    
         
            +
                      self.send("balance_from_#{c}", format_value, from_date)
         
     | 
| 
      
 128 
     | 
    
         
            +
                    else
         
     | 
| 
      
 129 
     | 
    
         
            +
                      self.send("balance_to#{c}", format_value, to_date)
         
     | 
| 
      
 130 
     | 
    
         
            +
                    end
         
     | 
| 
      
 131 
     | 
    
         
            +
                  end
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
                  #Saldo en cache
         
     | 
| 
      
 134 
     | 
    
         
            +
                  define_method "normal_balance_#{c}" do |format_value|
         
     | 
| 
      
 135 
     | 
    
         
            +
                    balance_sum_currency = "balance_sum_#{c}".to_sym
         
     | 
| 
      
 136 
     | 
    
         
            +
                    val = LedgerAccount.where(id: child_ids+[self.id]).sum(balance_sum_currency)
         
     | 
| 
      
 137 
     | 
    
         
            +
                    (format_value)? LedgerMove.format_value(val) : val
         
     | 
| 
      
 138 
     | 
    
         
            +
                  end
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
                  #Saldo hasta
         
     | 
| 
      
 141 
     | 
    
         
            +
                  define_method "balance_to_#{c}" do |format_value, to_date|
         
     | 
| 
      
 142 
     | 
    
         
            +
                    ledger_currency = get_currency(c.upcase)
         
     | 
| 
      
 143 
     | 
    
         
            +
                    #process(children_moves.where('date <= ? AND represent_ledger_currency_id = ?', to_date, ledger_currency.id).group(:dh).sum(:represent_value), format_value)
         
     | 
| 
      
 144 
     | 
    
         
            +
                    process(children_moves.filter_date_end(to_date).where('represent_ledger_currency_id = ?', ledger_currency.id).group(:dh).sum(:represent_value), format_value)
         
     | 
| 
      
 145 
     | 
    
         
            +
                  end
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
                  #Saldo desde
         
     | 
| 
      
 148 
     | 
    
         
            +
                  define_method "balance_from_#{c}" do |format_value, from_date|
         
     | 
| 
      
 149 
     | 
    
         
            +
                    ledger_currency = get_currency(c.upcase)
         
     | 
| 
      
 150 
     | 
    
         
            +
                    #process(children_moves.where('date >= ? AND represent_ledger_currency_id = ?', from_date, ledger_currency.id).group(:dh).sum(:represent_value), format_value)
         
     | 
| 
      
 151 
     | 
    
         
            +
                    process(children_moves.filter_date_start(from_date).where('represent_ledger_currency_id = ?', ledger_currency.id).group(:dh).sum(:represent_value), format_value)
         
     | 
| 
      
 152 
     | 
    
         
            +
                  end
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                  #Saldo desde - hasta
         
     | 
| 
      
 155 
     | 
    
         
            +
                  define_method "balance_from_to_#{c}" do |format_value, from_date, to_date|
         
     | 
| 
      
 156 
     | 
    
         
            +
                    ledger_currency = get_currency(c.upcase)
         
     | 
| 
      
 157 
     | 
    
         
            +
                    process(children_moves.filter_date_start(from_date).filter_date_end(to_date).where('represent_ledger_currency_id = ?', ledger_currency.id).group(:dh).sum(:represent_value), format_value)
         
     | 
| 
      
 158 
     | 
    
         
            +
                  end
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
                end
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
      
 165 
     | 
    
         
            +
                def process(dh_hash, format_value)
         
     | 
| 
      
 166 
     | 
    
         
            +
                  debe  = dh_hash["D"].to_i
         
     | 
| 
      
 167 
     | 
    
         
            +
                  haber = dh_hash["H"].to_i   
         
     | 
| 
      
 168 
     | 
    
         
            +
                  format_value ? LedgerMove.format_value(process_balance(debe, haber)) : process_balance(debe, haber)
         
     | 
| 
      
 169 
     | 
    
         
            +
                end
         
     | 
| 
      
 170 
     | 
    
         
            +
             
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
                def get_currency(c)
         
     | 
| 
      
 173 
     | 
    
         
            +
                  if c.nil?
         
     | 
| 
      
 174 
     | 
    
         
            +
                    c = SnapplerContable.default_currency
         
     | 
| 
      
 175 
     | 
    
         
            +
                  else
         
     | 
| 
      
 176 
     | 
    
         
            +
                    if c.is_a? Numeric
         
     | 
| 
      
 177 
     | 
    
         
            +
                      c = LedgerCurrency.find(c)
         
     | 
| 
      
 178 
     | 
    
         
            +
                    elsif c.is_a? String
         
     | 
| 
      
 179 
     | 
    
         
            +
                      c = LedgerCurrency.find_by_code(c)
         
     | 
| 
      
 180 
     | 
    
         
            +
                    end
         
     | 
| 
      
 181 
     | 
    
         
            +
                  end
         
     | 
| 
      
 182 
     | 
    
         
            +
                  return c
         
     | 
| 
      
 183 
     | 
    
         
            +
                end
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
                def children_moves
         
     | 
| 
      
 187 
     | 
    
         
            +
                  LedgerMove.where(ledger_account_id: child_ids+[self.id])
         
     | 
| 
      
 188 
     | 
    
         
            +
                end
         
     | 
| 
      
 189 
     | 
    
         
            +
             
     | 
| 
      
 190 
     | 
    
         
            +
                def process_balance
         
     | 
| 
      
 191 
     | 
    
         
            +
                  raise "Este metodo solo se tiene que implementar en las subclases"
         
     | 
| 
      
 192 
     | 
    
         
            +
                end
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
             
     | 
| 
      
 195 
     | 
    
         
            +
                def update_balance(value, dh, ledger_currency_id)
         
     | 
| 
      
 196 
     | 
    
         
            +
                  balance_update = case dh.upcase
         
     | 
| 
      
 197 
     | 
    
         
            +
                  when 'D' then process_balance(value, 0)  
         
     | 
| 
      
 198 
     | 
    
         
            +
                  when 'H' then process_balance(0, value)  
         
     | 
| 
      
 199 
     | 
    
         
            +
                  end
         
     | 
| 
      
 200 
     | 
    
         
            +
             
     | 
| 
      
 201 
     | 
    
         
            +
                  lc = LedgerCurrency.find(ledger_currency_id)
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
      
 204 
     | 
    
         
            +
                  
         
     | 
| 
      
 205 
     | 
    
         
            +
                  currency = lc.code.downcase
         
     | 
| 
      
 206 
     | 
    
         
            +
                  self.send("balance_sum_#{currency}=", (self.send("balance_sum_#{currency}") + balance_update))
         
     | 
| 
      
 207 
     | 
    
         
            +
                  save
         
     | 
| 
      
 208 
     | 
    
         
            +
                end
         
     | 
| 
      
 209 
     | 
    
         
            +
             
     | 
| 
      
 210 
     | 
    
         
            +
              def update_balance_destroy(value, dh, ledger_currency_id)
         
     | 
| 
      
 211 
     | 
    
         
            +
                #inverse operation
         
     | 
| 
      
 212 
     | 
    
         
            +
                ops = {'D' => 'H', 'H' => 'D'}
         
     | 
| 
      
 213 
     | 
    
         
            +
                update_balance(value, ops[dh], ledger_currency_id)
         
     | 
| 
      
 214 
     | 
    
         
            +
              end
         
     | 
| 
      
 215 
     | 
    
         
            +
                             
         
     | 
| 
      
 216 
     | 
    
         
            +
             
     | 
| 
      
 217 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,76 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class LedgerMove < ActiveRecord::Base
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              #--------------------------------------------- RELATIONS
         
     | 
| 
      
 4 
     | 
    
         
            +
              belongs_to :ledger_entry
         
     | 
| 
      
 5 
     | 
    
         
            +
              belongs_to :ledger_account
         
     | 
| 
      
 6 
     | 
    
         
            +
              belongs_to :real_ledger_currency, class_name: 'LedgerCurrency'
         
     | 
| 
      
 7 
     | 
    
         
            +
              belongs_to :represent_ledger_currency, class_name: 'LedgerCurrency'
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              #--------------------------------------------- CALLBACKS
         
     | 
| 
      
 10 
     | 
    
         
            +
              after_create :update_balance_create
         
     | 
| 
      
 11 
     | 
    
         
            +
              after_destroy :update_balance_destroy
         
     | 
| 
      
 12 
     | 
    
         
            +
              after_update :update_balance_update
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              #--------------------------------------------- SCOPES
         
     | 
| 
      
 15 
     | 
    
         
            +
              scope :filter_date_start, ->(date) { where('ledger_moves.datetime >= :datetime', datetime: Date.parse(date).beginning_of_day.to_datetime) if date.present? }
         
     | 
| 
      
 16 
     | 
    
         
            +
              scope :filter_date_end, ->(date) { where('ledger_moves.datetime <= :datetime', datetime: Date.parse(date).end_of_day.to_datetime) if date.present? }
         
     | 
| 
      
 17 
     | 
    
         
            +
              scope :order_date_asc, -> { order('ledger_moves.datetime ASC, ledger_moves.id ASC')}
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
              #--------------------------------------------- METHODS
         
     | 
| 
      
 22 
     | 
    
         
            +
              def update_balance_create
         
     | 
| 
      
 23 
     | 
    
         
            +
                self.ledger_account.update_balance(raw_represent_value, dh, represent_ledger_currency_id)
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              def update_balance_destroy
         
     | 
| 
      
 27 
     | 
    
         
            +
                self.ledger_account.update_balance_destroy(raw_represent_value, dh, represent_ledger_currency_id)
         
     | 
| 
      
 28 
     | 
    
         
            +
              end  
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              def update_balance_update    
         
     | 
| 
      
 31 
     | 
    
         
            +
                self.ledger_account.update_balance_destroy(represent_value_was, dh, represent_ledger_currency_id_was)
         
     | 
| 
      
 32 
     | 
    
         
            +
                self.ledger_account.update_balance(raw_represent_value, dh, represent_ledger_currency_id)
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              def self.format_value(value)
         
     | 
| 
      
 37 
     | 
    
         
            +
                value / SnapplerContable.default_divisor
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              def self.unformat_value(value)    
         
     | 
| 
      
 41 
     | 
    
         
            +
                (value * SnapplerContable.default_divisor).round.to_i
         
     | 
| 
      
 42 
     | 
    
         
            +
              end  
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
              #Defino metodos para los 2 valores ("real_value", "represent_value")
         
     | 
| 
      
 47 
     | 
    
         
            +
              ['real_value', 'represent_value'].each do |the_method|
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                #Getter
         
     | 
| 
      
 50 
     | 
    
         
            +
                define_method "#{the_method}" do
         
     | 
| 
      
 51 
     | 
    
         
            +
                  value_formated = read_attribute the_method.to_sym
         
     | 
| 
      
 52 
     | 
    
         
            +
                  self.class.format_value(value_formated)
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                #Setter
         
     | 
| 
      
 56 
     | 
    
         
            +
                define_method "#{the_method}=" do |val|
         
     | 
| 
      
 57 
     | 
    
         
            +
                  if val.is_a? Numeric
         
     | 
| 
      
 58 
     | 
    
         
            +
                    write_attribute the_method.to_sym, self.class.unformat_value(val)
         
     | 
| 
      
 59 
     | 
    
         
            +
                  else
         
     | 
| 
      
 60 
     | 
    
         
            +
                    raise "El valor debe ser un numero"
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                #Crudo Getter
         
     | 
| 
      
 65 
     | 
    
         
            +
                define_method "raw_#{the_method}" do
         
     | 
| 
      
 66 
     | 
    
         
            +
                  return read_attribute the_method.to_sym
         
     | 
| 
      
 67 
     | 
    
         
            +
                end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
              end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
            end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,11 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rails/generators'  
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module SnapplerContable
         
     | 
| 
      
 4 
     | 
    
         
            +
              class InitializerGenerator < ::Rails::Generators::Base
         
     | 
| 
      
 5 
     | 
    
         
            +
                def create_initializer_file
         
     | 
| 
      
 6 
     | 
    
         
            +
                  create_file "config/initializers/snappler_contable.rb", "# Monedas usadas\nSnapplerContable.used_currencies = ['ARS','USD','EUR','BRL'] \#'JPY'\n\n# Moneda por defecto\nSnapplerContable.default_currency = 'ARS'\n\n# Divisor por defecto (2 decimales)\nSnapplerContable.default_divisor = 100.0"
         
     | 
| 
      
 7 
     | 
    
         
            +
                end
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
            end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,25 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rails/generators'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'rails/generators/migration'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module SnapplerContable
         
     | 
| 
      
 5 
     | 
    
         
            +
              class MigrateGenerator < ::Rails::Generators::Base
         
     | 
| 
      
 6 
     | 
    
         
            +
                include Rails::Generators::Migration
         
     | 
| 
      
 7 
     | 
    
         
            +
                source_root File.expand_path('../templates', __FILE__)
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                desc "add snappler_contable migration"
         
     | 
| 
      
 10 
     | 
    
         
            +
                def self.next_migration_number(path)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  unless @prev_migration_nr
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
         
     | 
| 
      
 13 
     | 
    
         
            +
                  else
         
     | 
| 
      
 14 
     | 
    
         
            +
                    @prev_migration_nr += 1
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
                 @prev_migration_nr.to_s
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                def copy_migrations
         
     | 
| 
      
 20 
     | 
    
         
            +
                 migration_template "snappler_contable_migrate.rb", "db/migrate/snappler_contable_migrate.rb"
         
     | 
| 
      
 21 
     | 
    
         
            +
                 migration_template "snappler_contable_add_currencies.rb", "db/migrate/snappler_contable_add_currencies.rb"
         
     | 
| 
      
 22 
     | 
    
         
            +
                 migration_template "snappler_contable_app_ledger_accounts.rb", "db/migrate/snappler_contable_app_ledger_accounts.rb"
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,23 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rails/generators'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'rails/generators/migration'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module SnapplerContable
         
     | 
| 
      
 5 
     | 
    
         
            +
              class NewCurrencyGenerator < ::Rails::Generators::Base
         
     | 
| 
      
 6 
     | 
    
         
            +
                include Rails::Generators::Migration
         
     | 
| 
      
 7 
     | 
    
         
            +
                source_root File.expand_path('../templates', __FILE__)
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                desc "add snappler_contable migration"
         
     | 
| 
      
 10 
     | 
    
         
            +
                def self.next_migration_number(path)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  unless @prev_migration_nr
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
         
     | 
| 
      
 13 
     | 
    
         
            +
                  else
         
     | 
| 
      
 14 
     | 
    
         
            +
                    @prev_migration_nr += 1
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
                 @prev_migration_nr.to_s
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                def copy_migrations
         
     | 
| 
      
 20 
     | 
    
         
            +
                 migration_template "snappler_contable_new_currency.rb", "db/migrate/snappler_contable_new_currency.rb"
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     |