ledgerjournal 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 54a88d089772a52d3f2679f0ca80c2d3fed563d7cbadd44531ace686018045df
4
- data.tar.gz: f78a221028fd29e7a2553b55431b10fe7ff2ea0cac4fbe4cfb7d62db73f5da3f
3
+ metadata.gz: 0b5770e988a14b6a2a45ada7b393d3a7ef857a822e17a5c4da2caebb50393257
4
+ data.tar.gz: 5fa7b153ddbddc3a175566086b6ebb8277f75428ad34ea065e13a524ec53b2a8
5
5
  SHA512:
6
- metadata.gz: aea34667a60c6560425fa18032ae15b525db1459b741d50e67afed0d52fba9fcce3205163b39ecf01e4d258e59dff21674fdf945f86762df8d9af9296b4a92b5
7
- data.tar.gz: 20a2e543860cd3cc7e72ccd9a805d7bdd20e5cbf485f519afd7be24e84d2949de7fdfbc049fdb6a1ef8995d8bcae0c0d0790e36c6843e2577d8d693b6733fe75
6
+ metadata.gz: d3ce3d96d0e7b9cf22378d8b802b24077be2bcc56f5bffe0005c1b134d1d0621def7f74874ae1f260d5467ce02d7aa06092df30753414b4e59af225f5327fa37
7
+ data.tar.gz: c70b31078daf4176609859c4751d45d0c153dcee4cea59c22774a317aecd74163024b8b56d5f7f419b32460a7a4f7167f221c8cfd9cf5471fdf07ba8e51dc7ef
data/.rubocop.yml ADDED
@@ -0,0 +1,20 @@
1
+ Layout/LineLength:
2
+ Max: 200
3
+
4
+ Metrics/MethodLength:
5
+ Max: 30
6
+
7
+ Style/RedundantReturn:
8
+ Enabled: false
9
+
10
+ Metrics/AbcSize:
11
+ Enabled: false
12
+
13
+ Style/GuardClause:
14
+ Enabled: false
15
+
16
+ Style/FormatStringToken:
17
+ Enabled: false
18
+
19
+ Style/FormatString:
20
+ Enabled: false
data/.travis.yml CHANGED
@@ -2,6 +2,7 @@
2
2
  language: ruby
3
3
  cache: bundler
4
4
  rvm:
5
+ - 2.5
5
6
  - 2.6
6
7
  - 2.7
7
8
  before_install:
data/Gemfile CHANGED
@@ -1,7 +1,9 @@
1
- source "https://rubygems.org"
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in ledgerjournal.gemspec
4
6
  gemspec
5
7
 
6
- gem "rake", "~> 12.0"
7
- gem "minitest", "~> 5.0"
8
+ gem 'minitest', '~> 5.0'
9
+ gem 'rake', '~> 12.0'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ledgerjournal (0.5.0)
4
+ ledgerjournal (0.5.1)
5
5
  nokogiri (~> 1.10)
6
6
  open4 (~> 1.3)
7
7
 
data/README.md CHANGED
@@ -1,9 +1,11 @@
1
1
  # ledgerjournal
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/ledgerjournal.svg)](https://badge.fury.io/rb/ledgerjournal)
3
4
  [![Build Status](https://travis-ci.org/ralfebert/ledgerjournal.svg?branch=master)](https://travis-ci.org/github/ralfebert/ledgerjournal)
5
+ [![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](https://www.rubydoc.info/gems/ledgerjournal/)
4
6
 
5
7
  ledgerjournal is a Ruby gem to read and write [ledger](https://www.ledger-cli.org/) accounting files.
6
- For parsing, it uses the xml output from ledger. For outputting, it formats the ledger data to String in custom Ruby code.
8
+ For parsing, it uses the [ledger xml command](https://www.ledger-cli.org/3.0/doc/ledger3.html#The-xml-command). For outputting, it formats the ledger data as String in Ruby.
7
9
  The ledger binary needs to be installed to parse and pretty-print.
8
10
 
9
11
  ## Usage
@@ -11,7 +13,7 @@ The ledger binary needs to be installed to parse and pretty-print.
11
13
  Parsing a leger file:
12
14
 
13
15
  ```ruby
14
- journal = Ledger::Journal.new(path: "example_journal_en.txt")
16
+ journal = Ledger::Journal.new(path: "example_journal.txt")
15
17
  journal.transactions.each do |tx|
16
18
  puts tx.date, tx.payee
17
19
  end
@@ -20,11 +22,10 @@ end
20
22
  Creating a ledger:
21
23
 
22
24
  ```ruby
23
- journal = Ledger::Journal.new(path: "example_journal_en.txt")
25
+ journal = Ledger::Journal.new()
24
26
 
25
27
  journal.transactions << Ledger::Transaction.new(
26
28
  date: Date.new(2020, 1, 2),
27
- state: :cleared,
28
29
  payee: 'Example Payee',
29
30
  metadata: { "Foo" => "Bar", "Description" => "Example Transaction" },
30
31
  postings: [
@@ -36,6 +37,19 @@ journal.transactions << Ledger::Transaction.new(
36
37
  puts(journal.to_s)
37
38
  ```
38
39
 
40
+ ### Locale-specific settings
41
+
42
+ By default ledgerjournal expectes the ledger default date format '%Y/%m/%d' and amounts with decimal point (1234.56). This is configurable:
43
+
44
+ ```ruby
45
+ Ledger.defaults = Options.new(date_format: '%d.%m.%Y', decimal_comma: true)
46
+ ```
47
+
48
+ or:
49
+
50
+ ```ruby
51
+ Ledger.defaults = Ledger::Options.for_locale(:de)
52
+ ```
39
53
 
40
54
  ## Installation
41
55
 
@@ -59,4 +73,4 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/ralfeb
59
73
 
60
74
  ## License
61
75
 
62
- libledger is released under the MIT License. See LICENSE.md.
76
+ ledgerjournal is released under the MIT License. See LICENSE.md.
data/Rakefile CHANGED
@@ -1,10 +1,12 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rake/testtask'
3
5
 
4
6
  Rake::TestTask.new(:test) do |t|
5
- t.libs << "test"
6
- t.libs << "lib"
7
- t.test_files = FileList["test/**/*_test.rb"]
7
+ t.libs << 'test'
8
+ t.libs << 'lib'
9
+ t.test_files = FileList['test/**/*_test.rb']
8
10
  end
9
11
 
10
- task :default => :test
12
+ task default: :test
data/bin/console CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "bundler/setup"
4
- require "ledgerjournal"
4
+ require 'bundler/setup'
5
+ require 'ledgerjournal'
5
6
 
6
7
  # You can add fixtures and/or initialization code here to make experimenting
7
8
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +11,5 @@ require "ledgerjournal"
10
11
  # require "pry"
11
12
  # Pry.start
12
13
 
13
- require "irb"
14
+ require 'irb'
14
15
  IRB.start(__FILE__)
@@ -1,30 +1,35 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'lib/ledgerjournal/version'
2
4
 
3
5
  Gem::Specification.new do |spec|
4
- spec.name = "ledgerjournal"
6
+ spec.name = 'ledgerjournal'
5
7
  spec.version = Ledger::VERSION
6
8
  spec.licenses = ['MIT']
7
- spec.authors = ["Ralf Ebert"]
8
- spec.email = ["ralf.ebert@gmail.com"]
9
+ spec.authors = ['Ralf Ebert']
10
+ spec.email = ['ralf.ebert@gmail.com']
9
11
 
10
- spec.summary = %q{Library to read and write ledger accounting files.}
11
- spec.description = %q{ledgerjournal is a Ruby gem to read and write ledger accounting files.
12
+ spec.summary = 'Library to read and write ledger accounting files.'
13
+ spec.description = 'ledgerjournal is a Ruby gem to read and write ledger accounting files.
12
14
  For parsing, it uses the xml output from ledger. For outputting, it formats the ledger data to String in custom Ruby code.
13
- The ledger binary needs to be installed to parse and pretty-print.}
14
- spec.homepage = "https://github.com/ralfebert/ledgerjournal"
15
- spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
15
+ The ledger binary needs to be installed to parse and pretty-print.'
16
+ spec.homepage = 'https://github.com/ralfebert/ledgerjournal'
17
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
16
18
 
17
- spec.metadata["homepage_uri"] = spec.homepage
18
- spec.metadata["source_code_uri"] = "https://github.com/ralfebert/ledgerjournal.git"
19
+ spec.metadata = {
20
+ 'homepage_uri' => spec.homepage,
21
+ 'source_code_uri' => 'https://github.com/ralfebert/ledgerjournal.git',
22
+ 'bug_tracker_uri' => 'https://github.com/ralfebert/ledgerjournal/issues',
23
+ 'documentation_uri' => "https://www.rubydoc.info/gems/ledgerjournal/#{Ledger::VERSION}"
24
+ }
19
25
 
20
26
  # Specify which files should be added to the gem when it is released.
21
27
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
28
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
23
29
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
30
  end
25
- spec.require_paths = ["lib"]
26
-
31
+ spec.require_paths = ['lib']
32
+
27
33
  spec.add_dependency 'nokogiri', '~> 1.10'
28
34
  spec.add_dependency 'open4', '~> 1.3'
29
-
30
35
  end
data/lib/ledgerjournal.rb CHANGED
@@ -1,13 +1,13 @@
1
- require "ledgerjournal/version"
2
- require "ledgerjournal/options"
3
- require "ledgerjournal/journal"
4
- require "ledgerjournal/transaction"
5
- require "ledgerjournal/posting"
1
+ # frozen_string_literal: true
2
+
3
+ require 'ledgerjournal/version'
4
+ require 'ledgerjournal/options'
5
+ require 'ledgerjournal/journal'
6
+ require 'ledgerjournal/transaction'
7
+ require 'ledgerjournal/posting'
6
8
 
7
9
  # Ledger provides classes to read and write ledger accounting files.
8
10
  module Ledger
9
-
10
11
  # Error class for errors handling ledger files
11
12
  class Error < StandardError; end
12
-
13
13
  end
@@ -1,13 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'shellwords'
2
4
  require 'nokogiri'
3
5
  require 'open4'
6
+ require 'set'
4
7
 
5
8
  module Ledger
6
-
7
9
  # Represents a ledger journal
8
10
  # @see https://www.ledger-cli.org/3.0/doc/ledger3.html#Journal-Format
9
11
  class Journal
10
-
11
12
  # @return [Array<Ledger::Transaction>] list of transactions in journal
12
13
  attr_accessor :transactions
13
14
  # @return [String] path path to ledger file
@@ -20,8 +21,9 @@ module Ledger
20
21
  @transactions = []
21
22
  if path
22
23
  @path = path
23
- raise Error.new("#{@path} not found") unless File.exist?(@path)
24
- args = ["-f #{@path.shellescape}", ledger_args].compact.join(" ")
24
+ raise Error, "#{@path} not found" unless File.exist?(@path)
25
+
26
+ args = ["-f #{@path.shellescape}", ledger_args].compact.join(' ')
25
27
  read_ledger(ledger_args: args)
26
28
  end
27
29
  end
@@ -29,20 +31,20 @@ module Ledger
29
31
  # @param [Ledger::Journal] other
30
32
  # @return [Boolean] true if the other journal contains equal transactions
31
33
  def ==(other)
32
- self.transactions == other.transactions
34
+ transactions == other.transactions
33
35
  end
34
36
 
35
37
  # @return [String] returns the transactions in the journal formatted as string
36
38
  # @param [Boolean] pretty_print calls ledger to format the journal if true
37
39
  def to_s(pretty_print: true)
38
- str = self.transactions.map(&:to_s).join("\n\n")
40
+ str = transactions.map(&:to_s).join("\n\n")
39
41
  if pretty_print
40
42
  begin
41
- str = Ledger.defaults.run("-f - print", stdin: str)
42
- str = str.lines.map { |line| line.rstrip }.join("\n") + "\n"
43
- rescue => error
43
+ str = Ledger.defaults.run('-f - print', stdin: str)
44
+ str = str.lines.map(&:rstrip).join("\n") + "\n"
45
+ rescue StandardError => e
44
46
  # return an unformatted string if an error occurs
45
- puts "Couldn't format transaction log: #{error}"
47
+ puts "Couldn't format transaction log: #{e}"
46
48
  end
47
49
  end
48
50
  return str
@@ -50,23 +52,24 @@ module Ledger
50
52
 
51
53
  # If the journal was opened from a file, save/overwrite the file with the transactions from this journal.
52
54
  def save!
53
- raise Error.new("Journal was not read from path, cannot save") unless @path
54
- File.write(@path, self.to_s)
55
+ raise Error, 'Journal was not read from path, cannot save' unless @path
56
+
57
+ File.write(@path, to_s)
55
58
  end
56
59
 
57
- # returns all transactions that have a posting for the given account
58
- # @param [String] account account name
60
+ # returns all transactions that have a posting for one of the given accounts
61
+ # @param [String, Array<String>, Set<String>] account account name(s)
59
62
  def transactions_with_account(account)
60
- @transactions.select {|tx| tx.postings.map(&:account).include?(account) }
63
+ accounts = account.is_a?(Enumerable) ? Set.new(account) : Set[account]
64
+ @transactions.select { |tx| accounts.intersect?(Set.new(tx.postings.map(&:account))) }
61
65
  end
62
66
 
63
67
  private
64
- def read_ledger(ledger_args: "")
65
- xml_result = Ledger.defaults.run(ledger_args + " xml")
68
+
69
+ def read_ledger(ledger_args: '')
70
+ xml_result = Ledger.defaults.run(ledger_args + ' xml')
66
71
  xml = Nokogiri::XML(xml_result)
67
- @transactions = xml.css("transaction").map { |tx_xml| Transaction.parse_xml(tx_xml) }
72
+ @transactions = xml.css('transaction').map { |tx_xml| Transaction.parse_xml(tx_xml) }
68
73
  end
69
-
70
74
  end
71
-
72
75
  end
@@ -1,10 +1,10 @@
1
- module Ledger
1
+ # frozen_string_literal: true
2
2
 
3
+ module Ledger
3
4
  # Options for interaction with ledger-cli
4
5
  class Options
5
-
6
6
  # @param [String] date_format like '%Y/%m/%d' to pass to ledger-cli
7
- # @param [Boolean] decimal_comma pass true to use ',' as decimal comma separator
7
+ # @param [Boolean] decimal_comma pass true to use a comma as decimal separator, otherwise a dot is used
8
8
  def initialize(date_format:, decimal_comma:)
9
9
  @date_format = date_format
10
10
  @decimal_comma = decimal_comma
@@ -20,14 +20,14 @@ module Ledger
20
20
  when :de
21
21
  Options.new(date_format: '%d.%m.%Y', decimal_comma: true)
22
22
  else
23
- raise Error.new("Unknown locale for ledger options: #{locale}, supported are :en, :de")
23
+ raise Error, "Unknown locale for ledger options: #{locale}, supported are :en, :de"
24
24
  end
25
25
  end
26
26
 
27
27
  # @param [String] string decimal amount as String (like '12.34')
28
28
  # @return [BigDecimal] the given string as BigDecimal, parsed according the decimal_comma setting
29
29
  def parse_amount(string)
30
- BigDecimal(if @decimal_comma then string.gsub(".", "").gsub(",", ".") else string end)
30
+ BigDecimal(@decimal_comma ? string.gsub('.', '').gsub(',', '.') : string)
31
31
  end
32
32
 
33
33
  # Formats the given value as String
@@ -41,7 +41,7 @@ module Ledger
41
41
  str.gsub!('.', ',') if @decimal_comma
42
42
  return str
43
43
  else
44
- raise Error.new("Unknown value type #{value.class}")
44
+ raise Error, "Unknown value type #{value.class}"
45
45
  end
46
46
  end
47
47
 
@@ -50,23 +50,23 @@ module Ledger
50
50
  # @param [String] stdin stdin text to pass
51
51
  # @return [String] stdout result of calling ledger
52
52
  def run(args, stdin: nil)
53
- output = ""
54
- error = ""
53
+ output = String.new
54
+ error = String.new
55
55
  begin
56
- Open4.spawn("ledger #{cmdline_options} #{args}", :stdin => stdin, :stdout => output, :stderr => error)
57
- rescue => e
58
- raise Error.new("#{e}: #{error}")
56
+ Open4.spawn("ledger #{cmdline_options} #{args}", stdin: stdin, stdout: output, stderr: error)
57
+ rescue StandardError => e
58
+ raise Error, "#{e}: #{error}"
59
59
  end
60
60
  return output
61
61
  end
62
62
 
63
63
  private
64
+
64
65
  def cmdline_options
65
- args = ["--args-only", "--date-format #{@date_format}", "--input-date-format #{@date_format}"]
66
- args << "--decimal-comma" if @decimal_comma
67
- return args.join(" ")
66
+ args = ['--args-only', "--date-format #{@date_format}", "--input-date-format #{@date_format}"]
67
+ args << '--decimal-comma' if @decimal_comma
68
+ return args.join(' ')
68
69
  end
69
-
70
70
  end
71
71
 
72
72
  @defaults = Options.for_locale(:en)
@@ -75,5 +75,4 @@ module Ledger
75
75
  # @attr [Ledger::Options] defaults options to use when interacting with ledger-cli, by default settings for locale :en are used
76
76
  attr_accessor :defaults
77
77
  end
78
-
79
78
  end
@@ -1,17 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'date'
2
4
  require 'bigdecimal'
3
5
 
4
6
  module Ledger
5
-
6
7
  # @attr [String] account
7
8
  # @attr [String] currency
8
9
  # @attr [BigDecimal] amount
9
10
  # @attr [BigDecimal] balance_assignment if a balance_assignment is set, ledger-cli checks the balance of the account after this posting
10
11
  # @attr [Hash<String, String>] metadata
11
12
  class Posting
12
-
13
13
  attr_accessor :account, :currency, :amount, :balance_assignment, :metadata
14
-
14
+
15
15
  def initialize(account:, currency:, amount:, balance_assignment: nil, metadata: {})
16
16
  @account = account
17
17
  @currency = currency
@@ -19,13 +19,14 @@ module Ledger
19
19
  @balance_assignment = balance_assignment
20
20
  @metadata = metadata
21
21
  end
22
-
22
+
23
23
  def self.parse_xml(xml)
24
24
  balance_assignment = nil
25
25
  currency = xml.xpath('post-amount/amount/commodity/symbol').text
26
- if xml_balance = xml.xpath('balance-assignment').first
26
+ if (xml_balance = xml.xpath('balance-assignment').first)
27
27
  balance_currency = xml_balance.xpath('commodity/symbol').text
28
- raise Error.new("Posting currency #{currency} doesn't match assignment currency #{balance_currency}") if currency != balance_currency
28
+ raise Error, "Posting currency #{currency} doesn't match assignment currency #{balance_currency}" if currency != balance_currency
29
+
29
30
  balance_assignment = Ledger.defaults.parse_amount(xml_balance.xpath('quantity').text)
30
31
  end
31
32
  Posting.new(
@@ -33,31 +34,26 @@ module Ledger
33
34
  currency: currency,
34
35
  amount: Ledger.defaults.parse_amount(xml.xpath('post-amount/amount/quantity').text),
35
36
  balance_assignment: balance_assignment,
36
- metadata: Hash[xml.xpath("metadata/value").collect {|m| [m['key'], m.xpath("string").text]}]
37
+ metadata: Hash[xml.xpath('metadata/value').collect { |m| [m['key'], m.xpath('string').text] }]
37
38
  )
38
39
  end
39
-
40
+
40
41
  def ==(other)
41
- self.class == other.class && self.all_fields == other.all_fields
42
+ self.class == other.class && all_fields == other.all_fields
42
43
  end
43
-
44
+
44
45
  def to_s
45
- posting_line = "#{self.account} #{self.currency} #{Ledger.defaults.format(self.amount)}"
46
- if self.balance_assignment
47
- posting_line += " = #{self.currency} #{Ledger.defaults.format(self.balance_assignment)}"
48
- end
46
+ posting_line = "#{account} #{currency} #{Ledger.defaults.format(amount)}"
47
+ posting_line += " = #{currency} #{Ledger.defaults.format(balance_assignment)}" if balance_assignment
49
48
  lines = [posting_line]
50
- unless self.metadata.empty?
51
- lines += metadata.to_a.sort {|a,b| a[0].casecmp(b[0]) }.collect{|m| "; #{m[0]}: #{m[1]}" }
52
- end
49
+ lines += metadata.to_a.sort { |a, b| a[0].casecmp(b[0]) }.collect { |m| "; #{m[0]}: #{m[1]}" } unless metadata.empty?
53
50
  return lines.join("\n")
54
51
  end
55
-
52
+
56
53
  protected
54
+
57
55
  def all_fields
58
- self.instance_variables.map { |variable| self.instance_variable_get variable }
56
+ instance_variables.map { |variable| instance_variable_get variable }
59
57
  end
60
-
61
58
  end
62
-
63
59
  end
@@ -1,14 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'date'
2
4
 
3
5
  module Ledger
4
-
5
6
  # @attr [Date] date
6
7
  # @attr [Symbol] state state of transaction, can be :cleared or :pending
7
8
  # @attr [String] payee
8
9
  # @attr [Hash<String, String>] metadata
9
10
  # @attr [Array<Ledger::Posting>] postings
10
11
  class Transaction
11
-
12
12
  attr_accessor :date, :state, :payee, :metadata, :postings
13
13
 
14
14
  def initialize(date:, state: :cleared, payee:, metadata: {}, postings:)
@@ -21,44 +21,46 @@ module Ledger
21
21
 
22
22
  def self.parse_xml(xml)
23
23
  Transaction.new(
24
- date: Date.strptime(xml.xpath('date').text, '%Y/%m/%d'),
25
- payee: xml.xpath('payee').text,
26
- state: xml['state'].to_sym,
27
- metadata: Hash[xml.xpath("metadata/value").collect { |m| [m['key'], m.xpath("string").text] }],
28
- postings: xml.xpath('postings/posting').map { |posting_xml| Posting.parse_xml(posting_xml) }
24
+ date: Date.strptime(xml.xpath('date').text, '%Y/%m/%d'),
25
+ payee: xml.xpath('payee').text,
26
+ state: xml['state'].to_sym,
27
+ metadata: Hash[xml.xpath('metadata/value').collect { |m| [m['key'], m.xpath('string').text] }],
28
+ postings: xml.xpath('postings/posting').map { |posting_xml| Posting.parse_xml(posting_xml) }
29
29
  )
30
30
  end
31
31
 
32
32
  def ==(other)
33
- self.class == other.class && self.all_fields == other.all_fields
33
+ self.class == other.class && all_fields == other.all_fields
34
34
  end
35
35
 
36
36
  def to_s
37
- date_str = Ledger.defaults.format(self.date)
38
- states = {:pending => "!", :cleared => "*"}
39
- lines = ["#{date_str} #{states[self.state]} #{self.payee}"]
37
+ date_str = Ledger.defaults.format(date)
38
+ states = { pending: '!', cleared: '*' }
39
+ lines = ["#{date_str} #{states[state]} #{payee}"]
40
40
 
41
- unless self.metadata.empty?
42
- lines += metadata.to_a.sort { |a, b| a[0].casecmp(b[0]) }.collect { |m| " ; #{m[0]}: #{m[1]}" }
43
- end
41
+ lines += metadata.to_a.sort { |a, b| a[0].casecmp(b[0]) }.collect { |m| " ; #{m[0]}: #{m[1]}" } unless metadata.empty?
44
42
 
45
- lines += self.postings.map { |posting| posting.to_s.lines.map { |line| " " + line }.join }
43
+ lines += postings.map { |posting| posting.to_s.lines.map { |line| ' ' + line }.join }
46
44
 
47
45
  return lines.join("\n") + "\n"
48
46
  end
49
47
 
50
- # @param [String] account
51
- # @return [Ledger::Posting]
52
- def posting_for_account(account)
53
- postings.select { |posting| posting.account == account }.first
48
+ # @param [String, Array<String>] accounts name(s)
49
+ # @return [Ledger::Posting] Returns the first posting that matches one of the given account names
50
+ def posting_for_account(accounts)
51
+ accounts = [accounts] unless accounts.is_a?(Enumerable)
52
+ accounts.each do |account|
53
+ postings.each do |posting|
54
+ return posting if account == posting.account
55
+ end
56
+ end
57
+ return nil
54
58
  end
55
59
 
56
60
  protected
57
61
 
58
62
  def all_fields
59
- self.instance_variables.map { |variable| self.instance_variable_get(variable) }
63
+ instance_variables.map { |variable| instance_variable_get(variable) }
60
64
  end
61
-
62
65
  end
63
-
64
66
  end
@@ -1,4 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ledger
2
4
  # ledgerjournal version
3
- VERSION = "0.5.0"
5
+ VERSION = '0.5.1'
4
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ledgerjournal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ralf Ebert
@@ -49,6 +49,7 @@ extensions: []
49
49
  extra_rdoc_files: []
50
50
  files:
51
51
  - ".gitignore"
52
+ - ".rubocop.yml"
52
53
  - ".travis.yml"
53
54
  - Gemfile
54
55
  - Gemfile.lock
@@ -70,6 +71,8 @@ licenses:
70
71
  metadata:
71
72
  homepage_uri: https://github.com/ralfebert/ledgerjournal
72
73
  source_code_uri: https://github.com/ralfebert/ledgerjournal.git
74
+ bug_tracker_uri: https://github.com/ralfebert/ledgerjournal/issues
75
+ documentation_uri: https://www.rubydoc.info/gems/ledgerjournal/0.5.1
73
76
  post_install_message:
74
77
  rdoc_options: []
75
78
  require_paths:
@@ -78,7 +81,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
78
81
  requirements:
79
82
  - - ">="
80
83
  - !ruby/object:Gem::Version
81
- version: 2.3.0
84
+ version: 2.5.0
82
85
  required_rubygems_version: !ruby/object:Gem::Requirement
83
86
  requirements:
84
87
  - - ">="