class InvoiceProject

TODO requirements and validity
TODO open, YAML::parse, [transform, ] read_all, generate, validate
TODO statemachine!!

www.zenspider.com/Languages/Ruby/QuickRef.html

Attributes

defaults[RW]
errors[R]
project_folder[R]
project_path[R]
raw_data[RW]
settings[R]
status[R]

Public Class Methods

new(hash) click to toggle source

def initialize(project_path = nil, template_path = nil, settings = $settings, name = nil)

# File lib/ascii_invoicer/InvoiceProject.rb, line 61
def initialize(hash)
  @path          = hash[:path]
  @settings      = hash[:settings]
  @template_path = hash[:template_path]
  @data          = hash[:data]
  @data        ||= {}

  @name          = File.basename @path, '.yml'
  @settings      = hash[:settings]
  @status        = :ok
  @errors        = []
  @defaults      = {}
  @defaults      = @settings[:defaults] unless @settings[:defaults].nil?

  @defaults['format'] = '1.0.0'
  @logger             = $logger

  unless @template_path.nil?
    create @template_path
  end

  open(@path) unless @path.nil?
end

Public Instance Methods

blockers(choice = :invoice) click to toggle source
# File lib/ascii_invoicer/InvoiceProject.rb, line 244
def blockers choice = :invoice
  inval = {} # invalidators
  inval[ :minimal ] = [:client_last_name, :manager, :products, :event_dates]
  inval[ :offer   ] = inval[:minimal] + [:caterers, :offer_number ]
  inval[ :invoice ] = inval[:offer]   + [:invoice_number, :invoice_date]
  inval[ :payed   ] = inval[:invoice] + [:invoice_payed]
  inval[ :archive ] = inval[:payed]
  inval[ :calendar] = inval[:minimal]
  inval[choice] & @errors
end
data(key = nil) click to toggle source

getters for path_through_document getting path['document']

# File lib/ascii_invoicer/InvoiceProject.rb, line 266
def data key = nil
  return @data if key.nil?
  return @data.get_path key
end
date() click to toggle source

returns the date (LuigiProject Interface)

# File lib/ascii_invoicer/InvoiceProject.rb, line 152
def date
  return @data[:event][:date] if @data[:event][:date]
  return @data[:created]      if @data[:created]
  return Date.parse "01.01.0000"
end
export_filename(choice, ext="") click to toggle source
# File lib/ascii_invoicer/InvoiceProject.rb, line 271
def export_filename choice, ext=""
  offer_number   = data 'offer/number'
  invoice_number = data 'invoice/number'
  name = data 'name'
  date = data('event/date').strftime "%Y-%m-%d"

  ext.prepend '.' unless ext.length > 0 and ext.start_with? '.'

  if choice == :invoice
    "#{invoice_number} #{name} #{date}#{ext}"
  elsif choice == :offer
    "#{offer_number} #{name}#{ext}"
  else
    return false
  end
end
fill_template() click to toggle source
# File lib/ascii_invoicer/InvoiceProject.rb, line 167
def fill_template
  project_name = @name.sub(?_, " ") #latex build fails if values contain a "_"
  manager_name = @settings.manager_name
  version = @settings.version
  template = File.basename(@template_path, ".yml.erb")

  return binding()
end
import_100(hash) click to toggle source

currently only from 1.0.0 to 2.4.0 Format

# File lib/ascii_invoicer/InvoiceProject.rb, line 183
def import_100 hash
  rules = [
    { old:"client",       new:"client/fullname"   },
    { old:"address",      new:"client/address"    },
    { old:"email",        new:"client/email"      },
    { old:"event",        new:"event/name"        },
    { old:"location",     new:"event/location"    },
    { old:"description",  new:"event/description" }, #trim
    { old:"manumber",     new:"offer/number"      },
    { old:"anumber",      new:"offer/appendix"    },
    { old:"rnumber",      new:"invoice/number"    },
    { old:"payed_date",   new:"invoice/payed_date"},
    { old:"invoice_date", new:"invoice/date"      },
    { old:"signature",    new:"manager"           }, #trim
    #{ old:"hours/time",  new:"hours/total"       },
  ]
  ht = HashTransformer.new :rules => rules, :original_hash => hash
  new_hash = ht.transform()
  new_hash[ 'created' ] = "01.01.0000"

  date = strpdates(hash['date'])
  new_hash.set_path("event/dates/0/begin", date[0])
  new_hash.set_path("event/dates/0/end",   date[1]) unless date[1].nil?
  new_hash.set_path("event/dates/0/time/begin", new_hash.get_path("time"))     if date[1].nil?
  new_hash.set_path("event/dates/0/time/end",   new_hash.get_path("time_end")) if date[1].nil?

  manager_lines = new_hash['manager'].lines.to_a()
  if manager_lines.length > 1
    new_hash['manager'] = new_hash['manager'].lines[1]
  end

  if new_hash.get_path("client/fullname").words.class == Array
    new_hash.set_path("client/title",     new_hash.get_path("client/fullname").lines.to_a[0].strip)
    new_hash.set_path("client/last_name", new_hash.get_path("client/fullname").lines.to_a[1].strip)
    new_hash.set_path("client/fullname",  new_hash.get_path("client/fullname").gsub("\n",' ').strip)
  else
    fail_at :client_fullname
  end
  new_hash.set_path("offer/date", Date.today)
  new_hash.set_path("invoice/date", Date.today) unless new_hash.get_path("invoice/date")

  return hash
end
index() click to toggle source

returns index for sorting (year+invoicenumber)

# File lib/ascii_invoicer/InvoiceProject.rb, line 177
def index
  return @data[:invoice][:number] + date.strftime('%Y%m%d') if @data[:invoice][:number]
  return "zzz" + date.strftime('%Y%m%d')
end
manager() click to toggle source

returns the manager

# File lib/ascii_invoicer/InvoiceProject.rb, line 159
def manager
  data :manager
end
name() click to toggle source

returns the name (LuigiProject Interface)

# File lib/ascii_invoicer/InvoiceProject.rb, line 147
def name
  @data[:name]
end
open(project_path) click to toggle source

open given .yml and parse into @raw_data

# File lib/ascii_invoicer/InvoiceProject.rb, line 86
def open(project_path)
  #puts "opening \"#{project_path}\""
  raise "already opened another project" unless @project_path.nil?
  @project_path   = project_path
  @project_folder = File.split(project_path)[0]

  error "FILE \"#{project_path}\" does not exist!" unless File.exists?(project_path)

  ## setting the name
  @data[:name] = File.basename File.split(@project_path)[0]

  ## opening the project file
  begin
    @raw_data        = YAML::load(File.open(project_path))
  rescue SyntaxError => error
    @logger.warn "SyntaxError in #{project_path}, use \"edit\" to correct it.", :both
    @logger.info "Check #{@settings.log_file} for details.", :stdo
    @logger.error error, :file
    @status = :unparsable
    return false
  rescue Psych::SyntaxError => error
    @logger.warn "SyntaxError in #{project_path}, use \"edit\" to correct it.", :both
    @logger.info "Check #{@settings.log_file} for details.", :stdo
    @logger.error error, :file
    @status = :unparsable
    return false
  else
    @data[:valid] = true # at least for the moment
    @status = :ok
    @data[:project_path]  = project_path
  end

  #load format and transform or not
  @data[:format] = if @raw_data['format']
                     @raw_data['format']
                   elsif @raw_data['meta'] and @raw_data['meta']['format']
                     @raw_data['meta']['format']
                   else
                     "1.0.0"
                   end
  if @data[:format] < "2.4.0"
    begin
      @raw_data = import_100 @raw_data
    rescue =>error
      @status = :unparsable
      @logger.warn "#{error} parsing #{@project_path}"
      puts $@
      return false
    end
  end

  prepare_data()
  return true
end
output_files() click to toggle source
# File lib/ascii_invoicer/InvoiceProject.rb, line 288
def output_files
  output_path = File.expand_path File.join @settings.output_path
  {
    :offer => File.join(output_path, export_filename(:offer, 'pdf')),
    :invoice => File.join(output_path, export_filename(:invoice, 'pdf'))
  }
end
path() click to toggle source
# File lib/ascii_invoicer/InvoiceProject.rb, line 163
def path
  @project_path
end
prepare_data() click to toggle source
# File lib/ascii_invoicer/InvoiceProject.rb, line 232
def prepare_data
  @@filtered_keys.each {|key| read key }
  @@generated_keys.each {|key|
    value = apply_generator key, @data
    @data.set_path key, value, ?_, true # symbols = true
  }
end
pretty_name() click to toggle source

displays “CANCELED: name if canceled”

# File lib/ascii_invoicer/InvoiceProject.rb, line 142
def pretty_name
  @data[:canceled] ? "CANCELED: #{@data[:name]}" : @data[:name]
end
products() click to toggle source
# File lib/ascii_invoicer/InvoiceProject.rb, line 227
def products
  data :products
end
state_sign(choice) click to toggle source
# File lib/ascii_invoicer/InvoiceProject.rb, line 296
def state_sign choice
  if validate(choice)
    if File.exists? output_files[choice]
      return Paint[?✓,:green, :bright]
    else
      return Paint[?✓,:green]
    end
  else
    return Paint[?✗,:red]
  end
end
to_s() click to toggle source
# File lib/ascii_invoicer/InvoiceProject.rb, line 255
def to_s
  name
end
to_yaml() click to toggle source
# File lib/ascii_invoicer/InvoiceProject.rb, line 259
def to_yaml
  @raw_data.to_yaml
end
validate(choice = :invoice) click to toggle source
# File lib/ascii_invoicer/InvoiceProject.rb, line 240
def validate choice = :invoice
  blockers(choice).length == 0
end