ascii_invoicer 2.5.5
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/bin/ascii +722 -0
- data/latex/ascii-brief.cls +425 -0
- data/latex/ascii-brief.sty +46 -0
- data/lib/ascii_invoicer.rb +17 -0
- data/lib/ascii_invoicer/InvoiceProject.rb +356 -0
- data/lib/ascii_invoicer/ascii_logger.rb +64 -0
- data/lib/ascii_invoicer/filters.rb +129 -0
- data/lib/ascii_invoicer/generators.rb +209 -0
- data/lib/ascii_invoicer/hash_transformer.rb +23 -0
- data/lib/ascii_invoicer/mixins.rb +268 -0
- data/lib/ascii_invoicer/projectFileReader.rb +106 -0
- data/lib/ascii_invoicer/rfc5322_regex.rb +40 -0
- data/lib/ascii_invoicer/settings_manager.rb +62 -0
- data/lib/ascii_invoicer/texwriter.rb +105 -0
- data/lib/ascii_invoicer/tweaks.rb +25 -0
- data/lib/ascii_invoicer/version.rb +3 -0
- data/repl/ascii +2 -0
- data/settings/default-settings.yml +76 -0
- data/settings/settings_template.yml +54 -0
- data/templates/default.yml.erb +74 -0
- data/templates/document.tex.erb +87 -0
- metadata +297 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 186d774a2d826b6b83265d7597ebb7009a321d4f
|
4
|
+
data.tar.gz: f94639520acbbcee90c511f7539442dd7f7602f6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4e3d3887e9432fde377decb43b2a2e44383ee73ea04cbe0b75069cb5623a2f095ab95388f6633a676bba7e057f2c64bc63ca1c92f9dd4b3674bbe5aa6d7f49b3
|
7
|
+
data.tar.gz: 9865ad5aea22a6e4b8e6f42ffa73f571ae0410014da6c3286646409d55e415aeb8f3b8b81dca227fa9dc67287d8627c6e7e13a510a51d316739664b3316a0818
|
data/bin/ascii
ADDED
@@ -0,0 +1,722 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'pp'
|
4
|
+
require 'csv'
|
5
|
+
require 'yaml'
|
6
|
+
require 'thor'
|
7
|
+
require 'euro'
|
8
|
+
require 'paint'
|
9
|
+
require 'luigi'
|
10
|
+
require 'logger'
|
11
|
+
require 'textboxes'
|
12
|
+
require 'hash-graft'
|
13
|
+
|
14
|
+
#finding myself
|
15
|
+
$SCRIPT_PATH = File.split(File.expand_path(__FILE__))[0]
|
16
|
+
$GEM_PATH = File.split($SCRIPT_PATH)[0]
|
17
|
+
|
18
|
+
#require my libraries
|
19
|
+
require "#{$GEM_PATH}/lib/ascii_invoicer"
|
20
|
+
|
21
|
+
# initialize settings
|
22
|
+
settingsmanager = SettingsManager.new({
|
23
|
+
:homedir_path => File.join(Dir.home, ".ascii-invoicer.yml"),
|
24
|
+
:template_path => File.join($GEM_PATH, "/settings/settings_template.yml"),
|
25
|
+
:default_path => File.join($GEM_PATH, "/settings/default-settings.yml")
|
26
|
+
})
|
27
|
+
$SETTINGS = settingsmanager.settings
|
28
|
+
|
29
|
+
#initialize global logger
|
30
|
+
$logger = AsciiLogger.new "Ascii-Invoicer", $SETTINGS.log_file
|
31
|
+
|
32
|
+
## path to the source code
|
33
|
+
$SETTINGS.script_path = $SCRIPT_PATH
|
34
|
+
$SETTINGS.gem_path = $GEM_PATH
|
35
|
+
|
36
|
+
## Version of the software
|
37
|
+
$SETTINGS.version = $VERSION = AsciiInvoicer::VERSION
|
38
|
+
|
39
|
+
## path to the project File, here we expand the "~"
|
40
|
+
$SETTINGS.path = File.expand_path $SETTINGS.path
|
41
|
+
|
42
|
+
|
43
|
+
## "security"
|
44
|
+
#error "settings:editor is an elaborate string: \"#{$SETTINGS.editor}\"!\nDANGEROUS!" if $SETTINGS.editor.include? " "
|
45
|
+
$logger.error "settings:latex is an elaborate string: \"#{$SETTINGS.latex}\"!\nDANGEROUS!" if $SETTINGS.latex.include? " "
|
46
|
+
$logger.error "settings:output_path is an elaborate string: \"#{$SETTINGS.output_path}\"!\nDANGEROUS!" if $SETTINGS.output_path.include? " "
|
47
|
+
|
48
|
+
|
49
|
+
## bootstraping the plumber, first run creates all folders
|
50
|
+
unless File.exists? $SETTINGS.path
|
51
|
+
$logger.fatal "path #{$SETTINGS.path} does not exists"
|
52
|
+
exit
|
53
|
+
end
|
54
|
+
$PLUMBER = Luigi.new $SETTINGS, InvoiceProject
|
55
|
+
$PLUMBER.create_dir :storage unless $PLUMBER.check_dir :storage
|
56
|
+
$PLUMBER.create_dir :working unless $PLUMBER.check_dir :working
|
57
|
+
$PLUMBER.create_dir :archive unless $PLUMBER.check_dir :archive
|
58
|
+
$PLUMBER.create_dir :templates unless $PLUMBER.check_dir :templates
|
59
|
+
$logger.error "template not found!\n#{$PLUMBER.dirs[:templates]}" unless $PLUMBER.check_dir :templates
|
60
|
+
|
61
|
+
$SETTINGS.plumber_dirs = $PLUMBER.dirs
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
## here coms thor
|
66
|
+
class Commander < Thor
|
67
|
+
include Thor::Actions
|
68
|
+
include AsciiInvoicer
|
69
|
+
include AsciiMixins
|
70
|
+
|
71
|
+
|
72
|
+
package_name "ascii invoicer"
|
73
|
+
#argument :first, :type => :numeric
|
74
|
+
map "-l" => :list
|
75
|
+
map "l" => :list
|
76
|
+
map "o" => :offer
|
77
|
+
map "ls" => :list
|
78
|
+
map "dir" => :list
|
79
|
+
map "show" => :display
|
80
|
+
map "-d" => :display
|
81
|
+
map "close" => :archive
|
82
|
+
map "-i" => :invoice
|
83
|
+
map "-o" => :offer
|
84
|
+
map "-V" => :version
|
85
|
+
map "--version" => :version
|
86
|
+
map "config" => :settings
|
87
|
+
map "history" => :log
|
88
|
+
#map "-e" => :edit #depricated
|
89
|
+
|
90
|
+
class_option :verbose, :aliases=> "-v", :type => :boolean, :default => $SETTINGS.verbose, :desc => "Change default in #{$SETTINGS.settings_homedir_path}"
|
91
|
+
#class_option "keep-log", :aliases=> "-k", :type => :boolean
|
92
|
+
|
93
|
+
no_commands{
|
94
|
+
def open_projects(names, options)
|
95
|
+
$SETTINGS.verbose = true if options[:verbose]
|
96
|
+
if options[:file]
|
97
|
+
return [InvoiceProject.new({path => options[:file], settings => $SETTINGS})]
|
98
|
+
|
99
|
+
else
|
100
|
+
if options[:all]
|
101
|
+
available_projects = $PLUMBER.open_projects_all()
|
102
|
+
elsif options[:archive]
|
103
|
+
available_projects = $PLUMBER.open_projects_archive(options[:archive])
|
104
|
+
else
|
105
|
+
available_projects = $PLUMBER.open_projects_working()
|
106
|
+
end
|
107
|
+
|
108
|
+
projects = names.map{|name|
|
109
|
+
if name.class == String and name =~ /^\d*$/
|
110
|
+
available_projects[ (name.to_i - 1) ]
|
111
|
+
else
|
112
|
+
(available_projects.lookup_by_name name) + (available_projects.lookup_by_index name)
|
113
|
+
end
|
114
|
+
}.flatten.uniq
|
115
|
+
if projects.count < 1
|
116
|
+
$logger.error "Nothing found, containing #{names}."
|
117
|
+
#exit
|
118
|
+
end
|
119
|
+
return projects.select{|p|p}
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def render_projects(projects, type, options)
|
125
|
+
projects.each{|project|
|
126
|
+
if project.validate type or options[:force]
|
127
|
+
puts "% RENDERING"
|
128
|
+
project.create_tex(type, options[:stdout]) unless project.nil?
|
129
|
+
else
|
130
|
+
$logger.error "Cannot create an #{type.to_s} from \"#{project.name}\". No valid #{type}: #{project.blockers(type).join ','})"
|
131
|
+
end
|
132
|
+
}
|
133
|
+
end
|
134
|
+
}
|
135
|
+
|
136
|
+
|
137
|
+
desc "new NAME", "Creating a new project"
|
138
|
+
method_option :dont_edit, :type=>:boolean, :aliases => "-d",
|
139
|
+
:lazy_default=> true, :required => false, :desc => "do not edit a new file after creation"
|
140
|
+
method_option :template, :type=>:string, :aliases => "-t",
|
141
|
+
:default => "default", :required => false, :desc => "specify a template"
|
142
|
+
method_option :editor, :type => :string, :aliases => '-e',
|
143
|
+
:default => $SETTINGS.editor, :desc => "specify which editor to use, see #{$SETTINGS.settings_homedir_path}"
|
144
|
+
def new(name)
|
145
|
+
template = options[:template].to_sym
|
146
|
+
unless $PLUMBER.templates.keys.include? template
|
147
|
+
$logger.fatal "There is not such template \"#{template}\" "
|
148
|
+
exit
|
149
|
+
end
|
150
|
+
|
151
|
+
project = $PLUMBER.new_project name, template
|
152
|
+
if project
|
153
|
+
puts project.path
|
154
|
+
puts "creating a new project name #{name}" if project
|
155
|
+
edit_files $PLUMBER.get_project_file_path name unless options[:dont_edit]
|
156
|
+
else
|
157
|
+
puts "was not able to create #{name}"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
desc "edit NAMES", "Edit project"
|
163
|
+
method_option :settings, :type=>:boolean, :aliases => '-s',
|
164
|
+
:lazy_default=> true, :required => false, :desc => "edit settings"
|
165
|
+
method_option :archive,
|
166
|
+
:type=>:numeric, :aliases => "-a", :default => nil,
|
167
|
+
:lazy_default=> Date.today.year, :required => false, :desc => "Open File from archive YEAR"
|
168
|
+
method_option :editor, :type => :string, :aliases => '-e',
|
169
|
+
:default => $SETTINGS.editor, :desc => "specify which editor to use, see #{$SETTINGS.settings_homedir_path}"
|
170
|
+
method_option :template,
|
171
|
+
:type=>:string, :aliases => "-t", :default => nil,
|
172
|
+
:required => false, :desc => "Edit a template file"
|
173
|
+
|
174
|
+
def edit( *names )
|
175
|
+
if options[:settings]
|
176
|
+
paths = [ $SETTINGS.settings_homedir_path ]
|
177
|
+
elsif options[:template]
|
178
|
+
path = $PLUMBER.templates[ options[:template].to_sym ]
|
179
|
+
if not path.nil? and File.exists? path
|
180
|
+
paths = [path]
|
181
|
+
else
|
182
|
+
puts "no such template"
|
183
|
+
exit 1
|
184
|
+
end
|
185
|
+
else
|
186
|
+
projects = open_projects names, options
|
187
|
+
paths= projects.map{ |project| project.path }
|
188
|
+
|
189
|
+
if options[:archive]
|
190
|
+
map = $PLUMBER.map_project_files_archive(options[:archive])
|
191
|
+
else
|
192
|
+
map = $PLUMBER.map_project_files_working()
|
193
|
+
end
|
194
|
+
map.each{|k,v|
|
195
|
+
names.each{|name|
|
196
|
+
if k.downcase.include? name.downcase
|
197
|
+
paths += [v]
|
198
|
+
end
|
199
|
+
}
|
200
|
+
}
|
201
|
+
paths.uniq!
|
202
|
+
|
203
|
+
#pp paths
|
204
|
+
$logger.info "opening #{paths}", :stdo
|
205
|
+
end
|
206
|
+
|
207
|
+
if paths.size > 0
|
208
|
+
edit_files paths, options[:editor]
|
209
|
+
else
|
210
|
+
puts "nothing found (#{names})"
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
|
215
|
+
|
216
|
+
desc "list", "List current Projects"
|
217
|
+
method_option :archive,
|
218
|
+
:type=>:numeric, :aliases => "-a",
|
219
|
+
:lazy_default=> Date.today.year, :required => false, :desc => "list archived projects"
|
220
|
+
method_option :archives,
|
221
|
+
:type=>:boolean,
|
222
|
+
:lazy_default=> true, :required => false, :desc => "lists all years for which there are archives"
|
223
|
+
method_option :all, :type=>:boolean,
|
224
|
+
:lazy_default=> true, :required => false, :desc => "lists all projects, ever"
|
225
|
+
method_option :templates, :type=>:boolean,
|
226
|
+
:lazy_default=> true, :required => false, :desc => "lists all templates"
|
227
|
+
method_option :paths, :type=>:boolean, :aliases => '-p',
|
228
|
+
:lazy_default=> true, :required => false, :desc => "list paths to .yml files"
|
229
|
+
|
230
|
+
|
231
|
+
method_option :csv, :type=>:boolean,
|
232
|
+
:lazy_default=> true, :required => false, :desc => "output as csv"
|
233
|
+
method_option :sort, :type=>:string,
|
234
|
+
:required => false, :desc => "sort by [date | index | name | manager]",
|
235
|
+
:enum => ['date' , 'index', 'name', 'manager']
|
236
|
+
|
237
|
+
method_option :final, :type=>:boolean,
|
238
|
+
:lazy_default=> true, :required => false, :desc => "list shows final sum"
|
239
|
+
|
240
|
+
method_option :caterers, :type=>:boolean,
|
241
|
+
:lazy_default=> true, :required => false, :desc => "list caterers"
|
242
|
+
|
243
|
+
method_option :blockers, :type=>:boolean, :aliases => '-b',
|
244
|
+
:lazy_default=> true, :required => false, :desc => "list blockers"
|
245
|
+
|
246
|
+
method_option :errors, :type=>:boolean, :aliases => '-e',
|
247
|
+
:lazy_default=> true, :required => false, :desc => "list errors"
|
248
|
+
|
249
|
+
method_option :simple, :type=>:boolean, :aliases => '-s',
|
250
|
+
:lazy_default=> true, :required => false, :desc => "overrides the verbose setting"
|
251
|
+
|
252
|
+
method_option :colors, :type=>:boolean, :aliases => '-c', :default => $SETTINGS.colors,
|
253
|
+
:lazy_default=> true, :required => false, :desc => "overrides the colors setting"
|
254
|
+
|
255
|
+
method_option :filter, :type=>:hash, :aliases => '-f',
|
256
|
+
:required => false, :desc => "filter by manager, caterer etc (experimental)"
|
257
|
+
|
258
|
+
method_option :no_colors, :type=>:boolean, :aliases => '-n',
|
259
|
+
:lazy_default=> true, :required => false, :desc => "overrides the colors setting"
|
260
|
+
|
261
|
+
method_option :details, :type=>:array, :aliases => '-d',
|
262
|
+
:required => false, :desc => "adds details"
|
263
|
+
|
264
|
+
method_option :edit, :type=>:array,
|
265
|
+
:required => false, :desc => "open all listed files for edit"
|
266
|
+
|
267
|
+
def list
|
268
|
+
hash = {}
|
269
|
+
hash[:verbose] = (options[:verbose] and !options[:simple])
|
270
|
+
hash[:colors] = (options[:colors] and !options[:no_colors])
|
271
|
+
hash[:errors] = options[:errors]
|
272
|
+
hash[:blockers] = options[:blockers]
|
273
|
+
hash[:caterers] = options[:caterers]
|
274
|
+
hash[:details] = options[:details]
|
275
|
+
|
276
|
+
if options[:paths]
|
277
|
+
map = $PLUMBER.map_project_files_working()
|
278
|
+
map = $PLUMBER.map_project_files_archive(options[:archive]) if options[:archive]
|
279
|
+
table = Textboxes.new
|
280
|
+
map.each{|name, path| table.add_row [name, path] }
|
281
|
+
puts table
|
282
|
+
exit
|
283
|
+
end
|
284
|
+
|
285
|
+
if not options[:sort].nil? and [:date, :name, :index].include? options[:sort].to_sym
|
286
|
+
sort = options[:sort].to_sym
|
287
|
+
elsif $SETTINGS.list_sort?
|
288
|
+
sort = $SETTINGS.list_sort.to_sym
|
289
|
+
else
|
290
|
+
sort = :date
|
291
|
+
end
|
292
|
+
|
293
|
+
if options[:all]
|
294
|
+
projects = $PLUMBER.open_projects_all() #TODO
|
295
|
+
elsif options[:archives]
|
296
|
+
puts $PLUMBER.map_archive_years.keys
|
297
|
+
return
|
298
|
+
elsif options[:templates]
|
299
|
+
puts $PLUMBER.templates.keys
|
300
|
+
return
|
301
|
+
elsif options[:archive]
|
302
|
+
projects = $PLUMBER.open_projects_archive(options[:archive], sort)
|
303
|
+
else
|
304
|
+
projects = $PLUMBER.open_projects_working(sort)
|
305
|
+
end
|
306
|
+
|
307
|
+
if options[:filter]
|
308
|
+
projects = $PLUMBER.filter_by projects, options[:filter]
|
309
|
+
end
|
310
|
+
|
311
|
+
if options[:csv]
|
312
|
+
projects = $PLUMBER.sort_projects(projects, :index)
|
313
|
+
print_project_list_csv projects
|
314
|
+
elsif options[:yaml]
|
315
|
+
print_project_list_yaml projects
|
316
|
+
else
|
317
|
+
print_project_list(projects, hash)
|
318
|
+
end
|
319
|
+
|
320
|
+
if options[:edit]
|
321
|
+
all_paths= projects.map { |project| project.path }
|
322
|
+
|
323
|
+
paths = options[:edit].map{|index| all_paths[index.to_i-1] }
|
324
|
+
puts paths
|
325
|
+
|
326
|
+
if paths.size > 0
|
327
|
+
edit_files paths, options[:editor]
|
328
|
+
else
|
329
|
+
puts "nothing found (#{names})"
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
desc "templates", "List or add templates"
|
335
|
+
method_option :add, :type=>:boolean,
|
336
|
+
:lazy_default=> true, :required => false, :desc => "Adds template changes to index just like ascii add does to projects."
|
337
|
+
|
338
|
+
def templates
|
339
|
+
if options[:add]
|
340
|
+
path = $PLUMBER.dirs[:templates]
|
341
|
+
$PLUMBER.git_update_path(path) if $PLUMBER.open_git()
|
342
|
+
else
|
343
|
+
puts $PLUMBER.templates.keys
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
desc "csv", "Equal to: ascii list --all --csv --sort=index --filter event/date:#{Date.today.year}"
|
348
|
+
method_option :year,
|
349
|
+
:type=>:numeric, :aliases => "-y",
|
350
|
+
:default=> Date.today.year, :required => false, :desc => "Year to export"
|
351
|
+
def csv
|
352
|
+
invoke :list, [], csv:true, all:true, sort:"index", filter:{"event/date"=>options[:year].to_s}# where is this documented
|
353
|
+
end
|
354
|
+
|
355
|
+
desc "search QUERY", "Search everything, only one query currently"
|
356
|
+
def search *queries
|
357
|
+
queries.map!{|query|
|
358
|
+
path, term = query.split ?:
|
359
|
+
{path => term}
|
360
|
+
}
|
361
|
+
puts "#{queries[0].keys[0]}: #{queries[0].values[0]}"
|
362
|
+
invoke :list, [], all:true, filter:queries[0]#, details:queries[0].keys
|
363
|
+
end
|
364
|
+
|
365
|
+
desc "whoami", "Invoke settings --show manager_name"
|
366
|
+
def whoami
|
367
|
+
invoke :settings, [], show:"manager_name"
|
368
|
+
end
|
369
|
+
|
370
|
+
desc "calendar", "Create a calendar file from all caterings named \"invoicer.ics\""
|
371
|
+
def calendar
|
372
|
+
projects = $PLUMBER.open_projects_all()
|
373
|
+
valid = true
|
374
|
+
projects.each{|project|
|
375
|
+
unless project.validate(:calendar)
|
376
|
+
valid = false
|
377
|
+
$logger.error "error in event/date in \"#{project.name}\""
|
378
|
+
end
|
379
|
+
|
380
|
+
}
|
381
|
+
unless valid
|
382
|
+
$logger.error "Can't create Calendar."
|
383
|
+
exit
|
384
|
+
end
|
385
|
+
create_cal_file $PLUMBER.open_projects_all()
|
386
|
+
end
|
387
|
+
|
388
|
+
|
389
|
+
|
390
|
+
desc "archive NAME", "Move project to archive"
|
391
|
+
method_option :force,:type=>:boolean,
|
392
|
+
:lazy_default=> true, :required => false,
|
393
|
+
:desc => "Force archiving projects that are invalid."
|
394
|
+
def archive( *names )
|
395
|
+
projects = open_projects names, options
|
396
|
+
project = projects[0]
|
397
|
+
return false unless project
|
398
|
+
|
399
|
+
year = project.date.year
|
400
|
+
prefix = project.data[:invoice][:number]
|
401
|
+
prefix ||= ""
|
402
|
+
prefix += "canceled" if project.data[:canceled]
|
403
|
+
|
404
|
+
puts options
|
405
|
+
|
406
|
+
unless project.validate(:archive) or options[:force] or project.data[:canceled]
|
407
|
+
$logger.error "\"#{project.name}\" contains errors\n(#{project.errors.join(',')})"
|
408
|
+
else
|
409
|
+
new_path = $PLUMBER.archive_project project, Date.today.year, prefix
|
410
|
+
puts new_path
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
414
|
+
desc "reopen YEAR NAME", "reopen an archived project"
|
415
|
+
def reopen(year, name)
|
416
|
+
projects = $PLUMBER.open_projects_archive year
|
417
|
+
project = projects.lookup_by_name name
|
418
|
+
if project.count > 1
|
419
|
+
$logger.error "Ambigous results"
|
420
|
+
puts project
|
421
|
+
exit
|
422
|
+
else
|
423
|
+
project = project[0]
|
424
|
+
puts project.path
|
425
|
+
end
|
426
|
+
|
427
|
+
#unless $PLUMBER.unarchive_project project, year
|
428
|
+
# $logger.error "Can't unarchive #{name}, checks names of current projects for duplicates!"
|
429
|
+
#end
|
430
|
+
end
|
431
|
+
|
432
|
+
|
433
|
+
|
434
|
+
|
435
|
+
|
436
|
+
|
437
|
+
desc "display NAMES", "Shows information about a project in different ways"
|
438
|
+
method_option :archive,
|
439
|
+
:type=>:numeric, :aliases => "-a",
|
440
|
+
:default => nil,
|
441
|
+
:lazy_default=> Date.today.year,
|
442
|
+
:required => false,
|
443
|
+
:desc => "Select File from archive YEAR"
|
444
|
+
method_option :all, :type=>:boolean,
|
445
|
+
:default=> false, :lazy_default=> true, :required => false,
|
446
|
+
:desc => "Select File from any archive and current working directory "
|
447
|
+
method_option :name, :type=>:boolean,
|
448
|
+
:default=> false, :lazy_default=> true, :required => false,
|
449
|
+
:desc => "Display only the name"
|
450
|
+
method_option :offer, :type=>:boolean,
|
451
|
+
:default=> false, :lazy_default=> true, :required => false,
|
452
|
+
:desc => "Display the offer"
|
453
|
+
method_option :invoice, :type=>:boolean,
|
454
|
+
:default=> false, :lazy_default=> true, :required => false,
|
455
|
+
:desc => "Display the invoice"
|
456
|
+
method_option :csv, :type=>:boolean, :aliases => '-c',
|
457
|
+
:lazy_default=> true, :required => false, :desc => "show as csv"
|
458
|
+
method_option :errors, :type=>:boolean, :aliases => '-e',
|
459
|
+
:lazy_default=> true, :required => false, :desc => "show errors in footer"
|
460
|
+
method_option :products, :type=>:boolean,
|
461
|
+
:default=> false, :lazy_default=> true, :required => false,
|
462
|
+
:desc => "Display only the products for the --offer or --invoice"
|
463
|
+
method_option :caterers, :type=>:boolean,
|
464
|
+
:default=> false, :lazy_default=> true, :required => false,
|
465
|
+
:desc => "Display Caterers"
|
466
|
+
method_option :raw,:type=>:boolean,
|
467
|
+
:default=> false, :lazy_default=> true, :required => false,
|
468
|
+
:desc => ""
|
469
|
+
method_option :costs,:type=>:boolean,
|
470
|
+
:default=> false, :lazy_default=> true, :required => false,
|
471
|
+
:desc => ""
|
472
|
+
method_option :detail, :type=>:string, :banner => "key", :aliases =>"-d",
|
473
|
+
:default => nil, :lazy_default=> "", :required => false,
|
474
|
+
:desc => "output key or all with pp"
|
475
|
+
method_option :pp, :type=>:string, :banner => "key",
|
476
|
+
:default => nil, :lazy_default=> "", :required => false,
|
477
|
+
:desc => "output key or all with pp"
|
478
|
+
# method_option :yaml, :type=>:string, :banner => "key",
|
479
|
+
# :default => nil, :lazy_default=> "", :required => false,
|
480
|
+
# :desc => "output key or all as yaml"
|
481
|
+
method_option :cal, :type=>:boolean,
|
482
|
+
:default => nil, :lazy_default=> "", :required => false,
|
483
|
+
:desc => "output key or all as ical event[s]"
|
484
|
+
def display(*names)
|
485
|
+
projects = open_projects names, options
|
486
|
+
|
487
|
+
projects.each{ |project|
|
488
|
+
$logger.error("No project found!") if project.nil?
|
489
|
+
unless options[:cal] or options[:yaml] or options[:costs] or options[:caterers] or options[:invoice] or options[:offer] or options[:products]
|
490
|
+
fallback= true
|
491
|
+
end
|
492
|
+
|
493
|
+
if not options[:yaml].nil?
|
494
|
+
if options[:yaml] == ''
|
495
|
+
puts project.data.to_yaml
|
496
|
+
else
|
497
|
+
puts project.data.get_path(options[:yaml]).to_yaml
|
498
|
+
end
|
499
|
+
elsif options[:name]
|
500
|
+
puts project.name
|
501
|
+
elsif options[:csv]
|
502
|
+
display_products_csv project
|
503
|
+
elsif options[:raw]
|
504
|
+
raw = project.raw_data
|
505
|
+
raw.delete "cataloge"
|
506
|
+
puts raw.to_yaml
|
507
|
+
elsif not options[:detail].nil?
|
508
|
+
if options[:detail] == ''
|
509
|
+
puts project.data
|
510
|
+
else
|
511
|
+
puts project.data.get_path(options[:detail])
|
512
|
+
end
|
513
|
+
elsif not options[:pp].nil?
|
514
|
+
if options[:pp] == ''
|
515
|
+
pp project.data
|
516
|
+
else
|
517
|
+
pp project.data.get_path(options[:pp])
|
518
|
+
end
|
519
|
+
else
|
520
|
+
if options[:products]
|
521
|
+
puts display_products(project, :offer )
|
522
|
+
puts display_products(project, :invoice) if options[:invoice]
|
523
|
+
else
|
524
|
+
puts display_all(project, :offer , options[:errors]) if options[:offer ]
|
525
|
+
puts display_all(project, :invoice, options[:errors]) if options[:invoice] or fallback
|
526
|
+
end
|
527
|
+
if options[:cal]
|
528
|
+
project.data[:event][:calendaritems].each{|cal|
|
529
|
+
puts cal.to_ical
|
530
|
+
}
|
531
|
+
end
|
532
|
+
if options[:caterers]
|
533
|
+
print "#{project.name}:".ljust(35) if names.length > 1
|
534
|
+
if project.data[:hours][:caterers]
|
535
|
+
puts project.data[:hours][:caterers].map{|name, hours| "#{name} (#{hours})"}.join(", ")
|
536
|
+
else
|
537
|
+
puts "Caterers is empty"
|
538
|
+
end
|
539
|
+
end
|
540
|
+
end
|
541
|
+
}
|
542
|
+
end
|
543
|
+
|
544
|
+
desc "offer NAMES", "Create an offer from project"
|
545
|
+
method_option :archive,
|
546
|
+
:type=>:numeric, :aliases => "-a",
|
547
|
+
:default => nil,
|
548
|
+
:lazy_default=> Date.today.year,
|
549
|
+
:required => false,
|
550
|
+
:desc => "Open File from archive YEAR"
|
551
|
+
method_option :stdout,
|
552
|
+
:type=>:numeric, :aliases => "-s",
|
553
|
+
:lazy_default=> true,
|
554
|
+
:required => false,
|
555
|
+
:desc => "print tex to stdout"
|
556
|
+
method_option :force,:type=>:boolean,
|
557
|
+
:lazy_default=> true, :required => false,
|
558
|
+
:desc => "Ignore validator."
|
559
|
+
def offer(*names)
|
560
|
+
projects = open_projects names, options
|
561
|
+
render_projects projects, :offer, options
|
562
|
+
end
|
563
|
+
|
564
|
+
desc "invoice NAMES", "Create an invoice from project"
|
565
|
+
method_option :archive,
|
566
|
+
:type=>:numeric, :aliases => "-a",
|
567
|
+
:default => nil,
|
568
|
+
:lazy_default=> Date.today.year,
|
569
|
+
:required => false,
|
570
|
+
:desc => "Open File from archive YEAR"
|
571
|
+
method_option :stdout,
|
572
|
+
:type=>:numeric, :aliases => "-s",
|
573
|
+
:lazy_default=> true,
|
574
|
+
:required => false,
|
575
|
+
:desc => "print tex to stdout"
|
576
|
+
method_option :force,:type=>:boolean,
|
577
|
+
:lazy_default=> true, :required => false,
|
578
|
+
:desc => "Ignore validator."
|
579
|
+
def invoice( *names)
|
580
|
+
projects = open_projects names, options
|
581
|
+
render_projects projects, :invoice, options
|
582
|
+
end
|
583
|
+
|
584
|
+
|
585
|
+
|
586
|
+
|
587
|
+
|
588
|
+
|
589
|
+
desc "status", "Git Integration"
|
590
|
+
def status
|
591
|
+
$PLUMBER.git_status() if $PLUMBER.open_git()
|
592
|
+
end
|
593
|
+
|
594
|
+
|
595
|
+
desc "add NAMES", "Git Integration"
|
596
|
+
method_option :template,
|
597
|
+
:type=>:string, :aliases => "-t", :default => nil,
|
598
|
+
:required => false, :desc => "Adds a template file"
|
599
|
+
method_option :archive,
|
600
|
+
:type=>:numeric, :aliases => "-a",
|
601
|
+
:default => nil,
|
602
|
+
:lazy_default=> Date.today.year,
|
603
|
+
:required => false,
|
604
|
+
:desc => "Add File from archive YEAR"
|
605
|
+
|
606
|
+
def add *names
|
607
|
+
if options[:template]
|
608
|
+
path = $PLUMBER.templates[ options[:template].to_sym ]
|
609
|
+
if not path.nil? and File.exists? path
|
610
|
+
$PLUMBER.git_update_path(path) if $PLUMBER.open_git()
|
611
|
+
end
|
612
|
+
end
|
613
|
+
|
614
|
+
projects = open_projects names, options
|
615
|
+
projects.each {|project|
|
616
|
+
path = project.project_folder
|
617
|
+
if not path.nil? and File.exists? path
|
618
|
+
$PLUMBER.git_update_path(path) if $PLUMBER.open_git()
|
619
|
+
end
|
620
|
+
}
|
621
|
+
status()
|
622
|
+
end
|
623
|
+
|
624
|
+
desc "commit", "Git Integration"
|
625
|
+
method_option :message,
|
626
|
+
:type=>:string, :aliases => "-m", :default => nil,
|
627
|
+
:lazy_default=> Date.today.year, :required => true,
|
628
|
+
:desc => "Open File from archive YEAR"
|
629
|
+
def commit
|
630
|
+
$PLUMBER.git_commit(options[:message]) if $PLUMBER.open_git()
|
631
|
+
end
|
632
|
+
|
633
|
+
desc "push", "Git Integration"
|
634
|
+
def push
|
635
|
+
$PLUMBER.git_push() if $PLUMBER.open_git()
|
636
|
+
end
|
637
|
+
|
638
|
+
desc "pull", "Git Integration"
|
639
|
+
def pull
|
640
|
+
$PLUMBER.git_pull() if $PLUMBER.open_git()
|
641
|
+
end
|
642
|
+
|
643
|
+
desc "log", "Git Integration"
|
644
|
+
method_option :count,
|
645
|
+
:type=>:numeric, :aliases => "-c",
|
646
|
+
:default => 30,
|
647
|
+
:lazy_default=> 1000,
|
648
|
+
:required => false,
|
649
|
+
:desc => "Max count of history entries"
|
650
|
+
def log
|
651
|
+
$PLUMBER.git_log(options[:count]) if $PLUMBER.open_git()
|
652
|
+
end
|
653
|
+
|
654
|
+
|
655
|
+
|
656
|
+
|
657
|
+
|
658
|
+
desc "settings", "View settings"
|
659
|
+
method_option :edit,
|
660
|
+
:type=>:boolean, :aliases => "-e",
|
661
|
+
:lazy_default=> false,
|
662
|
+
:required => false,
|
663
|
+
:desc => "edit your settings"
|
664
|
+
method_option :show,
|
665
|
+
:type=>:string, :aliases => "-s",
|
666
|
+
:required => false,
|
667
|
+
:desc => "show a specific settings value"
|
668
|
+
|
669
|
+
def settings
|
670
|
+
|
671
|
+
if options[:edit]
|
672
|
+
edit_files $SETTINGS.settings_homedir_path
|
673
|
+
elsif options[:show]
|
674
|
+
value = $SETTINGS.get_path options[:show]
|
675
|
+
if value.class == Hash or value.class == Array
|
676
|
+
puts value.to_yaml
|
677
|
+
elsif value.class == Hashr
|
678
|
+
puts value.to_hash.to_yaml
|
679
|
+
else
|
680
|
+
puts value
|
681
|
+
end
|
682
|
+
else
|
683
|
+
puts $SETTINGS.to_hash.to_yaml
|
684
|
+
end
|
685
|
+
#pp $SETTINGS
|
686
|
+
end
|
687
|
+
|
688
|
+
desc "path", "Return projects storage path"
|
689
|
+
method_option :templates, :type=>:boolean, :aliases => '-t',
|
690
|
+
:lazy_default=> true, :required => false, :desc => "returns templates path"
|
691
|
+
method_option :output, :type=>:boolean, :aliases => '-o',
|
692
|
+
:lazy_default=> true, :required => false, :desc => "returns output path"
|
693
|
+
method_option :script, :type=>:boolean,
|
694
|
+
:lazy_default=> true, :required => false, :desc => "returns script path"
|
695
|
+
def path
|
696
|
+
if options[:script]
|
697
|
+
puts File.split($GEM_PATH)[0]
|
698
|
+
elsif options[:output]
|
699
|
+
puts File.expand_path File.join $SETTINGS.output_path
|
700
|
+
elsif options[:templates]
|
701
|
+
puts $PLUMBER.dirs[:templates]
|
702
|
+
else
|
703
|
+
puts File.join $SETTINGS.path, $SETTINGS.dirs.storage
|
704
|
+
end
|
705
|
+
end
|
706
|
+
|
707
|
+
desc "output", "Equal to: ascii path --output"
|
708
|
+
def output
|
709
|
+
invoke :path, [], output:true
|
710
|
+
end
|
711
|
+
|
712
|
+
desc "version", "Display version"
|
713
|
+
method_option :changed_files, :type=>:boolean, :aliases => '-c',
|
714
|
+
:lazy_default=> true, :required => false, :desc => "show changed files"
|
715
|
+
method_option :fetch, :type=>:boolean, :aliases => '-f',
|
716
|
+
:lazy_default=> true, :required => false, :desc => "update new code (FETCH ONLY != pull)"
|
717
|
+
def version
|
718
|
+
puts "ascii-invoicer v#{$VERSION}"
|
719
|
+
end
|
720
|
+
end
|
721
|
+
|
722
|
+
Commander.start
|