class Movements

Attributes

check_progress[R]
check_state[R]

Public Class Methods

from_json(str) click to toggle source
# File lib/africompta/entities/movement.rb, line 25
def self.from_json(str)
  self.from_s(ActiveSupport::JSON.decode(str)['str'])
end
from_s(str) click to toggle source
# File lib/africompta/entities/movement.rb, line 37
def self.from_s(str)
  str.force_encoding(Encoding::UTF_8)
  dputs(3) { "Getting movement from #{str.inspect}" }
  desc, str = str.split("\r")
  global_id, value, date, src, dst = str.split("\t")
  #date = Time.parse(date).to_ss
  date = Date.strptime(date, '%Y-%m-%d')
  value = value.to_f
  a_src, a_dst = self.get_accounts(src, dst)
  if not a_src or not a_dst
    dputs(0) { "Couldn't parse #{str.inspect}: " +
        (a_src ? '' : "account #{src} not found. ") +
        (a_dst ? '' : "account #{dst} not found") }
    return nil
  end
  # Does the movement already exist?
  dputs(DEBUG_SLOW) { 'from_s 1'
  }
  our_m = nil
  if not (our_m = self.mbgi(global_id))
    dputs(3) { 'New movement' }
    our_m = self.create(desc, date, value,
                        a_src, a_dst)
    dputs(DEBUG_SLOW) { 'from_s 2' }
    our_m.global_id = global_id
  else
    dputs(1) { "Overwriting movement\n#{our_m.to_json.inspect} with" }
    # And update it
    our_m.set(desc, date, value, a_src.id, a_dst.id)
    dputs(1) { "#{our_m.to_json.inspect}" }
    dputs(2) { "Now we're #{our_m.rev_index}:#{our_m.id} -> #{global_id}" }
  end
  dputs(DEBUG_SLOW) { 'from_s 3' }
  return our_m
end
get_accounts(src, dst) click to toggle source
# File lib/africompta/entities/movement.rb, line 29
def self.get_accounts(src, dst)
  [Accounts.match_by_global_id(src), Accounts.match_by_global_id(dst)]
end
mbgi(global_id) click to toggle source
# File lib/africompta/entities/movement.rb, line 33
def self.mbgi(global_id)
  self.match_by_global_id(global_id)
end

Public Instance Methods

check_against_db(file) click to toggle source
# File lib/africompta/entities/movement.rb, line 102
def check_against_db(file)
  # First build
  # in_db - content of 'file' in .to_s format
  # in_local - content available locally in .to_s format
  in_db, diff, in_local = [], [], []

  dputs(3) { 'Searching all movements' }
  @check_state = 'Collect local'
  @check_progress = 0.0
  in_local = Movements.search_all_.reject { |m| m.value.to_f.round(3) == 0.0 }
  progress_step = 1.0 / (in_local.size + 1)
  dputs(3) { "Movements total: #{in_local.size}" }

  @check_state = 'Collect local'
  in_local = in_local.collect { |a|
    @check_progress += progress_step
    a.to_s
  }

  dputs(3) { 'Going to check all movements' }
  @check_state = 'Collect file-DB'
  @check_progress = 0.0
  SQLite3::Database.new(file) do |db|
    db.execute('select id, desc, global_id, value, date, account_src_id, account_dst_id '+
                   'from compta_movements').each do |row|
      @check_progress += progress_step
      #dputs(3) { "Looking at #{row}" }

      id_, desc_, gid_, value_, date_, src_, dst_ = row
      if value_.to_f.round(3) != 0.0
        in_db.push "#{desc_}\r#{gid_}\t" +
                       "#{sprintf('%.3f', value_.to_f.round(3))}\t#{date_.to_s}\t"+
                       "#{get_account(db, src_)}\t#{get_account(db, dst_)}"
      end
    end
  end

  # Now compare what is available only in db and what is available only locally
  dputs(3) { 'Verifying movements on one side only' }
  @check_state = 'On one side'
  @check_progress = 0.0
  in_db.delete_if { |a|
    @check_progress += progress_step
    in_local.delete(a)
  }

  # And search for accounts with same global-id but different content
  dputs(3) { 'Verifying mixed-up movements' }
  (in_db + in_local).sort_by { |a| a.match(/\r(.*?)\t/)[1] }
  @check_state = 'Mixed-up'
  @check_progress = 0.0
  progress_step = 1.0 / (in_db.size + 1)
  in_db.delete_if { |a|
    @check_progress += progress_step
    gid = a.match(/\r(.*?)\t/)[1]
    if c = in_local.find { |b| b =~ /\r#{gid}\t/ }
      diff.push [a, c]
      in_local.delete c
    end
  }

  @check_state = 'Done'
  [in_db, diff, in_local]
end
create(desc, date, value, source, dest) click to toggle source
Calls superclass method
# File lib/africompta/entities/movement.rb, line 73
def create(desc, date, value, source, dest)
  return nil if source == dest
  dputs(DEBUG_SLOW) { 'create - 1' }
  if date.class == String
    date = Date.strptime(date, '%Y-%m-%d')
  end
  t = super(:desc => desc, :date => date,
            :value => 0, :account_src_id => source.id, :account_dst_id => dest.id)
  dputs(DEBUG_SLOW) { 'create - 2' }
  t.value = value
  dputs(DEBUG_SLOW) { 'create - 3' }
  t.global_id = Users.match_by_name('local').full + '-' + t.id.to_s
  dputs(DEBUG_SLOW) { 'create - 4' }
  dputs(1) { "Created #{t.to_json.inspect}" }
  t
end
get_account(db, id) click to toggle source
# File lib/africompta/entities/movement.rb, line 98
def get_account(db, id)
  db.execute("select * from compta_accounts where id=#{id}").first[4]
end
migration_1(m) click to toggle source
# File lib/africompta/entities/movement.rb, line 20
def migration_1(m)
  dputs(1) { "Migrating #{m.id}" }
  m.rev_index = m.id
end
search_index_range(from, to) click to toggle source
# File lib/africompta/entities/movement.rb, line 90
def search_index_range(from, to)
  @data.select { |k, v|
    v._rev_index && v._rev_index >= from && v._rev_index <= to
  }.map { |k, v|
    get_data_instance(k)
  }
end
setup_data() click to toggle source
# File lib/africompta/entities/movement.rb, line 5
def setup_data
  @default_type = :SQLiteAC
  @data_field_id = :id
  value_int :index

  value_entity_account :account_src_id
  value_entity_account :account_dst_id
  value_float :value
  value_str :desc
  value_date :date
  value_int :revision
  value_str :global_id
  value_int :rev_index
end