Module: MercuryBanking::Reports::BalanceSheet

Defined in:
lib/mercury_banking/reports/balance_sheet.rb

Overview

Module for generating balance sheet reports

Instance Method Summary collapse

Instance Method Details

#export_transactions_to_beancount(transactions, file_path) ⇒ Object



524
525
526
527
528
529
530
531
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 524

def export_transactions_to_beancount(transactions, file_path)
  # Create a temporary file for beancount export
  File.open(file_path, 'w') do |f|
    write_beancount_header(f)
    (f, transactions)
    write_beancount_transactions(f, transactions)
  end
end

#export_transactions_to_ledger(transactions, file_path) ⇒ Object



432
433
434
435
436
437
438
439
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 432

def export_transactions_to_ledger(transactions, file_path)
  # Create a temporary file for ledger export
  File.open(file_path, 'w') do |f|
    write_ledger_header(f)
    (f, transactions)
    write_ledger_transactions(f, transactions)
  end
end

#fix_ledger_file_syntax(file_path) ⇒ Object

Fix common syntax issues in a ledger file



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 50

def fix_ledger_file_syntax(file_path)
  fixed_file_path = "#{file_path}.fixed"

  # Create a fixed version of the file with safer formatting
  File.open(fixed_file_path, 'w') do |fixed_file|
    File.foreach(file_path) do |line|
      if line.match?(%r{^\d{4}[/\-.]\d{2}[/\-.]\d{2}})
        # This is a transaction line, ensure description is safe
        date, description = line.strip.split(' ', 2)
        if description && (description.match?(/^\d/) ||
                           description.match?(/^[v#]/) ||
                           description.match?(/^\s*\d{4}/) ||
                           description.match?(%r{^\s*\d{2}/\d{2}}))
          fixed_file.puts "#{date} - #{description}"
        else
          fixed_file.puts line
        end
      else
        fixed_file.puts line
      end
    end
  end

  puts "Created fixed ledger file at #{fixed_file_path}"
  fixed_file_path
end

#generate_beancount_balance_report_section(file_path, date_filter) ⇒ Object



367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 367

def generate_beancount_balance_report_section(file_path, date_filter)
  section_output = ""

  balance_cmd = "bean-report #{file_path}#{date_filter} balsheet"
  balance_output = `#{balance_cmd}`

  puts "\n=== Balance Sheet ===\n"
  puts balance_output

  section_output << "=== Balance Sheet ===\n"
  section_output << balance_output
  section_output << "\n"

  section_output
end

#generate_beancount_balance_sheet(file_path, end_date = nil) ⇒ Object

Generate a beancount balance sheet



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 118

def generate_beancount_balance_sheet(file_path, end_date = nil)
  # Check if bean-report command exists
  unless command_exists?('bean-report')
    puts "Error: 'bean-report' command not found. Please install beancount (https://beancount.github.io/)."
    return nil
  end

  # Construct the beancount command
  cmd = "bean-report #{file_path} balances"
  cmd += " --end #{end_date}" if end_date

  # Execute the command
  output = `#{cmd}`

  # Check if the command was successful
  if $?.success?
    output
  else
    puts "Error executing bean-report command: #{cmd}"
    puts output
    nil
  end
end

#generate_beancount_monthly_report_section(file_path, date_filter) ⇒ Object



399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 399

def generate_beancount_monthly_report_section(file_path, date_filter)
  section_output = ""

  monthly_cmd = "bean-report #{file_path}#{date_filter} monthly"
  monthly_output = `#{monthly_cmd}`

  puts "\n=== Monthly Activity ===\n"
  puts monthly_output

  section_output << "=== Monthly Activity ===\n"
  section_output << monthly_output
  section_output << "\n"

  section_output
end

#generate_beancount_pl_report_section(file_path, date_filter) ⇒ Object



383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 383

def generate_beancount_pl_report_section(file_path, date_filter)
  section_output = ""

  pl_cmd = "bean-report #{file_path}#{date_filter} income"
  pl_output = `#{pl_cmd}`

  puts "\n=== Income Statement ===\n"
  puts pl_output

  section_output << "=== Income Statement ===\n"
  section_output << pl_output
  section_output << "\n"

  section_output
end

#generate_beancount_register_report_section(file_path, date_filter, category) ⇒ Object



415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 415

def generate_beancount_register_report_section(file_path, date_filter, category)
  section_output = ""

  register_filter = category ? " --account #{category}" : ""
  register_cmd = "bean-report #{file_path}#{date_filter}#{register_filter} register"
  register_output = `#{register_cmd}`

  puts "\n=== Transaction Register ===\n"
  puts register_output

  section_output << "=== Transaction Register ===\n"
  section_output << register_output
  section_output << "\n"

  section_output
end

#generate_beancount_reports(file_path, report_type, category = nil, end_date = nil) ⇒ Object

Generate beancount reports



339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 339

def generate_beancount_reports(file_path, report_type, category = nil, end_date = nil)
  # Check if bean-report is installed
  unless command_exists?('bean-report')
    puts "Error: 'bean-report' command not found. Please install Beancount to generate reports."
    return
  end

  # Prepare to capture output
  report_output = ""
  report_output << "=== Mercury Banking Beancount Reports ===\n\n"

  puts "\n=== Mercury Banking Beancount Reports ===\n"

  # Build date filter (beancount uses different syntax)
  date_filter = end_date ? " -e #{end_date}" : ""

  # Generate requested reports
  report_output << generate_beancount_balance_report_section(file_path, date_filter) if %w[all balance].include?(report_type)

  report_output << generate_beancount_pl_report_section(file_path, date_filter) if %w[all pl].include?(report_type)

  report_output << generate_beancount_monthly_report_section(file_path, date_filter) if %w[all monthly].include?(report_type)

  report_output << generate_beancount_register_report_section(file_path, date_filter, category) if report_type == 'register'

  report_output
end

#generate_ledger_balance_report(file_path, end_date = nil) ⇒ Object

Generate a balance sheet report using ledger



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 78

def generate_ledger_balance_report(file_path, end_date = nil)
  # Construct the ledger command
  cmd = "ledger -f #{file_path}"
  cmd += " --end #{end_date}" if end_date
  cmd += " balance --flat Assets Liabilities Equity"

  # Execute the command
  output = `#{cmd}`

  # Check if the command was successful
  if $?.success?
    output
  else
    puts "Error executing ledger command: #{cmd}"
    puts "Error output: #{output}"

    # Try with a more permissive approach
    try_permissive_ledger_command(file_path, end_date)
  end
end

#generate_ledger_balance_report_section(file_path, date_filter, category_filter) ⇒ Object



249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 249

def generate_ledger_balance_report_section(file_path, date_filter, category_filter)
  section_output = ""

  balance_cmd = "ledger -f #{file_path}#{date_filter} balance --flat Assets Liabilities Equity#{category_filter}"
  balance_output = `#{balance_cmd}`

  puts "\n=== Balance Sheet ===\n"
  puts balance_output

  section_output << "=== Balance Sheet ===\n"
  section_output << balance_output
  section_output << "\n"

  section_output
end

#generate_ledger_balance_sheet(file_path, end_date = nil) ⇒ Object

Generate a ledger balance sheet



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 8

def generate_ledger_balance_sheet(file_path, end_date = nil)
  # Check if ledger command exists
  unless command_exists?('ledger')
    puts "Error: 'ledger' command not found. Please install ledger (https://www.ledger-cli.org/)."
    return nil
  end

  # Verify the file exists
  unless File.exist?(file_path)
    puts "Error: Ledger file not found at #{file_path}"
    return nil
  end

  # Verify and potentially fix the ledger file
  verified_file_path = verify_ledger_file_syntax(file_path)
  return nil unless verified_file_path

  # Generate the balance sheet
  generate_ledger_balance_report(verified_file_path, end_date)
end

#generate_ledger_monthly_category_report(file_path, date_filter, category) ⇒ Object



305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 305

def generate_ledger_monthly_category_report(file_path, date_filter, category)
  section_output = ""

  monthly_cmd = "ledger -f #{file_path}#{date_filter} --monthly --collapse register #{category}"
  monthly_output = `#{monthly_cmd}`

  puts "\n=== Monthly #{category} ===\n"
  puts monthly_output

  section_output << "=== Monthly #{category} ===\n"
  section_output << monthly_output
  section_output << "\n"

  section_output
end

#generate_ledger_monthly_report_section(file_path, date_filter, category) ⇒ Object



281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 281

def generate_ledger_monthly_report_section(file_path, date_filter, category)
  section_output = ""

  if category
    monthly_cmd = "ledger -f #{file_path}#{date_filter} --monthly --collapse register #{category}"
    monthly_output = `#{monthly_cmd}`

    puts "\n=== Monthly #{category} ===\n"
    puts monthly_output

    section_output << "=== Monthly #{category} ===\n"
    section_output << monthly_output
    section_output << "\n"
  else
    # Generate monthly expenses report
    section_output << generate_ledger_monthly_category_report(file_path, date_filter, "Expenses")

    # Generate monthly income report
    section_output << generate_ledger_monthly_category_report(file_path, date_filter, "Income")
  end

  section_output
end

#generate_ledger_pl_report_section(file_path, date_filter, category_filter) ⇒ Object



265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 265

def generate_ledger_pl_report_section(file_path, date_filter, category_filter)
  section_output = ""

  pl_cmd = "ledger -f #{file_path}#{date_filter} balance --flat Income Expenses#{category_filter}"
  pl_output = `#{pl_cmd}`

  puts "\n=== Income Statement ===\n"
  puts pl_output

  section_output << "=== Income Statement ===\n"
  section_output << pl_output
  section_output << "\n"

  section_output
end

#generate_ledger_register_report_section(file_path, date_filter, category) ⇒ Object



321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 321

def generate_ledger_register_report_section(file_path, date_filter, category)
  section_output = ""

  register_filter = category || "Assets Liabilities Equity Income Expenses"
  register_cmd = "ledger -f #{file_path}#{date_filter} register #{register_filter}"
  register_output = `#{register_cmd}`

  puts "\n=== Transaction Register ===\n"
  puts register_output

  section_output << "=== Transaction Register ===\n"
  section_output << register_output
  section_output << "\n"

  section_output
end

#generate_ledger_reports(file_path, report_type, category = nil, end_date = nil) ⇒ Object

Generate ledger reports (P&L, balance sheet, etc.)



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 218

def generate_ledger_reports(file_path, report_type, category = nil, end_date = nil)
  # Check if ledger is installed
  unless command_exists?('ledger')
    puts "Error: 'ledger' command not found. Please install Ledger CLI to generate reports."
    return
  end

  # Build date filter
  date_filter = end_date ? " --end #{end_date}" : ""

  # Build category filter
  category_filter = category ? " #{category}" : ""

  # Prepare to capture output
  report_output = ""
  report_output << "=== Mercury Banking Ledger Reports ===\n\n"

  puts "\n=== Mercury Banking Ledger Reports ===\n"

  # Generate requested reports
  report_output << generate_ledger_balance_report_section(file_path, date_filter, category_filter) if %w[all balance].include?(report_type)

  report_output << generate_ledger_pl_report_section(file_path, date_filter, category_filter) if %w[all pl].include?(report_type)

  report_output << generate_ledger_monthly_report_section(file_path, date_filter, category) if %w[all monthly].include?(report_type)

  report_output << generate_ledger_register_report_section(file_path, date_filter, category) if report_type == 'register'

  report_output
end

#parse_balance_sheet_output(output, format, debug = false) ⇒ Object

Parse balance sheet output to extract account balances



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 143

def parse_balance_sheet_output(output, format, debug = false)
  balances = {}

  if debug
    puts "\n=== Balance Sheet Parsing Debug ==="
    puts "Raw output to parse:"
    puts output
  end

  case format
  when 'ledger'
    balances = parse_ledger_balance_output(output, debug)
  when 'beancount'
    balances = parse_beancount_balance_output(output, debug)
  else
    puts "Unsupported format: #{format}"
  end

  balances
end

#parse_beancount_balance_output(output, _debug = false) ⇒ Object



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 197

def parse_beancount_balance_output(output, _debug = false)
  balances = {}

  output.each_line do |line|
    # Skip header lines and summary lines
    next if line.strip.empty? || line.include?('---') || line.include?('Assets:') || line.include?('Liabilities:')

    # Extract account name and balance
    next unless line =~ /(\S.*?)\s+([\d,.-]+)\s+USD/

     = ::Regexp.last_match(1).strip
    balance = ::Regexp.last_match(2).gsub(',', '').to_f

    # Add to balances hash
    balances[] = balance
  end

  balances
end

#parse_ledger_balance_output(output, debug = false) ⇒ Object



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 164

def parse_ledger_balance_output(output, debug = false)
  balances = {}

  output.each_line do |line|
    puts "Parsing line: #{line.inspect}" if debug
    line = line.strip

    # Skip empty lines and summary lines
    if line.empty? || line.include?('----')
      puts "  Skipping line (empty or summary)" if debug
      next
    end

    # Extract account name and balance using a more flexible regex
    # The ledger output format is typically something like:
    #              $18.10  Assets:Mercury Checking ••1090
    if (match = line.match(/\$\s*([\d,.-]+)\s+(.+)/))
      balance = match[1].gsub(',', '').to_f
       = match[2].strip

      puts "  Extracted: Account='#{}', Balance=$#{balance}" if debug

      # Add to balances hash
      balances[] = balance
      puts "  Added to balances hash" if debug
    elsif debug
      puts "  No match for balance pattern"
    end
  end

  balances
end

#try_permissive_ledger_command(file_path, end_date = nil) ⇒ Object

Try a more permissive ledger command as a fallback



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 100

def try_permissive_ledger_command(file_path, end_date = nil)
  puts "Trying with more permissive options..."
  cmd = "ledger -f #{file_path} --permissive"
  cmd += " --end #{end_date}" if end_date
  cmd += " balance --flat Assets Liabilities Equity"

  output = `#{cmd}`

  if $?.success?
    output
  else
    puts "Error executing permissive ledger command."
    puts "Error output: #{output}"
    nil
  end
end

#verify_ledger_file_syntax(file_path) ⇒ Object

Verify the syntax of a ledger file and fix common issues if needed



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 30

def verify_ledger_file_syntax(file_path)
  check_cmd = "ledger -f #{file_path} --verify"
  check_output = `#{check_cmd}`

  return file_path if $?.success?

  puts "Warning: Ledger file verification failed. The file may contain syntax errors."
  puts "Error output: #{check_output}"

  # Try to identify problematic lines
  problematic_lines = `grep -n '^[0-9]' #{file_path} | head -10`
  puts "First few transaction lines for inspection:"
  puts problematic_lines

  # Try to fix common issues
  puts "Attempting to fix common issues in the ledger file..."
  fix_ledger_file_syntax(file_path)
end

#write_beancount_account_declarations(file, transactions) ⇒ Object



542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 542

def (file, transactions)
  # First extract account info from transactions
   = transactions.map do |t|
    {
      "name" => t["accountName"] || "Unknown Account",
      "number" => t["accountNumber"]
    }
  end
  # Then make unique based on name and number
  accounts = .uniq { |a| [a["name"], a["number"]] }

  # Define accounts dynamically based on transaction data
  accounts.each do ||
     = ["name"]
     = ["number"]

    # Sanitize account name for beancount format
     = .gsub(/[^a-zA-Z0-9]/, '-')

    # Format the account name to include the account number if available
     = if 
                               "#{}-#{.to_s[-4..]}"
                             else
                               
                             end

    file.puts "1970-01-01 open Assets:#{}"
  end
  file.puts "1970-01-01 open Expenses:Unknown"
  file.puts "1970-01-01 open Income:Unknown"
  file.puts
end

#write_beancount_header(file) ⇒ Object



533
534
535
536
537
538
539
540
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 533

def write_beancount_header(file)
  file.puts "; Mercury Bank Transactions Export"
  file.puts "; Generated on #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
  file.puts
  file.puts "option \"title\" \"Mercury Bank Transactions\""
  file.puts "option \"operating_currency\" \"USD\""
  file.puts
end

#write_beancount_postings(file, amount, account_name, account_number = nil) ⇒ Object



608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 608

def write_beancount_postings(file, amount, ,  = nil)
  # Format the account name to include the account number if available
   = if 
                             "#{}-#{.to_s[-4..]}"
                           else
                             
                           end

  if amount.positive?
    file.puts "  Income:Unknown          -#{format('%.2f', amount)} USD"
    file.puts "  Assets:#{}    #{format('%.2f', amount)} USD"
  else
    file.puts "  Expenses:Unknown          #{format('%.2f', amount.abs)} USD"
    file.puts "  Assets:#{}    -#{format('%.2f', amount.abs)} USD"
  end
end

#write_beancount_transaction(file, transaction) ⇒ Object



585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 585

def write_beancount_transaction(file, transaction)
  date = if transaction["postedAt"]
           Time.parse(transaction["postedAt"]).strftime("%Y-%m-%d")
         else
           Time.parse(transaction["createdAt"]).strftime("%Y-%m-%d")
         end
  description = transaction["bankDescription"] || transaction["externalMemo"] || "Unknown transaction"
  amount = transaction["amount"]
   = transaction["accountName"] || "Unknown Account"
   = transaction["accountNumber"]

  # Sanitize account name for beancount format
   = .gsub(/[^a-zA-Z0-9]/, '-')

  file.puts "#{date} * \"#{description}\""
  file.puts "  ; Transaction ID: #{transaction['id']}"
  file.puts "  ; Status: #{transaction['status']}"
  file.puts "  ; Reconciled: No"

  write_beancount_postings(file, amount, , )
  file.puts
end

#write_beancount_transactions(file, transactions) ⇒ Object



575
576
577
578
579
580
581
582
583
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 575

def write_beancount_transactions(file, transactions)
  # Filter out failed transactions
  valid_transactions = transactions.reject { |t| t["status"] == "failed" }

  # Sort transactions by date
  valid_transactions.sort_by! { |t| t["postedAt"] || t["createdAt"] }.each do |t|
    write_beancount_transaction(file, t)
  end
end

#write_ledger_account_declarations(file, transactions) ⇒ Object



447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 447

def (file, transactions)
  # First extract account info from transactions
   = transactions.map do |t|
    {
      "name" => t["accountName"] || "Unknown Account",
      "number" => t["accountNumber"]
    }
  end
  # Then make unique based on name and number
  accounts = .uniq { |a| [a["name"], a["number"]] }

  # Define accounts dynamically based on transaction data
  accounts.each do ||
     = ["name"]
     = ["number"]

    # Format the account name to include the account number if available
     = if 
                               "#{} #{.to_s[-4..]}"
                             else
                               
                             end

    file.puts "account Assets:#{}"
  end
  file.puts "account Expenses:Unknown"
  file.puts "account Income:Unknown"
  file.puts
end

#write_ledger_header(file) ⇒ Object



441
442
443
444
445
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 441

def write_ledger_header(file)
  file.puts "; Mercury Bank Transactions Export"
  file.puts "; Generated on #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
  file.puts
end

#write_ledger_postings(file, amount, account_name, account_number = nil) ⇒ Object



507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 507

def write_ledger_postings(file, amount, ,  = nil)
  # Format the account name to include the account number if available
   = if 
                             "#{} #{.to_s[-4..]}"
                           else
                             
                           end

  if amount.positive?
    file.puts "    Income:Unknown          $-#{format('%.2f', amount)}"
    file.puts "    Assets:#{}    $#{format('%.2f', amount)}"
  else
    file.puts "    Expenses:Unknown          $#{format('%.2f', amount.abs)}"
    file.puts "    Assets:#{}    $-#{format('%.2f', amount.abs)}"
  end
end

#write_ledger_transaction(file, transaction) ⇒ Object



487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 487

def write_ledger_transaction(file, transaction)
  date = if transaction["postedAt"]
           Time.parse(transaction["postedAt"]).strftime("%Y/%m/%d")
         else
           Time.parse(transaction["createdAt"]).strftime("%Y/%m/%d")
         end
  description = transaction["bankDescription"] || transaction["externalMemo"] || "Unknown transaction"
  amount = transaction["amount"]
   = transaction["accountName"] || "Unknown Account"
   = transaction["accountNumber"]

  file.puts "#{date} #{description}"
  file.puts "    ; Transaction ID: #{transaction['id']}"
  file.puts "    ; Status: #{transaction['status']}"
  file.puts "    ; Reconciled: No"

  write_ledger_postings(file, amount, , )
  file.puts
end

#write_ledger_transactions(file, transactions) ⇒ Object



477
478
479
480
481
482
483
484
485
# File 'lib/mercury_banking/reports/balance_sheet.rb', line 477

def write_ledger_transactions(file, transactions)
  # Filter out failed transactions
  valid_transactions = transactions.reject { |t| t["status"] == "failed" }

  # Sort transactions by date
  valid_transactions.sort_by! { |t| t["postedAt"] || t["createdAt"] }.each do |t|
    write_ledger_transaction(file, t)
  end
end