-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinvoice_processor.rb
More file actions
179 lines (153 loc) Β· 4.53 KB
/
invoice_processor.rb
File metadata and controls
179 lines (153 loc) Β· 4.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#!/usr/bin/env ruby
require_relative 'lib/invoice_processor'
require_relative 'lib/holded_service'
require 'find'
def find_pdf_files(directory)
pdf_files = []
Find.find(directory) do |path|
if File.file?(path) && File.extname(path).downcase == '.pdf'
pdf_files << path
end
end
pdf_files.sort
end
def display_preview(data)
puts "\nExtracted Invoice Data:"
puts "- Invoice Number: #{data[:invoice_number]}"
puts "- Date: #{data[:date]}"
puts "- Vendor: #{data[:vendor_name]}"
puts "- Vendor ID (CIF/NIF): #{data[:vendor_id]}"
puts "- Total Amount: $#{data[:total_amount]}"
puts "- Tax Amount: $#{data[:tax_amount]}"
puts "- Line Items:"
data[:line_items].each do |item|
tax_info = item[:tax_percentage] ? " (Tax: #{item[:tax_percentage]}%)" : ""
puts " * #{item[:description]}: $#{item[:amount]}#{tax_info}"
end
puts
end
def ask_for_confirmation
print "Create expense in Holded? (y/n): "
STDIN.gets.chomp.downcase == 'y'
end
def create_expense_in_holded(data, original_file_path)
holded_service = HoldedService.new
# Create the expense document
result = holded_service.create_expense(data)
# Attach the original file to the document
if result && result['id']
puts "\nπ Attaching original file to document..."
begin
holded_service.attach_file(result['id'], original_file_path)
rescue => e
puts "β οΈ Warning: Failed to attach file: #{e.message}"
end
end
result
rescue => e
puts "β Failed to create expense in Holded: #{e.message}"
nil
end
def process_single_file(file_path)
puts "\n" + "="*60
puts "π Processing: #{file_path}"
puts "="*60
begin
processor = InvoiceProcessor.new([file_path])
data = processor.process_invoice
display_preview(data)
if ask_for_confirmation
puts "Creating expense in Holded..."
result = create_expense_in_holded(data, file_path)
if result
{ status: :ok, file: file_path }
else
{ status: :wrong, file: file_path, error: "Failed to create expense in Holded" }
end
else
puts "Operation cancelled for this file."
{ status: :wrong, file: file_path, error: "Operation cancelled by user" }
end
rescue => e
puts "β Error processing #{file_path}: #{e.message}"
{ status: :wrong, file: file_path, error: e.message }
end
end
def process_directory(directory_path)
pdf_files = find_pdf_files(directory_path)
if pdf_files.empty?
puts "No PDF files found in directory: #{directory_path}"
return
end
puts "π Found #{pdf_files.length} PDF file(s) in: #{directory_path}"
puts "π Files to process:"
pdf_files.each_with_index do |file, index|
puts " #{index + 1}. #{File.basename(file)}"
end
puts
results = []
pdf_files.each_with_index do |file_path, index|
puts "\nπ Processing file #{index + 1} of #{pdf_files.length}"
result = process_single_file(file_path)
results << result
end
puts "\nβ
All files processed!"
# Print summary
puts "\n" + "="*60
puts "π PROCESSING SUMMARY"
puts "="*60
results.each do |result|
file_name = File.basename(result[:file])
if result[:status] == :ok
puts "β
OK - #{file_name}"
else
puts "β WRONG - #{file_name}"
puts " Error: #{result[:error]}" if result[:error]
end
end
# Print totals
ok_count = results.count { |r| r[:status] == :ok }
wrong_count = results.count { |r| r[:status] == :wrong }
puts "\n" + "-"*60
puts "Total files: #{results.length}"
puts "β
Successful: #{ok_count}"
puts "β Failed: #{wrong_count}"
puts "="*60
end
def process_single_file_mode(file_path)
puts "π Processing single file: #{file_path}"
process_single_file(file_path)
end
begin
if ARGV.empty?
puts "Usage: ruby invoice_processor.rb <file_path_or_directory>"
puts " - If directory: processes all PDF files in the directory"
puts " - If file: processes the single PDF file"
exit 1
end
path = ARGV.first
unless File.exist?(path)
puts "Error: Path not found: #{path}"
exit 1
end
if File.directory?(path)
puts "π Processing directory: #{path}"
process_directory(path)
elsif File.file?(path)
if File.extname(path).downcase == '.pdf'
process_single_file_mode(path)
else
puts "Error: File is not a PDF: #{path}"
exit 1
end
else
puts "Error: Path is neither a file nor directory: #{path}"
exit 1
end
rescue ArgumentError => e
puts "Error: #{e.message}"
exit 1
rescue => e
puts "Unexpected error: #{e.message}"
exit 1
end