mirror of
https://github.com/Findus23/invoices.git
synced 2024-09-19 15:13:47 +02:00
finished management
This commit is contained in:
parent
634ba875b3
commit
8fab0003cb
3 changed files with 153 additions and 69 deletions
171
create.py
171
create.py
|
@ -1,75 +1,112 @@
|
|||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import jinja2
|
||||
|
||||
from utils import load_yaml, remove_tmp_files
|
||||
|
||||
env = jinja2.Environment(
|
||||
block_start_string='\BLOCK{',
|
||||
block_end_string='}',
|
||||
variable_start_string='\VAR{',
|
||||
variable_end_string='}',
|
||||
comment_start_string='\#{',
|
||||
comment_end_string='}',
|
||||
line_statement_prefix='%#',
|
||||
line_comment_prefix='%%',
|
||||
trim_blocks=True,
|
||||
autoescape=False,
|
||||
loader=jinja2.FileSystemLoader(os.path.abspath('.'))
|
||||
)
|
||||
|
||||
DATA = {
|
||||
"invoice_id": 1234,
|
||||
"invoice_date": "01.03.2018"
|
||||
}
|
||||
|
||||
DATA["from"] = load_yaml("from.yaml")
|
||||
DATA["to"] = load_yaml("recipents/{id}.yaml".format(id="innocraft"))
|
||||
|
||||
# invoice = {
|
||||
# "mode": "single",
|
||||
# "description": "TESTOBJEKT",
|
||||
# "timerange": "18.12.2016 - 28.02.2017",
|
||||
# "price": 400,
|
||||
# "locale": "de"
|
||||
# }
|
||||
invoice = {
|
||||
"mode": "hourly",
|
||||
"title": "Example Invoice",
|
||||
"description": "Example",
|
||||
"timerange": "18.12.2016 - 28.02.2017",
|
||||
"hours": 35,
|
||||
"per_hour": 21,
|
||||
"locale": "en"
|
||||
}
|
||||
|
||||
invoice["total"] = invoice["per_hour"] * invoice["hours"]
|
||||
|
||||
DATA["invoice"] = invoice
|
||||
|
||||
strings = load_yaml("strings.yaml")
|
||||
from utils import *
|
||||
|
||||
|
||||
def translate(key):
|
||||
if key in strings:
|
||||
return strings[key][invoice["locale"]]
|
||||
else:
|
||||
print("Translation key for '{key}' is missing".format(key=key))
|
||||
def create_invoice():
|
||||
current_id = config["last_id"]
|
||||
current_id += 1
|
||||
config["last_id"] = current_id
|
||||
invoice = {
|
||||
"locale": ask("locale", "set", set=["de", "en"], default="de"),
|
||||
"id": ask("id", "int", default=current_id),
|
||||
"title": ask("title"),
|
||||
"recipient": ask("recipient", "set", set=get_possible_recipents(), default="innocraft"),
|
||||
"date": ask("date", "date", default="today"),
|
||||
"mode": ask("Mode", "set", set=["single", "hourly"], default="hourly"),
|
||||
"description": ask("description"),
|
||||
"start": ask("from", "date"),
|
||||
"end": ask("to", "date"),
|
||||
}
|
||||
if invoice["mode"] == "single":
|
||||
single = {
|
||||
"price": ask("price", "money")
|
||||
}
|
||||
invoice.update(single)
|
||||
elif invoice["mode"] == "hourly":
|
||||
hourly = {
|
||||
"hours": ask("hours", "int"),
|
||||
"per_hour": ask("per hour", "money", default=config["default_hourly_rate"])
|
||||
}
|
||||
invoice.update(hourly)
|
||||
directory = invoice_dir + "/" + str(invoice["id"])
|
||||
os.mkdir(directory)
|
||||
print(invoice)
|
||||
save_yaml(invoice, directory + "/data.yaml")
|
||||
save_yaml(config, "config.yaml")
|
||||
|
||||
|
||||
def compile_invoice(id):
|
||||
directory = invoice_dir + "/" + str(id)
|
||||
invoice = load_yaml(directory + "/data.yaml")
|
||||
env = jinja2.Environment(
|
||||
block_start_string='\BLOCK{',
|
||||
block_end_string='}',
|
||||
variable_start_string='\VAR{',
|
||||
variable_end_string='}',
|
||||
comment_start_string='\#{',
|
||||
comment_end_string='}',
|
||||
line_statement_prefix='%#',
|
||||
line_comment_prefix='%%',
|
||||
trim_blocks=True,
|
||||
autoescape=False,
|
||||
loader=jinja2.FileSystemLoader(os.path.abspath('.'))
|
||||
)
|
||||
if invoice["mode"] == "hourly":
|
||||
invoice["total"] = invoice["per_hour"] * invoice["hours"]
|
||||
data = {
|
||||
"from": load_yaml("from.yaml"),
|
||||
"to": load_yaml("recipients/{id}.yaml".format(id=invoice["recipient"])),
|
||||
"invoice": invoice
|
||||
}
|
||||
|
||||
strings = load_yaml("strings.yaml")
|
||||
|
||||
def translate(key):
|
||||
if key in strings:
|
||||
return strings[key][invoice["locale"]]
|
||||
else:
|
||||
print("Translation key for '{key}' is missing".format(key=key))
|
||||
exit()
|
||||
|
||||
def format_digit(integer):
|
||||
integer = integer / 100
|
||||
string = "{0:.2f}".format(integer)
|
||||
if invoice["locale"] == "de":
|
||||
string = string.replace(".", ",")
|
||||
return string
|
||||
|
||||
env.filters['formatdigit'] = format_digit
|
||||
env.filters['t'] = translate
|
||||
with open(directory + "/{name}.tex".format(name=translate("invoice")), "w") as fh:
|
||||
template = env.get_template('template.tex')
|
||||
fh.write(template.render(section1='Long Form', section2='Short Form', **data))
|
||||
os.chdir(directory)
|
||||
subprocess.check_call(['pdflatex', '{name}.tex'.format(name=translate("invoice"))])
|
||||
print(directory)
|
||||
remove_tmp_files(translate("invoice"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) == 1 or len(sys.argv) > 3 or sys.argv[1] not in ["create", "compile"]:
|
||||
print("please use 'create' or 'compile'")
|
||||
exit()
|
||||
config = load_yaml("config.yaml")
|
||||
invoice_dir = config["invoice_dir"]
|
||||
|
||||
|
||||
def format_digit(integer):
|
||||
string = "{0:.2f}".format(integer)
|
||||
if invoice["locale"] == "de":
|
||||
string = string.replace(".", ",")
|
||||
return string
|
||||
|
||||
|
||||
env.filters['formatdigit'] = format_digit
|
||||
env.filters['t'] = translate
|
||||
with open("output.tex", "w") as fh:
|
||||
template = env.get_template('template.tex')
|
||||
fh.write(template.render(section1='Long Form', section2='Short Form', **DATA))
|
||||
subprocess.check_call(['pdflatex', 'output.tex'])
|
||||
remove_tmp_files("output")
|
||||
if sys.argv[1] == "create":
|
||||
create_invoice()
|
||||
if sys.argv[1] == "compile":
|
||||
if len(sys.argv) == 3:
|
||||
try:
|
||||
invoice_id = int(sys.argv[1])
|
||||
except ValueError:
|
||||
invoice_id = False
|
||||
print("invalid id")
|
||||
exit()
|
||||
else:
|
||||
invoice_id = config["last_id"]
|
||||
compile_invoice(invoice_id)
|
||||
|
|
|
@ -65,8 +65,8 @@
|
|||
\setkomavar{firstfoot}{\centering\color{Gray}\scriptsize\Name\separ\Address\separ\ZIP~\City\\
|
||||
\usekomavar{fromphone}\separ\usekomavar{fromemail}\separ\usekomavar{fromurl}\\\usekomavar{frombank}}
|
||||
|
||||
\setkomavar{invoice}{\VAR{invoice_id}}
|
||||
\setkomavar{date}{\VAR{invoice_date}}
|
||||
\setkomavar{invoice}{\VAR{invoice.id}}
|
||||
\setkomavar{date}{\VAR{invoice.date}}
|
||||
|
||||
\pdfinfo{
|
||||
/Author (\Name)
|
||||
|
|
47
utils.py
47
utils.py
|
@ -1,5 +1,7 @@
|
|||
import os
|
||||
from glob import glob
|
||||
|
||||
import dateparser
|
||||
import yaml
|
||||
|
||||
|
||||
|
@ -8,6 +10,51 @@ def load_yaml(filename):
|
|||
return yaml.load(stream)
|
||||
|
||||
|
||||
def save_yaml(data, filename):
|
||||
with open(filename, 'w') as outfile:
|
||||
yaml.dump(data, outfile, default_flow_style=False)
|
||||
|
||||
|
||||
def remove_tmp_files(base):
|
||||
for ext in ["aux", "log"]:
|
||||
os.remove(base + "." + ext)
|
||||
|
||||
|
||||
def get_possible_recipents():
|
||||
return [os.path.splitext(os.path.basename(file))[0] for file in glob("recipients/*.yaml")]
|
||||
|
||||
|
||||
def ask(question, validator=None, default=None, set=None):
|
||||
while True:
|
||||
string = question + (" [{default}]".format(default=default) if default else "") + ": "
|
||||
answer = input(string)
|
||||
if answer == "":
|
||||
if default:
|
||||
answer = default
|
||||
print("\033[F" + string + str(answer))
|
||||
else:
|
||||
continue
|
||||
if validator == "float":
|
||||
try:
|
||||
answer = float(answer)
|
||||
except ValueError:
|
||||
continue
|
||||
if validator == "money":
|
||||
try:
|
||||
answer = int(answer) * 100
|
||||
except ValueError:
|
||||
continue
|
||||
if validator == "int":
|
||||
try:
|
||||
answer = int(answer)
|
||||
except ValueError:
|
||||
continue
|
||||
if validator == "date":
|
||||
answer = dateparser.parse(answer).date()
|
||||
if answer is None:
|
||||
continue
|
||||
if validator == "set":
|
||||
if answer not in set:
|
||||
print("only [{formats}] are allowed".format(formats=", ".join(set)))
|
||||
continue
|
||||
return answer
|
||||
|
|
Loading…
Reference in a new issue