diff options
Diffstat (limited to 'invoice')
-rw-r--r-- | invoice/dbhelper.py | 80 | ||||
-rw-r--r-- | invoice/footer-line.png | bin | 9695 -> 0 bytes | |||
-rwxr-xr-x | invoice/generate-invoice.py | 258 | ||||
-rw-r--r-- | invoice/ktt-template.lco | 226 | ||||
-rw-r--r-- | invoice/logo.png | bin | 14405 -> 0 bytes | |||
-rw-r--r-- | invoice/mailhelper.py | 89 |
6 files changed, 0 insertions, 653 deletions
diff --git a/invoice/dbhelper.py b/invoice/dbhelper.py deleted file mode 100644 index b04030d..0000000 --- a/invoice/dbhelper.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -#-*- coding: utf-8 -*- - -import sqlite3 - -class DB(object): - def __init__(self, dbfile='shop.db'): - self.__connection = sqlite3.connect(dbfile) - - def get_user_info(self, userid): - c = self.__connection.cursor() - c.execute("SELECT id, email, firstname, lastname, gender, street, plz, city FROM users WHERE id = ?;", (userid,)) - row = c.fetchone() - c.close() - - if row is None: - return None - else: - return { - "id": row[0], - "email": row[1], - "firstname": row[2], - "lastname": row[3], - "gender": row[4], - "street": row[5], - "plz": row[6], - "city": row[7] - } - - def get_invoice_data(self, user, start=0, stop=0): - c = self.__connection.cursor() - startcondition = "" - stopcondition = "" - - if start > 0: - startcondition = " AND timestamp >= %d" % start - if stop > 0: - stopcondition = " AND timestamp <= %d" % stop - - c.execute("SELECT date(timestamp, 'unixepoch', 'localtime'), time(timestamp, 'unixepoch', 'localtime'), productname, price FROM invoice WHERE user = ?" + startcondition + stopcondition + " ORDER BY timestamp;", (user,)) - - result = [] - for row in c: - result.append({ - "date": row[0], - "time": row[1], - "product": row[2], - "price": row[3], - }) - - c.close() - - return result - - def get_invoice_amount(self, user, start=0, stop=0): - query = "SELECT SUM(price) FROM invoice WHERE user = ? AND timestamp >= ? AND timestamp <= ?"; - amount = 0 - - c = self.__connection.cursor() - c.execute(query, (user, start, stop)) - - for row in c: - amount += row[0] - - c.close() - return amount - - def get_users_with_purchases(self, start, stop): - result = [] - - c = self.__connection.cursor() - - c.execute("SELECT user FROM sales WHERE timestamp >= ? AND timestamp <= ? GROUP BY user ORDER BY user;", (start,stop)) - - for row in c: - result.append(row[0]) - - c.close() - - return result diff --git a/invoice/footer-line.png b/invoice/footer-line.png Binary files differdeleted file mode 100644 index b02cbaa..0000000 --- a/invoice/footer-line.png +++ /dev/null diff --git a/invoice/generate-invoice.py b/invoice/generate-invoice.py deleted file mode 100755 index 2dcd73f..0000000 --- a/invoice/generate-invoice.py +++ /dev/null @@ -1,258 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -import datetime, os, sys, subprocess, time, tempfile -from dbhelper import DB -from mailhelper import MAIL - -from config import * - -db = DB() -mailer = MAIL(SMTPSERVERNAME, SMTPSERVERPORT, SMTPSERVERUSER, SMTPSERVERPASS) - -if sys.hexversion < 0x03000000: - print("Please use Python 3.0 or newer!") - sys.exit() - -def get_timespan(type, timestamp = time.time()): - requested = datetime.datetime.fromtimestamp(timestamp) - - if type == "previous day": - # previous day, day from 08:00 - 7:59 - stop = requested.replace(hour = 8, minute = 0, second = 0) - datetime.timedelta(seconds = 1) - start = requested.replace(hour = 8, minute = 0, second = 0) - datetime.timedelta(days = 1) - if stop > requested: - stop -= datetime.timedelta(days = 1) - start -= datetime.timedelta(days = 1) - return (start, stop) - elif type == "previous month": - # previous month, day from 00:00 - 23:59 - stop = requested.replace(hour = 0, minute = 0, second = 0, day = 1) - datetime.timedelta(seconds = 1) - start = stop.replace(day = 1, hour = 0, minute = 0, second = 0) - return (start, stop) - elif type == "current month": - # current month, day from 00:00 - 23:59 - if requested.month == 12: - stop = requested.replace(month = 0, year = requested.year + 1) - else: - stop = requested.replace(month = requested.month + 1) - stop = stop.replace(day = 1, hour = 0, minute = 0, second = 0) - datetime.timedelta(seconds = 1) - start = requested.replace(day = 1, hour = 0, minute = 0, second = 0) - return (start, stop) - else: - return None - -def generate_pdf(data): - rubber = subprocess.Popen("rubber-pipe -d", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE) - pdf, stderr = rubber.communicate(input=data.encode('utf-8')) - return pdf - -def generate_invoice_tex(user, title, subject, start=0, stop=0, temporary=False): - userinfo = db.get_user_info(user) - - result = "\\documentclass[ktt-template,12pt,pagesize=auto,enlargefirstpage=on,paper=a4]{scrlttr2}\n\n" - result+= "\\title{%s}\n" % title - result+= "\\author{Kreativität trifft Technik}\n" - result+= "\\date{\\today}\n\n" - - result+= "\\setkomavar{subject}{%s}\n" % subject - result+= "\\setkomavar{toname}{%s %s}\n" % (userinfo["firstname"], userinfo["lastname"]) - result+= "\\setkomavar{toaddress}{%s\\newline\\newline\\textbf{%d %s}}\n\n" % (userinfo["street"], userinfo["plz"], userinfo["city"]) - - result+= "\\begin{document}\n" - result+= "\t\\begin{letter}{}\n" - - if userinfo["gender"] == "masculinum": - result+= "\t\t\\opening{Sehr geehrter Herr %s,}\n\n" % userinfo["lastname"] - elif userinfo["gender"] == "femininum": - result+= "\t\t\\opening{Sehr geehrte Frau %s,}\n\n" % userinfo["lastname"] - else: - result+= "\t\t\\opening{Sehr geehrte/r Frau/Herr %s,}\n\n" % userinfo["lastname"] - - result+= "\t\twir erlauben uns, Ihnen für den Verzehr von Speisen und Getränken den folgenden Betrag in Rechnung zu stellen:\n\n" - - result += "\t\t\\begin{footnotesize}\n" - result += "\t\t\t\\begin{longtable}{|p{2cm}|p{1.8cm}|p{5cm}|p{2cm}|}\n" - result += "\t\t\t\t\\hline\n" - result += "\t\t\t\t\\textbf{Datum} & \\textbf{Uhrzeit} & \\textbf{Artikel} & \\textbf{Preis}\\\\\n" - result += "\t\t\t\t\\hline\n" - result += "\\endhead\n" - result += "\t\t\t\t\\hline\n" - result += "\\endfoot\n" - - lastdate = "" - total = 0 - for row in db.get_invoice_data(user, start, stop): - total += row["price"] - - row["product"] = row["product"].replace("&", "\\&") - - if lastdate != row["date"]: - result += "\t\t\t\t%s\t& %s\t& %s\t& \\EUR{%d,%02d}\\\\\n" % (row["date"], row["time"], row["product"], row["price"] / 100, row["price"] % 100) - lastdate = row["date"] - else: - result += "\t\t\t\t%s\t& %s\t& %s\t& \\EUR{%d,%02d}\\\\\n" % (" ", row["time"], row["product"], row["price"] / 100, row["price"] % 100) - - result += "\t\t\t\t\\hline\n" - result += "\t\t\t\t\\multicolumn{3}{|l|}{Summe:} & \\EUR{%d,%02d}\\\\\n" % (total / 100, total % 100) - result += "\t\t\t\\end{longtable}\n" - result += "\t\t\\end{footnotesize}\n\n" - - result += "\t\tUmsatzsteuer wird nicht erhoben, da Kreativität trifft Technik e.V. als Kleinunternehmen\n" - result += "\t\tder Regelung des § 19 Abs. 1 UStG unterfällt.\n\n" - - if temporary is True: - result += "\t\tBei dieser Abrechnung handelt es sich lediglich um einen Zwischenstand. Die\n" - result += "\t\tHauptrechnung wird einmal monatlich getrennt zugestellt und der Gesamtbetrag\n" - result += "\t\twird dann vom angegebenen Bankkonto eingezogen.\n\n" - else: - result += "\t\tDer Gesamtbetrag wird in 10 Tagen von dem angegebenen Bankkonto\n" - result += "\t\teingezogen.\n\n" - - result += "\t\t\\closing{Mit freundlichen Grüßen}\n\n" - - result += "\t\\end{letter}\n" - result += "\\end{document}" - - return result - -def generate_invoice_text(user, title, subject, start=0, stop=0, temporary=False): - userinfo = db.get_user_info(user) - result = "" - - if userinfo["gender"] == "masculinum": - result+= "Sehr geehrter Herr %s,\n\n" % userinfo["lastname"] - elif userinfo["gender"] == "femininum": - result+= "Sehr geehrte Frau %s,\n\n" % userinfo["lastname"] - else: - result+= "Sehr geehrte/r Frau/Herr %s,\n\n" % userinfo["lastname"] - - result+= "wir erlauben uns, Ihnen für den Verzehr von Speisen und Getränken wie folgt zu berechnen:\n\n" - - lastdate = "" - total = 0 - namelength = 0 - for row in db.get_invoice_data(user, start, stop): - if len(row["product"]) > namelength: - namelength = len(row["product"]) - - result += " +------------+----------+-" + namelength * "-" + "-+----------+\n" - result += " | Datum | Uhrzeit | Artikel" + (namelength - len("Artikel")) * " " + " | Preis |\n" - result += " +------------+----------+-" + namelength * "-" + "-+----------+\n" - for row in db.get_invoice_data(user, start, stop): - total += row["price"] - - if lastdate != row["date"]: - result += " | %s | %s | %s | %3d,%02d € |\n" % (row["date"], row["time"], row["product"] + (namelength - len(row["product"])) * " ", row["price"] / 100, row["price"] % 100) - lastdate = row["date"] - else: - result += " | %s | %s | %s | %3d,%02d € |\n" % (" ", row["time"], row["product"] + (namelength - len(row["product"])) * " ", row["price"] / 100, row["price"] % 100) - result += " +------------+----------+-" + namelength * "-" + "-+----------+\n" - result += " | Summe: " + namelength * " " + " | %3d,%02d € |\n" % (total / 100, total % 100) - result += " +-------------------------" + namelength * "-" + "-+----------+\n\n" - - result += "Umsatzsteuer wird nicht erhoben, da der Verein Kreativität trifft Technik e.V.\n" - result += "als Kleinunternehmen unter die Regelung des § 19 Abs. 1 UStG fällt.\n\n" - - if temporary is True: - result += "Bei dieser Abrechnung handelt es sich lediglich um einen Zwischenstand. Die\n" - result += "Hauptrechnung wird einmal monatlich getrennt zugestellt und der Gesamtbetrag\n" - result += "wird dann vom angegebenen Bankkonto eingezogen.\n\n" - - dstop, dstart = get_timespan("current month") - start = int(dstop.strftime("%s")) - stop = int(dstart.strftime("%s")) - monthprice = db.get_invoice_amount(user, start, stop) - - result += "Der Gesamtbetrag für den aktuellen Monat beträgt bisher: %3d,%02d €\n\n" % (monthprice / 100, monthprice % 100) - else: - result += "Der Gesamtbetrag wird in 10 Tagen von dem angegebenen Bankkonto\n" - result += "eingezogen.\n\n" - - result += "Grüße aus dem Mainframe,\ndas Shop-System\n" - - return result - -def daily(timestamp = time.time()): - # timestamps for previous day - dstart, dstop = get_timespan("previous day", timestamp) - stop = int(dstop.strftime("%s")) - start = int(dstart.strftime("%s")) - - title = "Getränkerechnung %04d-%02d-%02d" % (dstart.year, dstart.month, dstart.day) - subject = "Getränke-Zwischenstand %02d.%02d.%04d %02d:%02d Uhr bis %02d.%02d.%04d %02d:%02d Uhr" % (dstart.day, dstart.month, dstart.year, dstart.hour, dstart.minute, dstop.day, dstop.month, dstop.year, dstop.hour, dstop.minute) - - for user in db.get_users_with_purchases(start, stop): - userinfo = db.get_user_info(user) - if userinfo is not None: - receiver = ("%s %s" % (userinfo["firstname"], userinfo["lastname"]), userinfo["email"]) - msg = generate_invoice_text(user, title, subject, start, stop, True) - mail = mailer.generate_mail(receiver, title, msg, None, timestamp) - mailer.send_mail(mail, userinfo["email"]) - else: - print("Can't send invoice for missing user with the following id:", user) - -def monthly(timestamp = time.time()): - # timestamps for previous month - dstart, dstop = get_timespan("previous month", timestamp) - stop = int(dstop.strftime("%s")) - start = int(dstart.strftime("%s")) - - title = "Getränkerechnung %04d/%02d" % (dstart.year, dstart.month) - number = 0 - - invoices = {} - invoicedata = [] - - for user in db.get_users_with_purchases(start, stop): - number += 1 - subject = "Rechnung Nr. %04d%02d5%03d" % (dstart.year, dstart.month, number) - userinfo = db.get_user_info(user) - if userinfo is not None: - receiver = ("%s %s" % (userinfo["firstname"], userinfo["lastname"]), userinfo["email"]) - tex = generate_invoice_tex(user, title, subject, start, stop, False) - msg = generate_invoice_text(user, title, subject, start, stop, False) - pdf = generate_pdf(tex) - invoices["%04d%02d5%03d_%s_%s.pdf" % (dstart.year, dstart.month, number, userinfo["firstname"], userinfo["lastname"])] = pdf - amount = db.get_invoice_amount(user, start, stop) - invoicedata.append({"userid": user, "lastname": userinfo["lastname"], "firstname": userinfo["firstname"], "invoiceid": "%04d%02d5%03d" % (dstart.year, dstart.month, number), "amount": amount}) - mail = mailer.generate_mail(receiver, title, msg, pdf, timestamp) - mailer.send_mail(mail, userinfo["email"]) - print("Sent invoice to", userinfo["firstname"], userinfo["lastname"]) - else: - print("Can't send invoice for missing user with the following id:", user) - - print("Sent mails to all users done.") - - csvinvoicedata = "" - for entry in invoicedata: - csvinvoicedata += "%d,%s,%s,%s,%d.%02d\n" % (entry["userid"], entry["lastname"], entry["firstname"], entry["invoiceid"], entry["amount"] / 100, entry["amount"] % 100) - invoices["invoicedata.csv"] = csvinvoicedata - - mail = mailer.generate_mail(("Schatzmeister", "schatzmeister@kreativitaet-trifft-technik.de"), - "Rechnungen %04d%02d" % (dstart.year, dstart.month), - None, invoices, timestamp) - mailer.send_mail(mail, "schatzmeister@kreativitaet-trifft-technik.de") - - print("Sent mail to treasurer done.") - -def backup(): - timestamp = time.time() - dt = datetime.datetime.fromtimestamp(timestamp) - - receiver=("KtT-Shopsystem Backups", "shop-backup@kreativitaet-trifft-technik.de") - subject="Backup KtT-Shopsystem %04d-%02d-%02d %02d:%02d" % (dt.year, dt.month, dt.day, dt.hour, dt.minute) - message="You can find a backup of 'shop.db' attached to this mail." - dbfile = open('shop.db', 'rb') - attachments={"shop.db": dbfile.read()} - dbfile.close() - - msg = mailer.generate_mail(receiver, subject, message, attachments, timestamp) - mailer.send_mail(msg, "shop-backup@kreativitaet-trifft-technik.de") - -if sys.argv[1] == "daily": - daily() - backup() -elif sys.argv[1] == "monthly": - monthly() -else: - print("not supported!") diff --git a/invoice/ktt-template.lco b/invoice/ktt-template.lco deleted file mode 100644 index d7352a0..0000000 --- a/invoice/ktt-template.lco +++ /dev/null @@ -1,226 +0,0 @@ -\usepackage{wallpaper} -\usepackage{ifpdf} -\usepackage{longtable} -\usepackage[utf8]{inputenc} -\usepackage[T1]{fontenc} -\usepackage[german]{babel} -\usepackage{graphicx} -\usepackage{pgf} -\usepackage{calc} -\usepackage[right]{eurosym} -\usepackage{lmodern} -\usepackage{textcomp} - -%% -%% This is file `DIN.lco', -%% generated with the docstrip utility. -%% -%% The original source files were: -%% -%% scrkvers.dtx (with options: `trace') -%% scrklco.dtx (with options: `lco,DIN,head') -%% scrklco.dtx (with options: `lco,DIN,body') -%% -%% Copyright (c) 1994-2012 -%% Markus Kohm and any individual authors listed elsewhere in this file. -%% -%% This file was generated from file(s) of the KOMA-Script bundle. -%% --------------------------------------------------------------- -%% -%% It may be distributed under the conditions of the -%% LaTeX Project Public License in the version distributed together -%% with KOMA-Script, see file `lppl.txt' or `lppl-de.txt'. -%% -%% This file may only be distributed together with a copy of the -%% KOMA-Script bundle. You may however distribute the -%% KOMA-Script bundle without all such generated files. See also -%% `lppl.txt' or `lppl-de.txt' for additional information. -%% -%% The list of files belonging to KOMA-Script distribution is given in -%% the file `manifest.txt'. See also `lppl.txt' or `lppl-de.txt' for -%% additional information. -%% -%% If this file is a beta version, you may not be allowed to distribute -%% it. Look at the comments below to see if this is the case. -%% -%% English and German manuals are part of KOMA-Script bundle. -%% ---------------------------------------------------------- -%% -%% See `README'. -%% -%% The KOMA-Script bundle (but maybe not this file) was based upon the -%% LaTeX 2.09 Script family created by Frank Neukam 1993 and the LaTeX2e -%% standard classes created by The LaTeX3 Project 1994-1996. You may -%% find a complete unmodified copy of LaTeX2e at -%% <http://www.ctan.org/pub/tex-archive/macros/latex/base/>. -%% -%%% From File: scrkvers.dtx -\begingroup - \makeatletter - \ifx\KOMAScriptVersion\undefined - \newcommand*{\@CheckKOMAScriptVersion}[1]{% - \gdef\KOMAScriptVersion{#1}% - }% - \else - \newcommand*{\@CheckKOMAScriptVersion}[1]{% - \def\@tempa{#1}% - \ifx\KOMAScriptVersion\@tempa\else - \@latex@warning@no@line{% - \noexpand\KOMAScriptVersion\space is - `\KOMAScriptVersion',\MessageBreak - but `#1' was expected!\MessageBreak - You should not use classes, packages or files - from\MessageBreak - different KOMA-Script versions% - }% - \fi - } - \fi - \@CheckKOMAScriptVersion{2012/03/08 v3.10a KOMA-Script}% -\endgroup -%%% From File: scrklco.dtx -\ProvidesFile{% - ktt-template% - .lco}[\KOMAScriptVersion\space letter-class-option] -\providecommand*\LCOWarningNoLine[2]{% - \LCOWarning{#1}{#2\@gobble}% -} -\providecommand*\LCOWarning[2]{% - \GenericWarning{% - (#1)\@spaces\@spaces\@spaces\@spaces\@spaces\@spaces\@spaces - }{% - Letter class option #1 Warning: #2% - }% -} -%%% From File: scrklco.dtx -\@ifundefined{scr@fromname@var}{% - \LCOWarningNoLine{% - DIN% - }{% - This letter class option file was made only\MessageBreak - to be used with KOMA-Script letter class\MessageBreak - `scrlttr2'. Use with other classes may result\MessageBreak - in a lot of errors% - }% -}{} -\LetterOptionNeedsPapersize{% - DIN% -}{a4} -\setkomavar*{fromzipcode}{% - D} -\@setplength{foldmarkhpos}{3.5mm} -\@setplength{tfoldmarkvpos}{% - 105mm} -\@setplength{mfoldmarkvpos}{\z@} -\@setplength{bfoldmarkvpos}{% - 210mm} -\@setplength{lfoldmarkhpos}{\z@} -\@setplength{toaddrvpos}{% - 45mm} -\@setplength{toaddrhpos}{% - 20mm} -\@setplength{toaddrwidth}{% - 85mm} -\@setplength{toaddrheight}{% - 45mm} -\@setplength{toaddrindent}{% - \z@} -\@setplength{backaddrheight}{% - 5mm} -\@setplength{specialmailindent}{\fill} -\@setplength{specialmailrightindent}{1em} -\@setplength{locwidth}{% - \z@} -\@setplength{firstheadvpos}{% - 8mm} -\@setplength{firstheadwidth}{% - \paperwidth} -\ifdim \useplength{toaddrhpos}>\z@ - \@addtoplength[-2]{firstheadwidth}{\useplength{toaddrhpos}} -\else - \@addtoplength[2]{firstheadwidth}{\useplength{toaddrhpos}} -\fi -\@setplength{firstfootwidth}{\useplength{firstheadwidth}} -\ifnum \scr@compatibility >\@nameuse{scr@v@2.9t}\relax - \@setplength{firstfootvpos}{\paperheight} - \@addtoplength{firstfootvpos}{-30mm} -\else - \@setplength{firstfootvpos}{1in} - \@addtoplength{firstfootvpos}{\topmargin} - \@addtoplength{firstfootvpos}{\headheight} - \@addtoplength{firstfootvpos}{\headsep} - \@addtoplength{firstfootvpos}{\textheight} - \@addtoplength{firstfootvpos}{\footskip} -\fi -\@setplength{refvpos}{% - 98.5mm} -\@setplength{refaftervskip}{% - \baselineskip} -\@setplength{refwidth}{0pt} -\@setplength{sigindent}{0mm} -\@setplength{sigbeforevskip}{2\baselineskip} -\let\raggedsignature=\centering - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\usepackage{calc} -\makeatletter -\@setplength{refwidth}{\textwidth} -\@setplength{refhpos}{\useplength{toaddrhpos}} -\setlength{\oddsidemargin}{\useplength{toaddrhpos}-1in} -\makeatother - - -\setlength{\parskip}{2ex} -\setlength{\parindent}{0pt} - -\KOMAoptions{fromlogo=true} -\setkomavar{fromname}{Kreativität trifft Technik e.V.} -\setkomavar{fromaddress}{Binsenstraße 3\\26129 Oldenburg} -\setkomavar{fromemail}{vorstand@kreativitaet-trifft-technik.de} -\setkomavar{fromurl}{www.kreativitaet-trifft-technik.de} -\setkomavar{fromlogo}{\includegraphics[scale=0.7]{logo}} -\newcommand\twitter{@KtT\_OL} -\newcommand\amtsgericht{\textbf{Amtsgericht Oldenburg}\\VR 201044} -\newcommand\finanzamt{\textbf{Finanzamt Oldenburg}\\\textbf{Steuer Nr.:} 64/220/18413} -\newcommand\vorstand{\textbf{Vorstand}\\Patrick Günther, Martin Hilscher, Holger Cremer} -\setkomavar{frombank}{\textbf{Raiffeisenbank Oldenburg}\\ - \textbf{Kontonummer}: 370 18 500\\ - \textbf{Bankleitzahl}: 280 602 28 -} - -\firsthead{% - \hfill\includegraphics[scale=0.7]{logo} -} - -\firstfoot{% - \scriptsize{ - \parbox{ \useplength{firstfootwidth} }{ - %\rule{180mm}{0.5pt} - \begin{tabular}{ll} - \textbf{\usekomavar{fromname}}\\ - \usekomavar{fromaddress}\\ - \\ - \amtsgericht - \end{tabular}\hfill - \begin{tabular}{ll} - \textbf{Mail:} \usekomavar{fromemail}\\ - \textbf{Web:} \usekomavar{fromurl}\\ - \textbf{Twitter:} \twitter\\ - \\ - \vorstand - \end{tabular}\hfill - \begin{tabular}{ll} - \usekomavar{frombank}\\ - \\ - \finanzamt - \end{tabular} - }} -} - -\LLCornerWallPaper{1}{footer-line} - -\endinput -%% -%% End of file `DIN.lco'. -% vim: set filetype=tex :EOF diff --git a/invoice/logo.png b/invoice/logo.png Binary files differdeleted file mode 100644 index 788a208..0000000 --- a/invoice/logo.png +++ /dev/null diff --git a/invoice/mailhelper.py b/invoice/mailhelper.py deleted file mode 100644 index ae9d3ac..0000000 --- a/invoice/mailhelper.py +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env python3 -#-*- coding: utf-8 -*- -from email.mime.multipart import MIMEMultipart -from email.mime.application import MIMEApplication -from email.mime.text import MIMEText -from email.header import Header - -import time, email.utils, smtplib - -import sys - -class MAIL(object): - def __init__(self, server, port, username, password): - self.__server = server - self.__port = port - self.__username = username - self.__password = password - pass - - def __format_addresses(self, addresses, header_name=None, charset=None): - header=email.header.Header(charset=charset, header_name=header_name) - for i, (name, addr) in enumerate(addresses): - if i!=0: - # add separator between addresses - header.append(',', charset='us-ascii') - # check if address name is a unicode or byte string in "pure" us-ascii - try: - # check id byte string contains only us-ascii chars - name.encode('us-ascii') - except UnicodeError: - # Header will use "RFC2047" to encode the address name - # if name is byte string, charset will be used to decode it first - header.append(name, charset='utf-8') - # here us-ascii must be used and not default 'charset' - header.append('<%s>' % (addr,), charset='us-ascii') - else: - # name is a us-ascii byte string, i can use formataddr - formated_addr=email.utils.formataddr((name, addr)) - # us-ascii must be used and not default 'charset' - header.append(formated_addr, charset='us-ascii') - return header - - def generate_mail(self, receiver, subject, message, attachments = None, timestamp=time.time(), cc = None): - msg = MIMEMultipart() - msg["From"] = "KtT-Shopsystem <shop@kreativitaet-trifft-technik.de>" - msg["Date"] = email.utils.formatdate(timestamp, True) - - try: - if receiver[0].encode("ascii"): - msg["To"] = receiver[0] + " <" + receiver[1] + ">" - except UnicodeError: - msg["To"] = self.__format_addresses([receiver]) - - if cc != None: - msg["Cc"] = cc - msg["Subject"] = Header(subject, 'utf-8') - msg.preamble = "Please use a MIME aware email client!" - - msg.attach(MIMEText(message, 'plain', 'utf-8')) - - if isinstance(attachments, dict): - for name, data in attachments.items(): - if name.endswith("pdf"): - pdf = MIMEApplication(data, 'pdf') - pdf.add_header('Content-Disposition', 'attachment', filename = name) - msg.attach(pdf) - if name.endswith("db"): - file = MIMEApplication(data) - file.add_header('Content-Disposition', 'attachment', filename = name) - msg.attach(file) - else: - txt = MIMEText(data, 'plain', 'utf-8') - txt.add_header('Content-Disposition', 'attachment', filename = name) - msg.attach(txt) - elif attachments is not None: - pdf = MIMEApplication(attachments, 'pdf') - pdf.add_header('Content-Disposition', 'attachment', filename = 'rechnung.pdf') - msg.attach(pdf) - - return msg - - def send_mail(self, mail, receiver): - server = smtplib.SMTP(self.__server, self.__port) - server.starttls() - if self.__username != "": - server.login(self.__username, self.__password) - maildata = mail.as_string() - server.sendmail(mail["From"], receiver, maildata) - server.quit() |