mercury_banking 0.5.34
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/.env_test +1 -0
- data/.gitignore +24 -0
- data/.rspec +3 -0
- data/.rubocop.yml +17 -0
- data/.travis.yml +6 -0
- data/CHANGELOG.md +90 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +26 -0
- data/Gemfile.lock +140 -0
- data/LICENSE +21 -0
- data/LINTING_REPORT.md +118 -0
- data/README.md +244 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/mercury +17 -0
- data/bin/setup +8 -0
- data/lib/mercury_banking/api.rb +184 -0
- data/lib/mercury_banking/cli/accounts.rb +61 -0
- data/lib/mercury_banking/cli/base.rb +68 -0
- data/lib/mercury_banking/cli/financials.rb +302 -0
- data/lib/mercury_banking/cli/reconciliation.rb +406 -0
- data/lib/mercury_banking/cli/reports.rb +265 -0
- data/lib/mercury_banking/cli/transactions.rb +222 -0
- data/lib/mercury_banking/cli.rb +209 -0
- data/lib/mercury_banking/formatters/export_formatter.rb +306 -0
- data/lib/mercury_banking/formatters/table_formatter.rb +133 -0
- data/lib/mercury_banking/multi.rb +135 -0
- data/lib/mercury_banking/recipient.rb +29 -0
- data/lib/mercury_banking/reconciliation.rb +139 -0
- data/lib/mercury_banking/reports/balance_sheet.rb +586 -0
- data/lib/mercury_banking/reports/reconciliation.rb +307 -0
- data/lib/mercury_banking/utils/command_utils.rb +18 -0
- data/lib/mercury_banking/version.rb +3 -0
- data/lib/mercury_banking.rb +19 -0
- data/mercury_banking.gemspec +37 -0
- metadata +183 -0
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module MercuryBanking
|
5
|
+
# Class to manage reconciliation status for transactions
|
6
|
+
class Reconciliation
|
7
|
+
RECONCILIATION_DIR = File.join(Dir.home, '.mercury-banking', 'reconciliation')
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
# Ensure reconciliation directory exists
|
11
|
+
FileUtils.mkdir_p(RECONCILIATION_DIR)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Get the reconciliation file path for an account
|
15
|
+
def reconciliation_file(account_id)
|
16
|
+
File.join(RECONCILIATION_DIR, "#{account_id}.json")
|
17
|
+
end
|
18
|
+
|
19
|
+
# Load reconciled transactions for an account
|
20
|
+
def load_reconciled_transactions(account_id)
|
21
|
+
file_path = reconciliation_file(account_id)
|
22
|
+
|
23
|
+
if File.exist?(file_path)
|
24
|
+
begin
|
25
|
+
data = JSON.parse(File.read(file_path))
|
26
|
+
# Handle both old format (array of transaction IDs) and new format (hash with dates)
|
27
|
+
if data.is_a?(Array)
|
28
|
+
# Convert old format to new format
|
29
|
+
new_data = {}
|
30
|
+
data.each do |transaction_id|
|
31
|
+
new_data[transaction_id] = nil
|
32
|
+
end
|
33
|
+
return new_data
|
34
|
+
else
|
35
|
+
return data
|
36
|
+
end
|
37
|
+
rescue JSON::ParserError
|
38
|
+
# If the file is corrupted, return an empty hash
|
39
|
+
return {}
|
40
|
+
end
|
41
|
+
else
|
42
|
+
# If the file doesn't exist, return an empty hash
|
43
|
+
return {}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Save reconciled transactions for an account
|
48
|
+
def save_reconciled_transactions(account_id, transactions)
|
49
|
+
file_path = reconciliation_file(account_id)
|
50
|
+
File.write(file_path, JSON.pretty_generate(transactions))
|
51
|
+
end
|
52
|
+
|
53
|
+
# Mark a transaction as reconciled
|
54
|
+
def mark_reconciled(account_id, transaction_id)
|
55
|
+
transactions = load_reconciled_transactions(account_id)
|
56
|
+
|
57
|
+
# Add the transaction ID if it's not already in the list
|
58
|
+
if transactions.key?(transaction_id)
|
59
|
+
return false # Already reconciled
|
60
|
+
else
|
61
|
+
transactions[transaction_id] = Time.now.strftime('%Y-%m-%d')
|
62
|
+
save_reconciled_transactions(account_id, transactions)
|
63
|
+
return true # Successfully reconciled
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Mark a transaction as unreconciled
|
68
|
+
def mark_unreconciled(account_id, transaction_id)
|
69
|
+
transactions = load_reconciled_transactions(account_id)
|
70
|
+
|
71
|
+
# Remove the transaction ID if it's in the list
|
72
|
+
if transactions.key?(transaction_id)
|
73
|
+
transactions.delete(transaction_id)
|
74
|
+
save_reconciled_transactions(account_id, transactions)
|
75
|
+
return true # Successfully unreconciled
|
76
|
+
else
|
77
|
+
return false # Not reconciled to begin with
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Check if a transaction is reconciled
|
82
|
+
def reconciled?(account_id, transaction_id)
|
83
|
+
transactions = load_reconciled_transactions(account_id)
|
84
|
+
transactions.key?(transaction_id)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Get all reconciled transaction IDs for an account
|
88
|
+
def get_reconciled_transactions(account_id)
|
89
|
+
load_reconciled_transactions(account_id).keys
|
90
|
+
end
|
91
|
+
|
92
|
+
# Get the reconciliation date for a transaction
|
93
|
+
def get_reconciliation_date(account_id, transaction_id)
|
94
|
+
transactions = load_reconciled_transactions(account_id)
|
95
|
+
transactions[transaction_id]
|
96
|
+
end
|
97
|
+
|
98
|
+
# Get reconciliation status for all transactions
|
99
|
+
def get_reconciliation_status(account_id, transactions)
|
100
|
+
reconciled_data = load_reconciled_transactions(account_id)
|
101
|
+
|
102
|
+
transactions.map do |t|
|
103
|
+
{
|
104
|
+
transaction_id: t["id"],
|
105
|
+
date: t["postedAt"] || t["createdAt"],
|
106
|
+
description: t["bankDescription"] || t["externalMemo"] || "Unknown transaction",
|
107
|
+
amount: t["amount"],
|
108
|
+
reconciled: reconciled_data.key?(t["id"]),
|
109
|
+
reconciled_at: reconciled_data[t["id"]]
|
110
|
+
}
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Get reconciliation summary
|
115
|
+
def get_reconciliation_summary(account_id, transactions)
|
116
|
+
reconciled_data = load_reconciled_transactions(account_id)
|
117
|
+
|
118
|
+
total_transactions = transactions.size
|
119
|
+
reconciled_count = transactions.count { |t| reconciled_data.key?(t["id"]) }
|
120
|
+
unreconciled_count = total_transactions - reconciled_count
|
121
|
+
|
122
|
+
reconciled_amount = transactions
|
123
|
+
.select { |t| reconciled_data.key?(t["id"]) }
|
124
|
+
.sum { |t| t["amount"].to_f }
|
125
|
+
|
126
|
+
unreconciled_amount = transactions
|
127
|
+
.reject { |t| reconciled_data.key?(t["id"]) }
|
128
|
+
.sum { |t| t["amount"].to_f }
|
129
|
+
|
130
|
+
{
|
131
|
+
total_transactions: total_transactions,
|
132
|
+
reconciled_count: reconciled_count,
|
133
|
+
unreconciled_count: unreconciled_count,
|
134
|
+
reconciled_amount: reconciled_amount,
|
135
|
+
unreconciled_amount: unreconciled_amount
|
136
|
+
}
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|