Skip to content

Commit a3f2310

Browse files
authored
Merge pull request #20 from westnetz/feature/testcoverage
Add test for most CLI functions (print-stats, create-invoice, print-contracts, render)
2 parents 41f5464 + 1ab8a57 commit a3f2310

25 files changed

+852
-33
lines changed

.github/workflows/rechnung_checks_and_tests.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
run: |
2929
pip install black
3030
black .
31-
# - name: Test with pytest
32-
# run: |
33-
# pip install pytest
34-
# pytest
31+
- name: Test with pytest
32+
run: |
33+
pip install pytest pytest-cov
34+
make test

.gitignore

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
*.egg-info/*
2+
.coverage
23
__pycache__
3-
assets/
44
bin/
5-
contracts/
6-
invoices/
75
lib*
86
pyvenv.cfg
9-
settings.yaml
107
share/
8+
./assets/
9+
./contracts/
10+
./invoices/
11+
./settings.yaml

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ black: ## Format code
2121

2222
.PHONY: test
2323
test: ## Run unittests
24-
python -m pytest --cov=./ $(PYTEST_ARGS)
24+
pytest -v rechnung --cov=./ --cov-report term-missing:skip-covered $(PYTEST_ARGS)
2525

2626
.PHONY: git-flow
2727
git-flow: ## Initialize git-flow

rechnung/cli.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import click
22
import os
3+
import arrow
34

45
from .settings import get_settings_from_cwd, copy_assets, create_required_settings_file
56
from .invoice import create_invoices, render_invoices, send_invoices
@@ -21,7 +22,7 @@ def init():
2122
"""
2223
Create the directory structure in the current directory.
2324
"""
24-
print("Initializing...")
25+
print(f"Initializing in {cwd}...")
2526

2627
create_required_settings_file(cwd)
2728
settings = get_settings_from_cwd(cwd, create_non_existing_dirs=True)
@@ -62,16 +63,21 @@ def print_stats():
6263
Print stats about the contracts
6364
"""
6465
settings = get_settings_from_cwd(cwd)
65-
contracts = get_contracts(settings).values()
66-
print(f"{len(contracts)} contracts in total")
67-
68-
total_monthly = sum(
69-
map(
70-
lambda x: x[0].get("quantity", 1) * x[0]["price"],
71-
list(map(lambda i: i["items"], contracts)),
66+
contracts = get_contracts(settings).items()
67+
now = arrow.now()
68+
contracts_totals = list()
69+
for cid, data in contracts:
70+
# fetch dates, if no end date is set or know, it will be set to 1 year in the future
71+
start_date = arrow.get(data["start"])
72+
end_date = arrow.get(data.get("end", now + arrow.arrow.relativedelta(years=1)))
73+
if start_date > now or now > end_date:
74+
continue
75+
76+
contracts_totals.append(
77+
sum(map(lambda i: i.get("quantity", i) * i["price"], data["items"]))
7278
)
73-
)
74-
print(f"{total_monthly:.2f}€ per month")
79+
print(f"{len(contracts_totals)} active contracts of {len(contracts)} in total")
80+
print(f"{sum(contracts_totals):.2f}€ per month")
7581

7682

7783
@cli1.command()

rechnung/tests/__init__.py

Whitespace-only changes.
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
@page {
2+
size: A4;
3+
margin: 10mm 15mm 25mm 20mm;
4+
}
5+
6+
@font-face {
7+
font-family: Delicious;
8+
}
9+
10+
/* ASIDE SECTION */
11+
12+
section.aside {
13+
float: right;
14+
margin-left: 10mm;
15+
width: 15%;
16+
height: 100%;
17+
}
18+
19+
p.aside {
20+
font-size: 10px;
21+
}
22+
23+
p.asidesmall {
24+
font-size: 9px;
25+
}
26+
27+
#logo {
28+
width: 100%;
29+
}
30+
31+
/* MAIN SECTION */
32+
33+
section.main {
34+
margin-left: 5mm;
35+
}
36+
37+
table.details {
38+
width: 75%;
39+
border: 1px solid #000;
40+
margin: 3mm 0mm 3mm 2mm;
41+
}
42+
43+
td.details {
44+
border: 1px solid;
45+
border-color: #000;
46+
padding: 1mm;
47+
}
48+
49+
th.details{
50+
padding: 2mm 2mm 1mm 2mm;
51+
font-size: 14px;
52+
}
53+
54+
td.detailsheader{
55+
padding: 0mm 2mm 2mm 2mm;
56+
font-size: 10px;
57+
}
58+
59+
table.bank {
60+
width: 50%;
61+
margin: auto;
62+
}
63+
64+
td.left {
65+
width: 30%;
66+
}
67+
68+
.contactpreferences {
69+
margin: 3mm 0mm 3mm 2mm;
70+
}
71+
72+
.smallprint {
73+
width: 75%;
74+
font-size: 9px;
75+
}
76+
77+
/* GENERAL STUFF */
78+
79+
h1 {
80+
font-family: Delicious;
81+
font-size: 22px;
82+
margin-left: 5mm;
83+
}
84+
85+
table {
86+
width: 100%;
87+
border-color: #000;
88+
border-collapse: collapse;
89+
}
90+
91+
p, th, td {
92+
font-family: Delicious;
93+
font-size: 11px;
94+
}
95+
96+
p {
97+
width: 75%;
98+
}
99+
100+
th {
101+
font-size: 11px;
102+
}
103+
104+
hr {
105+
margin: 15mm 100mm 0mm 0mm;
106+
}
107+
108+
.left {
109+
text-align: left;
110+
}
111+
112+
.center {
113+
text-align: center;
114+
}
115+
116+
.right {
117+
text-align: right;
118+
}
119+
120+
.strong {
121+
font-weight: bold;
122+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Dear customer,
2+
3+
please find your contract attached. Sign it and send it back to us please.
4+
5+
Cheers,
6+
John Doe
7+
8+
--
9+
A great company
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
<html>
2+
3+
<head>
4+
<title>
5+
Contract
6+
</title>
7+
</head>
8+
9+
<body>
10+
<h1>Contract</h1>
11+
12+
<section class="aside">
13+
14+
<embed src="file://{{ invoice.logo_path }}" id="logo"
15+
/>
16+
17+
<p class="aside">
18+
your great company ltd.<br />
19+
A street 21<br />
20+
01234 Inacity
21+
</p>
22+
<p class="aside">
23+
+49 (0)123 4567 890
24+
</p>
25+
<p class="aside">
26+
info@yourcompany.tld<br />
27+
http://yourcompany.tld
28+
</p>
29+
<p class="aside">
30+
IBAN DE00 0000 0000 0000 0000 00<br />
31+
BIC ACABBACA<br />
32+
A Bank
33+
</p>
34+
<p class="aside">
35+
St.-Nr: 000/000/000000<br />
36+
Ust.-ID: DE00000000000
37+
</p>
38+
<p class="asidesmall">
39+
Court: Inacity
40+
</p>
41+
</section>
42+
43+
<section class="main">
44+
<table class="details">
45+
<tr>
46+
<th class="details" colspan="2"><b>Vertrags- und Anschlussinformationen</b>
47+
<tr>
48+
<td class="detailsheader" colspan="2">(wird von A great company ausgefüllt)</td>
49+
</tr>
50+
{% for detail in details %}
51+
<tr>
52+
<td class="details left">{{ detail.verbose_name }}</td>
53+
<td class="details">{{ detail.verbose_answer }}</td>
54+
</tr>
55+
{% endfor %}
56+
</table>
57+
58+
<p>
59+
Alle Preise verstehen sich in Euro. Das Zahlungsziel beträgt 14 Kalendertage ab Rechnungsstellung. Der angegebene Betrag ist unter Angabe der Rechnungsnummer auf folgendes Konto zu überweisen:
60+
</p>
61+
62+
<table class="bank">
63+
<tr>
64+
<td>Kontoinhaber: </td>
65+
<td>A great company</td>
66+
</tr>
67+
<tr>
68+
<td>Bank: </td>
69+
<td>Postbank Leipzig</td>
70+
</tr>
71+
<tr>
72+
<td>IBAN: </td>
73+
<td>DE00 0000 0000 0000 0000 00</td>
74+
</tr>
75+
<tr>
76+
<td>BIC: </td>
77+
<td>ACABBACA</td>
78+
</tr>
79+
</table>
80+
81+
<p></p>
82+
83+
<table class="details">
84+
<tr>
85+
<th class="details" colspan="2">Kundendaten</th>
86+
</tr>
87+
<tr>
88+
<td class="detailsheader" colspan="2">(bitte vollständig ausfüllen)</td>
89+
</tr>
90+
<tr>
91+
<td class="details left">Firma</td>
92+
<td class="details"></td>
93+
</tr>
94+
<tr>
95+
<td class="details left">Name, Vorname</td>
96+
<td class="details"></td>
97+
</tr>
98+
<tr>
99+
<td class="details left">Straße, Hausnummer</td>
100+
<td class="details"></td>
101+
</tr>
102+
<tr>
103+
<td class="details left">Postleitzahl, Ort, Land</td>
104+
<td class="details"></td>
105+
</tr>
106+
<tr>
107+
<td class="details left">Geburtsdatum</td>
108+
<td class="details"></td>
109+
</tr>
110+
<tr>
111+
<td class="details left">Emailadresse</td>
112+
<td class="details"></td>
113+
</tr>
114+
</table>
115+
116+
<p></p>
117+
118+
<table class="details">
119+
<tr>
120+
<th class="details" colspan="2">Alternative Kontaktinformationen
121+
</tr>
122+
<tr>
123+
<td class="detailsheader" colspan="2">(Angabe freiwillig)</td>
124+
</tr>
125+
<tr>
126+
<td class="details left">Handynummer</td>
127+
<td class="details"></td>
128+
</tr>
129+
<tr>
130+
<td class="details left">Sonstiges</td>
131+
<td class="details"></td>
132+
</tr>
133+
</table>
134+
135+
<p class="contactpreferences">
136+
□ Störungs- und Wartungsbenachrichtigung per Email (bei Wunsch bitte ankreuzen)<br />
137+
□ Informationen rund um A great company per Mail (bei Wunsch bitte ankreuzen)
138+
</p>
139+
140+
<p class="smallprint"><b>Rechte des Betroffenen: Auskunft, Berichtigung, Löschung und Sperrung, Widerspruchsrecht</b><br />
141+
Sie sind gemäß § 34 BDSG jederzeit berechtigt, gegenüber der A great company (Vertragspartner) um umfangreiche Auskunftserteilung zu den zu Ihrer Person gespeicherten Daten zu ersuchen. Gemäß § 35 BDSG können Sie jederzeit gegenüber des A great company (Vertragspartner) die Berichtigung, Löschung und Sperrung einzelner personenbezogener Daten verlangen. Sie können darüber hinaus jederzeit ohne Angabe von Gründen von Ihrem Widerspruchsrecht Gebrauch machen und die erteilte Einwilligungserklärung mit Wirkung für die Zukunft abändern oder gänzlich widerrufen. Sie können den Widerruf entweder postalisch oder per E-Mail an den Vertragspartner übermitteln. Es entstehen Ihnen dabei keine anderen Kosten als die Portokosten bzw. die Übermittlungskosten.</p>
142+
143+
<p>Ich bin volljährig und habe die Widerrufsbelehrung sowie die Produktbeschreibung erhalten und zur Kenntnis genommen.</p>
144+
145+
<hr />
146+
<p>
147+
Datum, Ort, Unterschrift
148+
</p>
149+
</section>
150+
151+
</body>
152+
</html>

0 commit comments

Comments
 (0)