1
0
Fork 0
mirror of https://github.com/Findus23/invoices.git synced 2024-09-19 15:13:47 +02:00

first working version

This commit is contained in:
Lukas Winkler 2018-03-04 21:04:54 +01:00
commit 634ba875b3
No known key found for this signature in database
GPG key ID: 94AFBE7C2656A5B5
5 changed files with 572 additions and 0 deletions

327
.gitignore vendored Normal file
View file

@ -0,0 +1,327 @@
# Created by https://www.gitignore.io/api/latex,python
### LaTeX ###
## Core latex/pdflatex auxiliary files:
*.aux
*.lof
*.log
*.lot
*.fls
*.out
*.toc
*.fmt
*.fot
*.cb
*.cb2
## Intermediate documents:
*.dvi
*.xdv
*-converted-to.*
*.pdf
## Bibliography auxiliary files (bibtex/biblatex/biber):
*.bbl
*.bcf
*.blg
*-blx.aux
*-blx.bib
*.run.xml
## Build tool auxiliary files:
*.fdb_latexmk
*.synctex
*.synctex(busy)
*.synctex.gz
*.synctex.gz(busy)
*.pdfsync
*Notes.bib
## Auxiliary and intermediate files from other packages:
# algorithms
*.alg
*.loa
# achemso
acs-*.bib
# amsthm
*.thm
# beamer
*.nav
*.pre
*.snm
*.vrb
# changes
*.soc
# cprotect
*.cpt
# elsarticle (documentclass of Elsevier journals)
*.spl
# endnotes
*.ent
# fixme
*.lox
# feynmf/feynmp
*.mf
*.mp
*.t[1-9]
*.t[1-9][0-9]
*.tfm
#(r)(e)ledmac/(r)(e)ledpar
*.end
*.?end
*.[1-9]
*.[1-9][0-9]
*.[1-9][0-9][0-9]
*.[1-9]R
*.[1-9][0-9]R
*.[1-9][0-9][0-9]R
*.eledsec[1-9]
*.eledsec[1-9]R
*.eledsec[1-9][0-9]
*.eledsec[1-9][0-9]R
*.eledsec[1-9][0-9][0-9]
*.eledsec[1-9][0-9][0-9]R
# glossaries
*.acn
*.acr
*.glg
*.glo
*.gls
*.glsdefs
# gnuplottex
*-gnuplottex-*
# gregoriotex
*.gaux
*.gtex
# hyperref
*.brf
# knitr
*-concordance.tex
# TODO Comment the next line if you want to keep your tikz graphics files
*.tikz
*-tikzDictionary
# listings
*.lol
# makeidx
*.idx
*.ilg
*.ind
*.ist
# minitoc
*.maf
*.mlf
*.mlt
*.mtc[0-9]*
*.slf[0-9]*
*.slt[0-9]*
*.stc[0-9]*
# minted
_minted*
*.pyg
# morewrites
*.mw
# nomencl
*.nlo
# pax
*.pax
# pdfpcnotes
*.pdfpc
# sagetex
*.sagetex.sage
*.sagetex.py
*.sagetex.scmd
# scrwfile
*.wrt
# sympy
*.sout
*.sympy
sympy-plots-for-*.tex/
# pdfcomment
*.upa
*.upb
# pythontex
*.pytxcode
pythontex-files-*/
# thmtools
*.loe
# TikZ & PGF
*.dpth
*.md5
*.auxlock
# todonotes
*.tdo
# easy-todo
*.lod
# xindy
*.xdy
# xypic precompiled matrices
*.xyc
# endfloat
*.ttt
*.fff
# Latexian
TSWLatexianTemp*
## Editors:
# WinEdt
*.bak
*.sav
# Texpad
.texpadtmp
# Kile
*.backup
# KBibTeX
*~[0-9]*
# auto folder when using emacs and auctex
/auto/*
# expex forward references with \gathertags
*-tags.tex
### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
.pytest_cache/
nosetests.xml
coverage.xml
*.cover
.hypothesis/
# Translations
*.mo
*.pot
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule.*
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
output*
*.yaml
!*.example.yaml
!strings.yaml
.idea/

75
create.py Normal file
View file

@ -0,0 +1,75 @@
import os
import subprocess
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")
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):
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")

24
strings.yaml Normal file
View file

@ -0,0 +1,24 @@
invoice:
de: Rechnung
en: Invoice
descr:
de: Beschreibung
en: Description
period:
de: Leistungszeitraum
en: Period
total:
de: Gesamtpreis
en: Total
per_hour:
de: Stundensatz
en: Hourly Rate
hours:
de: Stunden
en: Hours
taxexception:
de: Umsatzsteuerfrei aufgrund der Kleinunternehmerregelung gemäß §6(1)27 UStG
en: VAT-exempt because of small-business regulation (§6(1)27 UStG)
transfer:
de: Ich bitte Sie, den Gesamtbetrag innerhalb der nächsten 10 Tage auf folgendes Konto zu überweisen
en: Please transfer the due invoice amount to the following account

133
template.tex Normal file
View file

@ -0,0 +1,133 @@
\documentclass[
a4paper,
12pt,
version=last,
fromalign=right,
% foldmarks=p, % keine mittlere Faltmarke
foldmarks=off,
enlargefirstpage,
fromemail,
fromphone,
fromcity,
fromlogo,
fromrule,
backaddress,
]{scrlttr2}
\usepackage[utf8]{inputenc}
\BLOCK{if invoice.locale =="de"}
\usepackage[ngerman]{babel}
\BLOCK{else}
\usepackage[english]{babel}
\BLOCK{endif}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{mathpazo}
\usepackage[left]{eurosym}
\usepackage{booktabs}
\usepackage{microtype}
\usepackage{tabularx}
\usepackage{color}
\definecolor{LightGray}{rgb}{0.7,0.7,0.7}
\definecolor{Gray}{rgb}{0.5,0.5,0.5}
\setkomafont{fromrule}{\color{LightGray}}
\setkomafont{fromaddress}{\sffamily} % Sans Serif
\setkomafont{fromname}{\sffamily\bfseries} % and bold
\setkomafont{pagefoot}{\sffamily\bfseries}
\usepackage{graphicx}
\newcommand{\separ}{~\textperiodcentered~}
\hyphenpenalty=10000
\newcommand{\VAR}[1]{\LaTeX} % Just a placeholder (will never be used)
\newcommand{\BLOCK}[1]{\LaTeX} % Just a placeholder (will never be used)
\newcommand{\Name}{\VAR{from.name}}
\setkomavar{fromname}{\Name}
\newcommand{\Address}{\VAR{from.address}}
\newcommand{\ZIP}{\VAR{from.zip}}
\newcommand{\City}{\VAR{from.city}}
\newcommand{\CityShort}{\VAR{from.cityShort}}
\setkomavar{fromaddress}{\Address\\\ZIP~\City
\BLOCK{if to.country!="Austria"}\\\VAR{from.country}\BLOCK{endif}}
\setkomavar{fromphone}[]{\VAR{from.phone}}
\setkomavar{fromemail}[]{\VAR{from.email}}
\setkomavar{fromurl}[]{\VAR{from.url}}
%\setkomavar{fromlogo}{\includegraphics[height=3.2cm]{template/header.jpg}}
\setkomavar{frombank}{Sparkasse Krems\separ IBAN: \VAR{from.IBAN}\separ BIC: \VAR{from.BIC}}
%TODO: Linie über
\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}}
\pdfinfo{
/Author (\Name)
/Title (\VAR{"invoice" |t} \VAR{from.name} (\VAR{rechnungsDatum}))
/Subject (\VAR{"invoice" |t} \VAR{from.name} (\VAR{rechnungsDatum}))
/Keywords (\VAR{"invoice" |t})
}
\setkomavar{backaddress}{\usekomavar{fromname}, \Address, \ZIP~\CityShort}
% Begin document
\begin{document}
\begin{letter}{\VAR{to.name} \\ \VAR{to.address} \\ \VAR{to.plz}~\VAR{to.ort}
\BLOCK{if to.country!="Austria"}\\\VAR{to.country}\BLOCK{endif}}
\setkomavar{title}{\VAR{invoice.title}}
\opening{}
\BLOCK{if invoice.mode=="single"}
\begin{tabular}{ll}
\VAR{"descr"|t}:& \VAR{invoice.description} \\
\VAR{"period"|t}: & \VAR{invoice.timerange} \\
\VAR{"total"|t}: & \EUR{\VAR{invoice.price | formatdigit }} \\
\vspace{0.5cm}
\end{tabular}
\BLOCK{elif invoice.mode=="hourly"}
\vspace{0.5cm}
\begin{tabularx}{\textwidth}{Xrrr}
\VAR{"descr"|t} & \VAR{"per_hour"|t} & \VAR{"hours"|t} & \VAR{"total"|t} \\ \midrule
\VAR{invoice.description} &
\EUR{\VAR{invoice.per_hour | formatdigit }} &
\VAR{invoice.hours} &
\EUR{\VAR{invoice.total | formatdigit }} \\
\midrule %\cmidrule{4-4}
& & & \EUR{\VAR{invoice.total | formatdigit }} \\
\end{tabularx}
\BLOCK{endif}
\vspace{0.5cm}
\noindent \VAR{"taxexception"|t}
\vspace{0.5cm}
\noindent \VAR{"transfer"|t}:
\vspace{0.5cm}
\begin{tabular}{@{}ll}
Bank: &\VAR{from.bank}\\
IBAN:& \VAR{from.IBAN}\\
BIC:& \VAR{from.BIC}
\end{tabular}
\end{letter}
\end{document}

13
utils.py Normal file
View file

@ -0,0 +1,13 @@
import os
import yaml
def load_yaml(filename):
with open(filename, 'r') as stream:
return yaml.load(stream)
def remove_tmp_files(base):
for ext in ["aux", "log"]:
os.remove(base + "." + ext)