appydave-tools 0.10.2 → 0.10.4

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: 63c99bf6126fd82479ca9280e75f8d5c9226b1e8f6df4f6f581476363fd45245
4
- data.tar.gz: 2f171fac8f490c259e6d259c848af330f3b7c4c1a35aea456fcc85251224f69e
3
+ metadata.gz: 40337ac9a46d2a5d2b7a645b14e572f011c84b52e958ba880be666d6dfe3413b
4
+ data.tar.gz: 4e4e4bd076cae97a6cdec63dd70313f49efcbb19fb6295ffd1ef297dbbf08e42
5
5
  SHA512:
6
- metadata.gz: 06227ef4baf7765404e787a91dd53728032cfcea6718b36d19bb378f35b754eabd365d1a2eea270299f6b2fb2ab98bfa529feff71426fd78b0968768c23131b2
7
- data.tar.gz: 6ac8d46c1f8afb609faf5145fe864e24b09de807691295eef2613029c0ebcfb30f92adbb60a437e810b14b7ba841e1e1bb5cb1499ca5fab5b7864907e91b4e53
6
+ metadata.gz: 86448501dd1959eb0173ed98af2dead6965b56bf9cfcdc5007d335b73ecd94f8bb7e5cda9f099997285509e93f7ecff1368740fbe38c16c5e4240b1578462116
7
+ data.tar.gz: 9e32acedc6fbc3b7e21123a56f068e7c91a6b6b4cc58a7315102a08b9455950f531755c5d1405b66dd52a9df60132aab08395877f771d8b096bb364aa6e83e7e
data/.rubocop.yml CHANGED
@@ -14,6 +14,7 @@ AllCops:
14
14
  Exclude:
15
15
  - ".builders/**/*"
16
16
  - "spec/samples/**/*"
17
+ - "**/deprecated/**/*"
17
18
 
18
19
  Metrics/BlockLength:
19
20
  Exclude:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [0.10.3](https://github.com/klueless-io/appydave-tools/compare/v0.10.2...v0.10.3) (2024-06-17)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * extending bank reconciliation with platform and banking mapping ([848b044](https://github.com/klueless-io/appydave-tools/commit/848b044bf4bb7c27bae6cf33aba400ab68eb105c))
7
+
8
+ ## [0.10.2](https://github.com/klueless-io/appydave-tools/compare/v0.10.1...v0.10.2) (2024-06-17)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * make progress on prompt completion tool ([fbc60b7](https://github.com/klueless-io/appydave-tools/commit/fbc60b712e3e18d7f73c47f4568bae65295557df))
14
+
1
15
  ## [0.10.1](https://github.com/klueless-io/appydave-tools/compare/v0.10.0...v0.10.1) (2024-06-13)
2
16
 
3
17
 
@@ -14,6 +14,7 @@ class BankReconciliationCLI
14
14
  def initialize
15
15
  @commands = {
16
16
  'clean' => method(:clean_transactions),
17
+ 'transform' => method(:transform),
17
18
  'process' => method(:process_transactions),
18
19
  'filter' => method(:filter_transactions)
19
20
  }
@@ -48,6 +49,10 @@ class BankReconciliationCLI
48
49
  options[:output] = v
49
50
  end
50
51
 
52
+ opts.on('-d', '--debug', 'Enable debug mode') do
53
+ options[:debug] = true
54
+ end
55
+
51
56
  opts.on_tail('-h', '--help', 'Show this message') do
52
57
  puts opts
53
58
  exit
@@ -58,17 +63,37 @@ class BankReconciliationCLI
58
63
  output_file = options[:output] || 'clean_transactions.csv'
59
64
  include_patterns = options[:include].empty? ? ['*'] : options[:include]
60
65
 
61
- puts "Cleaning transactions with options: #{options}"
66
+ # puts "Cleaning transactions with options: #{options}"
62
67
 
63
68
  # Ensure the clean directory exists
64
69
  clean_dir = File.dirname(output_file)
65
70
  FileUtils.mkdir_p(clean_dir)
66
71
 
67
72
  # Initialize the CleanTransactions class and process the files
68
- cleaner = Appydave::Tools::BankReconciliation::Clean::CleanTransactions.new(transaction_folder: transaction_folder)
73
+ cleaner = Appydave::Tools::BankReconciliation::Clean::CleanTransactions.new(transaction_folder: transaction_folder, debug: options[:debug])
69
74
  cleaner.clean_transactions(include_patterns, output_file)
75
+ end
76
+
77
+ def transform(args)
78
+ options = {}
79
+ OptionParser.new do |opts|
80
+ opts.banner = 'Usage: bank_reconciliation.rb clean [options]'
81
+
82
+ opts.on('-c', '--to-csv', 'Write chart of accounts JSON to CSV') { options[:to_csv] = true }
83
+ opts.on('-j', '--to-json', 'Write chart of accounts CSV to JSON') { options[:to_json] = true }
84
+
85
+ opts.on('-d', '--debug', 'Enable debug mode') do
86
+ options[:debug] = true
87
+ end
88
+
89
+ opts.on_tail('-h', '--help', 'Show this message') do
90
+ puts opts
91
+ exit
92
+ end
93
+ end.parse!(args)
70
94
 
71
- puts "Cleaning transactions with options: #{options}"
95
+ Appydave::Tools::Configuration::Models::BankReconciliationConfig.new.coa_to_csv if options[:to_csv]
96
+ Appydave::Tools::Configuration::Models::BankReconciliationConfig.new.coa_csv_to_json if options[:to_json]
72
97
  end
73
98
 
74
99
  def process_transactions(args)
@@ -76,6 +101,7 @@ class BankReconciliationCLI
76
101
  OptionParser.new do |opts|
77
102
  opts.banner = 'Usage: bank_reconciliation.rb process [options]'
78
103
  opts.on('-i', '--input FILE', 'Input CSV file with transactions') { |v| options[:input] = v }
104
+ opts.on('-d', '--debug', 'Enable debug mode') { |v| options[:debug] = v }
79
105
  opts.on_tail('-h', '--help', 'Show this message') do
80
106
  puts opts
81
107
  exit
@@ -96,8 +122,9 @@ class BankReconciliationCLI
96
122
  opts.on('-e', '--end DATE', 'Filter by dates less than or eqaul to DDMMYY') { |v| options[:year] = v }
97
123
  opts.on('-c', '--codes CODES', 'Filter by chart of account codes (comma-separated)') { |v| options[:codes] = v }
98
124
  opts.on('-w', '--wild TEXT', 'Wildcard text match') { |v| options[:text] = v }
99
- opts.on('-d', '--display', 'Display filtered transactions in table format') { |v| options[:display] = v }
125
+ opts.on('-v', '--view', 'Display filtered transactions in table format') { |v| options[:display] = v }
100
126
  opts.on('-o', '--output FILE', 'Output CSV file name') { |v| options[:output] = v }
127
+ opts.on('-d', '--debug', 'Enable debug mode') { |v| options[:debug] = v }
101
128
  opts.on_tail('-h', '--help', 'Show this message') do
102
129
  puts opts
103
130
  exit
@@ -15,7 +15,7 @@ module Appydave
15
15
 
16
16
  def initialize
17
17
  @config_path = File.join(Config.config_path, "#{config_name}.json")
18
- puts "Config path: #{config_path}"
18
+ # puts "Config path: #{config_path}"
19
19
  @data = load
20
20
  end
21
21
 
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Appydave
4
+ module Tools
5
+ # Debuggable is a module for adding debug logging to classes
6
+ module Debuggable
7
+ attr_accessor :debug
8
+
9
+ def log_info(message)
10
+ log.info(message) if debug
11
+ end
12
+
13
+ def log_kv(key, value)
14
+ log.kv(key, value) if debug
15
+ end
16
+
17
+ def log_subheading(message)
18
+ log.subheading(message) if debug
19
+ end
20
+ end
21
+ end
22
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Appydave
4
4
  module Tools
5
- module PromptTools
5
+ module Llm
6
6
  module Models
7
7
  # What LLM are we using?
8
8
  class LlmInfo < Appydave::Tools::Types::BaseModel
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Appydave
4
+ module Tools
5
+ module Llm
6
+ class OpenAiCompletion
7
+ include KLog::Logging
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ # AI Prompt Tool
2
+
3
+ Tool for running AI prompt based tasks.
4
+
5
+ [ChatGPT - Update video](https://chatgpt.com/c/cf08e889-cad7-4277-918e-82f4a23b0bc8)
@@ -16,7 +16,7 @@ module Appydave
16
16
  attr_reader :clipboard
17
17
 
18
18
  def initialize(options = {})
19
- configure(options)
19
+ setup_options(options)
20
20
 
21
21
  validate_options
22
22
  end
@@ -44,7 +44,7 @@ module Appydave
44
44
 
45
45
  private
46
46
 
47
- def configure(options)
47
+ def setup_options(options)
48
48
  @prompt = options.delete(:prompt)
49
49
  @prompt_file = options.delete(:prompt_file)
50
50
  @llm = Appydave::Tools::PromptTools::Models::LlmInfo.new(
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Appydave
4
4
  module Tools
5
- VERSION = '0.10.2'
5
+ VERSION = '0.10.4'
6
6
  end
7
7
  end
@@ -2,4 +2,4 @@
2
2
 
3
3
  Service classes for interacting with the YouTube API.
4
4
 
5
- [ChatGPT - Update video](https://chatgpt.com/c/41b75159-95c5-4183-92f3-e1be5e52a1e8)
5
+ [ChatGPT - Update video](https://chatgpt.com/c/41b75159-95c5-4183-92f3-e1be5e52a1e8)
@@ -18,11 +18,15 @@ require 'webrick'
18
18
  require 'pry'
19
19
 
20
20
  require 'appydave/tools/version'
21
+ require 'appydave/tools/debuggable'
21
22
  require 'appydave/tools/types/indifferent_access_hash'
22
23
  require 'appydave/tools/types/hash_type'
23
24
  require 'appydave/tools/types/array_type'
24
25
  require 'appydave/tools/types/base_model'
25
26
 
27
+ require 'appydave/tools/llm/models/llm_info'
28
+ require 'appydave/tools/llm/openai_completion'
29
+
26
30
  require 'appydave/tools/cli_actions/base_action'
27
31
 
28
32
  # May want to move this into the tools location
@@ -37,16 +41,15 @@ require 'appydave/tools/configuration/configurable'
37
41
  require 'appydave/tools/configuration/config'
38
42
  require 'appydave/tools/configuration/models/config_base'
39
43
  require 'appydave/tools/configuration/models/settings_config'
40
- require 'appydave/tools/configuration/models/bank_reconciliation_config'
44
+ # require 'appydave/tools/configuration/models/bank_reconciliation_config'
41
45
  require 'appydave/tools/configuration/models/channels_config'
42
46
  require 'appydave/tools/configuration/models/youtube_automation_config'
43
47
  require 'appydave/tools/name_manager/project_name'
44
- require 'appydave/tools/bank_reconciliation/clean/clean_transactions'
45
- require 'appydave/tools/bank_reconciliation/clean/read_transactions'
46
- require 'appydave/tools/bank_reconciliation/clean/mapper'
47
- require 'appydave/tools/bank_reconciliation/models/transaction'
48
+ # require 'appydave/tools/bank_reconciliation/clean/clean_transactions'
49
+ # require 'appydave/tools/bank_reconciliation/clean/read_transactions'
50
+ # require 'appydave/tools/bank_reconciliation/clean/mapper'
51
+ # require 'appydave/tools/bank_reconciliation/models/transaction'
48
52
 
49
- require 'appydave/tools/prompt_tools/models/llm_info'
50
53
  require 'appydave/tools/prompt_tools/prompt_completion'
51
54
 
52
55
  require 'appydave/tools/subtitle_master/clean'
data/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "appydave-tools",
3
- "version": "0.10.2",
3
+ "version": "0.10.4",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "appydave-tools",
9
- "version": "0.10.2",
9
+ "version": "0.10.4",
10
10
  "devDependencies": {
11
11
  "@klueless-js/semantic-release-rubygem": "github:klueless-js/semantic-release-rubygem",
12
12
  "@semantic-release/changelog": "^6.0.3",
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appydave-tools",
3
- "version": "0.10.2",
3
+ "version": "0.10.4",
4
4
  "description": "AppyDave YouTube Automation Tools",
5
5
  "scripts": {
6
6
  "release": "semantic-release"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appydave-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.2
4
+ version: 0.10.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Cruwys
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-06-17 00:00:00.000000000 Z
11
+ date: 2024-10-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -167,11 +167,6 @@ files:
167
167
  - bin/youtube_manager.rb
168
168
  - images.log
169
169
  - lib/appydave/tools.rb
170
- - lib/appydave/tools/bank_reconciliation/_doc.md
171
- - lib/appydave/tools/bank_reconciliation/clean/clean_transactions.rb
172
- - lib/appydave/tools/bank_reconciliation/clean/mapper.rb
173
- - lib/appydave/tools/bank_reconciliation/clean/read_transactions.rb
174
- - lib/appydave/tools/bank_reconciliation/models/transaction.rb
175
170
  - lib/appydave/tools/cli_actions/_doc.md
176
171
  - lib/appydave/tools/cli_actions/base_action.rb
177
172
  - lib/appydave/tools/cli_actions/get_video_action.rb
@@ -180,18 +175,20 @@ files:
180
175
  - lib/appydave/tools/configuration/_doc.md
181
176
  - lib/appydave/tools/configuration/config.rb
182
177
  - lib/appydave/tools/configuration/configurable.rb
183
- - lib/appydave/tools/configuration/models/bank_reconciliation_config.rb
184
178
  - lib/appydave/tools/configuration/models/channels_config.rb
185
179
  - lib/appydave/tools/configuration/models/config_base.rb
186
180
  - lib/appydave/tools/configuration/models/settings_config copy.xrb
187
181
  - lib/appydave/tools/configuration/models/settings_config.rb
188
182
  - lib/appydave/tools/configuration/models/youtube_automation_config.rb
189
183
  - lib/appydave/tools/configuration/openai.rb
184
+ - lib/appydave/tools/debuggable.rb
190
185
  - lib/appydave/tools/gpt_context/_doc.md
191
186
  - lib/appydave/tools/gpt_context/file_collector.rb
187
+ - lib/appydave/tools/llm/models/llm_info.rb
188
+ - lib/appydave/tools/llm/openai_completion.rb
192
189
  - lib/appydave/tools/name_manager/_doc.md
193
190
  - lib/appydave/tools/name_manager/project_name.rb
194
- - lib/appydave/tools/prompt_tools/models/llm_info.rb
191
+ - lib/appydave/tools/prompt_tools/_doc.md
195
192
  - lib/appydave/tools/prompt_tools/prompt_completion.rb
196
193
  - lib/appydave/tools/subtitle_master/_doc.md
197
194
  - lib/appydave/tools/subtitle_master/clean.rb
@@ -1,36 +0,0 @@
1
- # Bank reconciliation
2
-
3
- [ChatGPT conversation](https://chatgpt.com/c/5d382562-95e5-4243-9b74-c3807d363486)
4
-
5
-
6
- ## Code structure
7
-
8
- ```bash
9
- ├─ lib
10
- │ ├─ appydave
11
- │ │ └─ tools
12
- │ │ ├─ bank_reconciliation
13
- │ │ │ ├─ clean
14
- │ │ │ │ ├─ read_transactions.rb
15
- │ │ │ │ ├─ transaction_cleaner.rb
16
- │ │ │ ├─ models
17
- │ │ │ │ ├─ raw_transaction.rb
18
- │ │ │ │ └─ reconciled_transaction.rb
19
- │ │ └─ configuration
20
- │ │ └─ models
21
- │ │ └─ bank_reconciliation_config.rb
22
- └─ spec
23
- ├─ appydave
24
- │ ├─ tools
25
- │ │ ├─ bank_reconciliation
26
- │ │ │ ├─ clean
27
- │ │ │ │ ├─ read_transactions_spec.rb
28
- │ │ │ ├─ models
29
- │ │ │ │ └─ raw_transaction_spec.rb
30
- │ │ └─ configuration
31
- │ │ └─ models
32
- │ │ └─ bank_reconciliation_config_spec.rb
33
- └─ fixtures
34
- └─ bank-reconciliation
35
- └─ bank-west.csv
36
- ```
@@ -1,106 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Appydave
4
- module Tools
5
- module BankReconciliation
6
- module Clean
7
- # Clean transactions
8
- class CleanTransactions
9
- include Appydave::Tools::Configuration::Configurable
10
- include KLog::Logging
11
-
12
- attr_reader :transaction_folder
13
- attr_reader :output_folder
14
- attr_reader :transactions
15
-
16
- # (config_file)
17
- def initialize(transaction_folder: nil, output_folder: nil)
18
- # needs to use config.bank_reconciliation.transaction_folder
19
- transaction_folder ||= '/Volumes/Expansion/Sync/bank-reconciliation/original-transactions'
20
- output_folder ||= File.join(transaction_folder, 'clean')
21
-
22
- @transaction_folder = transaction_folder
23
- @output_folder = output_folder
24
- end
25
-
26
- def clean_transactions(input_globs, output_file)
27
- raw_transactions = grab_raw_transactions(input_globs)
28
- transactions, duplicates_count = deduplicate(raw_transactions)
29
-
30
- transactions = Mapper.new.map(transactions)
31
-
32
- # tp transactions, Appydave::Tools::BankReconciliation::Models::Transaction.csv_headers
33
-
34
- log.kv 'Deduped consolidated transactions', duplicates_count if duplicates_count.positive?
35
-
36
- save_to_csv(transactions, output_file)
37
-
38
- @transactions = transactions
39
- end
40
-
41
- private
42
-
43
- def grab_raw_transactions(input_globs)
44
- original_dir = Dir.pwd
45
- transactions = []
46
-
47
- begin
48
- Dir.chdir(transaction_folder)
49
-
50
- input_globs.each do |glob|
51
- Dir.glob(glob).each do |file|
52
- log.kv 'Reading transactions from', file
53
- raw_transactions = ReadTransactions.new(file).read
54
- deduped_transactions, duplicates_count = deduplicate(raw_transactions)
55
-
56
- if duplicates_count.positive?
57
- log.kv 'Duplicates count', duplicates_count
58
- log.kv 'File', file
59
- end
60
-
61
- transactions += deduped_transactions
62
- end
63
- end
64
- ensure
65
- Dir.chdir(original_dir)
66
- end
67
-
68
- transactions
69
- end
70
-
71
- def deduplicate(transactions)
72
- unique_transactions = transactions.uniq do |transaction|
73
- [
74
- transaction.bsb_number,
75
- transaction.account_number,
76
- transaction.transaction_date,
77
- transaction.narration,
78
- transaction.cheque_number,
79
- transaction.debit,
80
- transaction.credit,
81
- transaction.balance,
82
- transaction.transaction_type
83
- ]
84
- end
85
-
86
- duplicates = transactions.size - unique_transactions.size
87
-
88
- [unique_transactions, duplicates]
89
- end
90
-
91
- def save_to_csv(transactions, output_file)
92
- FileUtils.mkdir_p(output_folder)
93
- output_file = File.join(output_folder, output_file)
94
-
95
- CSV.open(output_file, 'w') do |csv|
96
- csv << Appydave::Tools::BankReconciliation::Models::Transaction.csv_headers
97
- transactions.each do |transaction|
98
- csv << transaction.to_csv_row
99
- end
100
- end
101
- end
102
- end
103
- end
104
- end
105
- end
106
- end
@@ -1,136 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Appydave
4
- module Tools
5
- module BankReconciliation
6
- module Clean
7
- # Map transactions to chart of accounts and bank accounts
8
- class Mapper
9
- include Appydave::Tools::Configuration::Configurable
10
-
11
- # "bank_accounts": [
12
- # {
13
- # "account_number": "5435 6859 0116 7736",
14
- # "bsb": "",
15
- # "name": "Mastercard",
16
- # "platform": "Bankwest"
17
- # },
18
- # {
19
- # "account_number": "303-092",
20
- # "bsb": "1361644",
21
- # "name": "atcall",
22
- # "platform": "Bankwest"
23
- # },
24
-
25
- def map(transactions)
26
- transactions.map do |original_transaction|
27
- transaction = original_transaction.dup
28
-
29
- transaction = map_chart_of_account(transaction)
30
- map_bank_account(transaction)
31
- end
32
- end
33
-
34
- private
35
-
36
- def map_chart_of_account(transaction)
37
- equality_match(transaction) ||
38
- trigram_match(transaction, 0.9, '90%') ||
39
- trigram_match(transaction, 0.8, '80%') ||
40
- trigram_match(transaction, 0.7, '70%') ||
41
- trigram_match(transaction, 0.6, '60%') ||
42
- trigram_match(transaction, 0.5, '50%') ||
43
- start_with_match(transaction) ||
44
- includes(transaction)
45
- transaction
46
- end
47
-
48
- def map_bank_account(transaction)
49
- bank_account = config.bank_reconciliation.get_bank_account(transaction.account_number, transaction.bsb_number)
50
-
51
- if bank_account
52
- transaction.account_name = bank_account.name
53
- transaction.platform = bank_account.platform
54
- end
55
-
56
- transaction
57
- end
58
-
59
- def equality_match(transaction)
60
- coa = config.bank_reconciliation.chart_of_accounts.find do |chart_of_account|
61
- chart_of_account.narration.to_s.delete(' ').downcase == transaction.narration.delete(' ').downcase
62
- end
63
-
64
- return nil unless coa
65
-
66
- transaction.coa_match_type = 'equality'
67
- transaction.coa_code = coa.code
68
- transaction
69
- end
70
-
71
- def start_with_match(transaction)
72
- coa = config.bank_reconciliation.chart_of_accounts.find do |chart_of_account|
73
- transaction.narration.to_s.delete(' ').downcase.start_with?(chart_of_account.narration.to_s.downcase)
74
- end
75
-
76
- return nil unless coa
77
-
78
- transaction.coa_match_type = 'starts_with'
79
- transaction.coa_code = coa.code
80
- transaction
81
- end
82
-
83
- def includes(transaction)
84
- coa = config.bank_reconciliation.chart_of_accounts.find do |chart_of_account|
85
- transaction.narration.to_s.delete(' ').downcase.include?(chart_of_account.narration.delete(' ').to_s.downcase)
86
- end
87
-
88
- return nil unless coa
89
-
90
- transaction.coa_match_type = 'includes'
91
- transaction.coa_code = coa.code
92
- transaction
93
- end
94
-
95
- def trigram_match(transaction, score_threshold, match_type)
96
- scored_transactions = config.bank_reconciliation.chart_of_accounts.map do |coa|
97
- {
98
- coa: coa,
99
- score: compare(coa.narration, transaction.narration)
100
- }
101
- end
102
-
103
- scored_transactions.sort_by! { |t| t[:score] }.reverse!
104
-
105
- best = scored_transactions.first
106
-
107
- return nil unless best
108
- return nil if best[:score] < score_threshold
109
-
110
- coa = best[:coa]
111
-
112
- transaction.coa_match_type = match_type
113
- transaction.coa_code = coa.code
114
- transaction
115
- end
116
-
117
- def compare(text1, text2)
118
- text1_trigs = trigramify(text1)
119
- text2_trigs = trigramify(text2)
120
-
121
- all_cnt = (text1_trigs | text2_trigs).size
122
- same_cnt = (text1_trigs & text2_trigs).size
123
-
124
- same_cnt.to_f / all_cnt
125
- end
126
-
127
- def trigramify(text)
128
- trigs = []
129
- text.chars.each_cons(3) { |v| trigs << v.join }
130
- trigs
131
- end
132
- end
133
- end
134
- end
135
- end
136
- end
@@ -1,88 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Appydave
4
- module Tools
5
- module BankReconciliation
6
- module Clean
7
- # Read transactions from a CSV file
8
- class ReadTransactions
9
- attr_reader :platform
10
- attr_reader :transactions
11
-
12
- def initialize(file)
13
- @file = file
14
- end
15
-
16
- def read
17
- csv_lines = File.read(@file).lines
18
-
19
- @platform = detect_platform(csv_lines)
20
-
21
- case platform
22
- when :bankwest
23
- read_bankwest(csv_lines)
24
- when :bankwest2
25
- read_bankwest2(csv_lines)
26
- end
27
- end
28
-
29
- private
30
-
31
- def read_bankwest(csv_lines)
32
- @transactions = []
33
-
34
- # Skip the header line and parse each subsequent line
35
- CSV.parse(csv_lines.join, headers: true).each do |row|
36
- transaction = Models::Transaction.new(
37
- bsb_number: row['BSB Number'],
38
- account_number: row['Account Number'],
39
- transaction_date: row['Transaction Date'],
40
- narration: row['Narration'],
41
- cheque_number: row['Cheque Number'],
42
- debit: row['Debit'],
43
- credit: row['Credit'],
44
- balance: row['Balance'],
45
- transaction_type: row['Transaction Type']
46
- )
47
- @transactions << transaction
48
- end
49
-
50
- @transactions
51
- end
52
-
53
- def read_bankwest2(csv_lines)
54
- @transactions = []
55
-
56
- # Skip the header line and parse each subsequent line
57
- CSV.parse(csv_lines.join, headers: true).each do |row|
58
- transaction = Models::Transaction.new(
59
- bsb_number: row['BSB / Account Number'].split(' - ').first,
60
- account_number: row['BSB / Account Number'].split(' - ').last,
61
- transaction_date: row['Transaction Date'],
62
- narration: row['Narration'],
63
- cheque_number: row['Cheque Number'],
64
- debit: row['Debit'],
65
- credit: row['Credit'],
66
- balance: row['Balance'],
67
- transaction_type: row['Transaction Type']
68
- )
69
- @transactions << transaction
70
- end
71
-
72
- @transactions
73
- end
74
-
75
- # For bankwest the first row is the CSV will look like:
76
- # BSB Number,Account Number,Transaction Date,Narration,Cheque Number,Debit,Credit,Balance,Transaction Type
77
- def detect_platform(csv_lines)
78
- return :bankwest if csv_lines.first.start_with?('BSB Number,Account Number,Transaction Date,Narration,Cheque Number,Debit,Credit,Balance,Transaction Type')
79
- return :bankwest2 if csv_lines.first.start_with?('Account Name,BSB / Account Number,Transaction Date,Narration,Cheque Number,Debit,Credit,Balance,Transaction Type')
80
-
81
- puts "Unknown platform detected. CSV columns are: #{csv_lines.first.strip}"
82
- raise Appydave::Tools::Error, 'Unknown platform'
83
- end
84
- end
85
- end
86
- end
87
- end
88
- end
@@ -1,91 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Appydave
4
- module Tools
5
- module BankReconciliation
6
- module Models
7
- # Unified transaction model for raw and reconciled data
8
- class Transaction
9
- attr_accessor :bsb_number,
10
- :account_number,
11
- :transaction_date,
12
- :narration,
13
- :cheque_number,
14
- :debit,
15
- :credit,
16
- :balance,
17
- :transaction_type,
18
- :platform,
19
- :coa_code,
20
- :coa_match_type,
21
- :account_name
22
-
23
- def initialize(bsb_number: nil,
24
- account_number: nil,
25
- transaction_date: nil,
26
- narration: nil,
27
- cheque_number: nil,
28
- debit: nil,
29
- credit: nil,
30
- balance: nil,
31
- transaction_type: nil,
32
- platform: nil,
33
- coa_code: nil,
34
- coa_match_type: nil,
35
- account_name: nil)
36
- @bsb_number = bsb_number&.strip
37
- @account_number = account_number&.strip
38
- @transaction_date = transaction_date&.strip
39
- @transaction_date = Date.strptime(@transaction_date, '%d/%m/%Y')
40
- @narration = narration&.gsub(/\s{2,}/, ' ')&.strip
41
- @cheque_number = cheque_number&.strip
42
- @debit = debit&.strip
43
- @credit = credit&.strip
44
- @balance = balance&.strip
45
- @transaction_type = transaction_type&.strip
46
- @platform = platform
47
- @coa_code = coa_code
48
- @coa_match_type = coa_match_type
49
- @account_name = account_name
50
- end
51
-
52
- def self.csv_headers
53
- %i[
54
- bsb_number
55
- account_number
56
- transaction_date
57
- narration
58
- cheque_number
59
- debit
60
- credit
61
- balance
62
- transaction_type
63
- platform
64
- coa_code
65
- coa_match_type
66
- account_name
67
- ]
68
- end
69
-
70
- def to_csv_row
71
- [
72
- @bsb_number,
73
- @account_number,
74
- @transaction_date,
75
- @narration,
76
- @cheque_number,
77
- @debit,
78
- @credit,
79
- @balance,
80
- @transaction_type,
81
- @platform,
82
- @coa_code,
83
- @coa_match_type,
84
- @account_name
85
- ]
86
- end
87
- end
88
- end
89
- end
90
- end
91
- end
@@ -1,97 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Appydave
4
- module Tools
5
- module Configuration
6
- module Models
7
- # Bank reconciliation configuration
8
- class BankReconciliationConfig < ConfigBase
9
- # def
10
- # Retrieve all bank accounts
11
- def bank_accounts
12
- data['bank_accounts'].map do |account|
13
- BankAccount.new(account)
14
- end
15
- end
16
-
17
- def chart_of_accounts
18
- data['chart_of_accounts'].map do |entry|
19
- ChartOfAccount.new(entry)
20
- end
21
- end
22
-
23
- def get_bank_account(account_number, bsb = nil)
24
- account_data = data['bank_accounts'].find do |account|
25
- account['account_number'] == account_number && (account['bsb'].nil? || account['bsb'] == bsb)
26
- end
27
-
28
- BankAccount.new(account_data) if account_data
29
- end
30
-
31
- # Retrieve a chart of account entry by code
32
- def get_chart_of_account(code)
33
- entry_data = data['chart_of_accounts'].find { |entry| entry['code'] == code }
34
- ChartOfAccount.new(entry_data) if entry_data
35
- end
36
-
37
- def print
38
- log.subheading 'Bank Reconciliation - Accounts'
39
-
40
- tp bank_accounts, :account_number, :bsb, :name, :bank
41
-
42
- log.subheading 'Bank Reconciliation - Chart of Accounts'
43
-
44
- tp chart_of_accounts, :code, :narration
45
- end
46
-
47
- private
48
-
49
- def default_data
50
- {
51
- 'bank_accounts' => [],
52
- 'chart_of_accounts' => []
53
- }
54
- end
55
-
56
- # Inner class to represent a bank account
57
- class BankAccount
58
- attr_accessor :account_number, :bsb, :name, :platform
59
-
60
- def initialize(data)
61
- @account_number = data['account_number']
62
- @bsb = data['bsb']
63
- @name = data['name']
64
- @platform = data['platform']
65
- end
66
-
67
- def to_h
68
- {
69
- 'account_number' => @account_number,
70
- 'bsb' => @bsb,
71
- 'name' => @name,
72
- 'platform' => @platform
73
- }
74
- end
75
- end
76
-
77
- # Inner class to represent a chart of account entry
78
- class ChartOfAccount
79
- attr_accessor :code, :narration
80
-
81
- def initialize(data)
82
- @code = data['code']
83
- @narration = data['narration']
84
- end
85
-
86
- def to_h
87
- {
88
- 'code' => @code,
89
- 'narration' => @narration
90
- }
91
- end
92
- end
93
- end
94
- end
95
- end
96
- end
97
- end