Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
executable file 132 lines (119 sloc) 5.29 KB
#!/usr/bin/env python3
from decimal import Decimal
from invoice import Invoice
import json
import optparse
import os
import render
import string
import sys
import time
import uuid
# add a --file argument and parse the arguments
parser = optparse.OptionParser()
parser.add_option("-f", "--file", dest = "filename", help = "load invoice from SOURCE", metavar = "SOURCE")
(options, args) = parser.parse_args()
print("Welcome to TurboOlaf!")
# load an invoice from file or, if no file was given, use the default invoice prototype
if options.filename:
invoice = Invoice(json.load(open(options.filename)))
print("Loaded invoice from " + options.filename)
else:
invoice = Invoice(json.load(open("invoice_prototype.olaf")))
for product in invoice['products']:
product["quantity"] = 0
invoice['id'] = str(int(time.time()))
# records the order in which the products entered
product_addition_order_list = []
# remember the last added product that is impacted by the quantity command
last_added_product = None
while True:
# print a list of all scanned products
# order them by insertion, newest product first
unique_product_addition_order_list = []
for p in product_addition_order_list:
if not p in unique_product_addition_order_list:
unique_product_addition_order_list.append(p)
# also include products that may have been scanned in a previous run
for p in invoice['products']:
if not p in unique_product_addition_order_list:
unique_product_addition_order_list.append(p)
# print the list preceded by a line break
print();
print(render.product_list_as_string(unique_product_addition_order_list))
print("Total: " + str(invoice.get_total_price()))
# try to get input for a new product
try:
entered = input("olaf > ")
except EOFError:
break
except KeyboardInterrupt:
print("\nCaught SIGINT, exiting...\n")
sys.exit(1)
# clear immediately and then show the input again
# this gives the impression that the input field always scrolls to the top
os.system("clear")
print("olaf > " + entered)
# end if no input was given
if not entered:
break
else:
# check if the input is a Sonderposten
if entered[0] == '$':
# the input is a Sonderposten
try:
special_product = { 'ids': [str(uuid.uuid4())]}
special_product['quantity'] = 1
# try to extract a given name from the input
try:
special_product['name'] = entered[1:].split(' ')[1]
except IndexError:
special_product['name'] = "Sonderposten"
special_product['price'] = Decimal(entered[1:].split(' ')[0])
# only if nothing of the above failed, write the above
invoice['products'].append(special_product)
except:
print("Invalid Sonderposten format!")
# else, if the input is not a Sonderposten
else:
# check if any of the entered characters are letters
if any(map(lambda l: l in string.ascii_letters, entered)):
# try to get a product with the given identifier
if not invoice.get_product(entered):
print("Invalid product code " + entered + " entered")
else:
invoice.get_product(entered)["quantity"] += 1
product_addition_order_list.insert(0, invoice.get_product(entered))
last_added_product = invoice.get_product(entered)
print("Entered " + invoice.get_product(entered)["name"])
else:
# check if the length of the input is long enough for a barcode
if len(entered) >= 8:
if not invoice.get_product(entered):
print("Invalid product code " + entered + " entered")
else:
invoice.get_product(entered)["quantity"] += 1
product_addition_order_list.insert(0, invoice.get_product(entered))
last_added_product = invoice.get_product(entered)
print("Scanned " + invoice.get_product(entered)["name"])
# a short number, i.e. a quantity was entered
else:
if last_added_product:
last_added_product["quantity"] += int(entered) - 1
print("Added another " + str(int(entered) - 1) + " " + last_added_product["name"])
# adding even more products might lead to a confusing workflow
last_added_product = None
else:
print("No previous product entered!")
print(render.invoice_as_printable_string(invoice.get_copy_with_resolved_dependencies()))
# create data directories if they do not exist yet
if not os.path.exists('invoices/'):
os.makedirs('invoices/')
if not os.path.exists('qif/'):
os.makedirs('qif/')
invoice_file = open("invoices/" + invoice['id'] + ".json", 'w')
invoice_file.write(json.dumps(invoice, indent=4, ensure_ascii=False))
invoice_file.close()
qif_file = open("qif/" + invoice['id'] + ".qif", 'w')
qif_file.write(render.invoice_as_qif(invoice))
qif_file.close()