appydave-tools 0.10.2 → 0.10.4

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 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