Class: MercuryBanking::Reconciliation

Inherits:
Object
  • Object
show all
Defined in:
lib/mercury_banking/reconciliation.rb

Overview

Class to manage reconciliation status for transactions

Constant Summary collapse

RECONCILIATION_DIR =
File.join(Dir.home, '.mercury-banking', 'reconciliation')

Instance Method Summary collapse

Constructor Details

#initializeReconciliation

Returns a new instance of Reconciliation.



11
12
13
14
# File 'lib/mercury_banking/reconciliation.rb', line 11

def initialize
  # Ensure reconciliation directory exists
  FileUtils.mkdir_p(RECONCILIATION_DIR)
end

Instance Method Details

#get_reconciled_transactions(account_id) ⇒ Object

Get all reconciled transaction IDs for an account



87
88
89
# File 'lib/mercury_banking/reconciliation.rb', line 87

def get_reconciled_transactions()
  load_reconciled_transactions().keys
end

#get_reconciliation_date(account_id, transaction_id) ⇒ Object

Get the reconciliation date for a transaction



92
93
94
95
# File 'lib/mercury_banking/reconciliation.rb', line 92

def get_reconciliation_date(, transaction_id)
  transactions = load_reconciled_transactions()
  transactions[transaction_id]
end

#get_reconciliation_status(account_id, transactions) ⇒ Object

Get reconciliation status for all transactions



98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/mercury_banking/reconciliation.rb', line 98

def get_reconciliation_status(, transactions)
  reconciled_data = load_reconciled_transactions()

  transactions.map do |t|
    {
      transaction_id: t["id"],
      date: t["postedAt"] || t["createdAt"],
      description: t["bankDescription"] || t["externalMemo"] || "Unknown transaction",
      amount: t["amount"],
      reconciled: reconciled_data.key?(t["id"]),
      reconciled_at: reconciled_data[t["id"]]
    }
  end
end

#get_reconciliation_summary(account_id, transactions) ⇒ Object

Get reconciliation summary



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/mercury_banking/reconciliation.rb', line 114

def get_reconciliation_summary(, transactions)
  reconciled_data = load_reconciled_transactions()

  total_transactions = transactions.size
  reconciled_count = transactions.count { |t| reconciled_data.key?(t["id"]) }
  unreconciled_count = total_transactions - reconciled_count

  reconciled_amount = transactions
                      .select { |t| reconciled_data.key?(t["id"]) }
                      .sum { |t| t["amount"].to_f }

  unreconciled_amount = transactions
                        .reject { |t| reconciled_data.key?(t["id"]) }
                        .sum { |t| t["amount"].to_f }

  {
    total_transactions: total_transactions,
    reconciled_count: reconciled_count,
    unreconciled_count: unreconciled_count,
    reconciled_amount: reconciled_amount,
    unreconciled_amount: unreconciled_amount
  }
end

#load_reconciled_transactions(account_id) ⇒ Object

Load reconciled transactions for an account



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/mercury_banking/reconciliation.rb', line 22

def load_reconciled_transactions()
  file_path = reconciliation_file()

  return {} unless File.exist?(file_path)

  begin
    data = JSON.parse(File.read(file_path))
    # Handle both old format (array of transaction IDs) and new format (hash with dates)
    return data unless data.is_a?(Array)

    # Convert old format to new format
    new_data = {}
    data.each do |transaction_id|
      new_data[transaction_id] = nil
    end
    new_data
  rescue JSON::ParserError
    # If the file is corrupted, return an empty hash
    {}
  end

  # If the file doesn't exist, return an empty hash
end

#mark_reconciled(account_id, transaction_id) ⇒ Object

Mark a transaction as reconciled



53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/mercury_banking/reconciliation.rb', line 53

def mark_reconciled(, transaction_id)
  transactions = load_reconciled_transactions()

  # Add the transaction ID if it's not already in the list
  return false if transactions.key?(transaction_id)

  # Already reconciled

  transactions[transaction_id] = Time.now.strftime('%Y-%m-%d')
  save_reconciled_transactions(, transactions)
  true # Successfully reconciled
end

#mark_unreconciled(account_id, transaction_id) ⇒ Object

Mark a transaction as unreconciled



67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/mercury_banking/reconciliation.rb', line 67

def mark_unreconciled(, transaction_id)
  transactions = load_reconciled_transactions()

  # Remove the transaction ID if it's in the list
  return false unless transactions.key?(transaction_id)

  transactions.delete(transaction_id)
  save_reconciled_transactions(, transactions)
  true # Successfully unreconciled

  # Not reconciled to begin with
end

#reconciled?(account_id, transaction_id) ⇒ Boolean

Check if a transaction is reconciled

Returns:

  • (Boolean)


81
82
83
84
# File 'lib/mercury_banking/reconciliation.rb', line 81

def reconciled?(, transaction_id)
  transactions = load_reconciled_transactions()
  transactions.key?(transaction_id)
end

#reconciliation_file(account_id) ⇒ Object

Get the reconciliation file path for an account



17
18
19
# File 'lib/mercury_banking/reconciliation.rb', line 17

def reconciliation_file()
  File.join(RECONCILIATION_DIR, "#{}.json")
end

#save_reconciled_transactions(account_id, transactions) ⇒ Object

Save reconciled transactions for an account



47
48
49
50
# File 'lib/mercury_banking/reconciliation.rb', line 47

def save_reconciled_transactions(, transactions)
  file_path = reconciliation_file()
  File.write(file_path, JSON.pretty_generate(transactions))
end