Skip to content

Commit 320c8df

Browse files
committed
Implement a tool for income journals
1 parent 1ae06b7 commit 320c8df

15 files changed

+964
-5
lines changed

Diff for: README.rst

+13
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,19 @@ arba:
9090

9191
Sugeneruoja visas sąskaitas iš YAML failo HTML arba PDF formatu.
9292

93+
94+
``shaibos-journal`` – pajamų-išlaidų žurnalo generavimas
95+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
96+
97+
Naudojimas:
98+
99+
::
100+
101+
shaibos-invoice --format=html --year=2020
102+
103+
Suformuoja perskaitomus pajamų-išlaidų žurnalus visoms sukonfiguruotoms veikloms, turinčioms sąskaitų.
104+
105+
93106
``shaibos-totals`` – per metus išrašytų sąskaitų suvestinė
94107
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
95108

Diff for: bin/shaibos-journal

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
4+
import argparse
5+
6+
import os
7+
8+
try:
9+
import shaibos # noqa pylint: disable=unused-import
10+
except ImportError:
11+
import sys
12+
13+
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../'))
14+
15+
import shaibos # noqa pylint: disable=unused-import
16+
17+
from shaibos.util.template import default_journal_template_path
18+
from shaibos.load.from_yaml import load_invoices_from_yaml_file
19+
from shaibos.save.to_format import save_any
20+
from shaibos.save.to_format import format_to_extension
21+
from shaibos.util.log import get_logger
22+
23+
# ---
24+
25+
logger = get_logger()
26+
27+
28+
def export_journals(input_yaml, year, print_totals, template, output_dir, format):
29+
all_invoices = load_invoices_from_yaml_file(input_yaml)
30+
extension = format_to_extension(format)
31+
32+
all_invoices_by_activity = {}
33+
34+
for invoice_number_prefix in all_invoices:
35+
for invoice in all_invoices[invoice_number_prefix]:
36+
if not invoice.has_been_paid():
37+
logger.warning("Invoice '%s' hasn't been marked as paid, skipping", invoice)
38+
continue
39+
if invoice.payment.date.year != year:
40+
continue
41+
42+
activity_code = invoice.activity.evrk_code
43+
if activity_code not in all_invoices_by_activity:
44+
all_invoices_by_activity[activity_code] = []
45+
46+
all_invoices_by_activity[activity_code].append(invoice)
47+
48+
for evrk_code, invoices_by_activity in all_invoices_by_activity.items():
49+
invoices_by_activity = sorted(invoices_by_activity,
50+
key=lambda x: (x.payment_date(), x.number))
51+
52+
total_taxed_income = sum(invoice.total_taxed_income for invoice in invoices_by_activity)
53+
data = {
54+
'invoices': invoices_by_activity,
55+
'seller': invoices_by_activity[0].seller,
56+
'activity': invoices_by_activity[0].activity,
57+
'print_totals': print_totals,
58+
'total_taxed_income': total_taxed_income,
59+
'debug_exchange_rates': False,
60+
}
61+
62+
output_path = os.path.join(output_dir,
63+
'journal_{}_{}.{}'.format(year, evrk_code, extension))
64+
save_any(data, template, output_path, format)
65+
logger.info('Saved %s journal %s', format, output_path)
66+
67+
68+
if __name__ == "__main__":
69+
parser = argparse.ArgumentParser(description='Export income journals to HTML or PDF.')
70+
parser.add_argument('-i', '--input_yaml', type=str, default='shaibos.yaml',
71+
help='YAML file with invoices (leave empty to use shaibos.yaml)')
72+
parser.add_argument('-t', '--template', type=str, default=default_journal_template_path(),
73+
help='Jinja2 template for rendering the journal '
74+
'(leave empty to use basic template)')
75+
parser.add_argument('-o', '--output_dir', type=str, default=None,
76+
help='Output directory for files (leave empty to write to '
77+
'"invoices/(pdf|html)")')
78+
parser.add_argument('-y', '--year', type=int, required=True,
79+
help='Year for which to print journal')
80+
parser.add_argument('--print_totals', default=False, action='store_true',
81+
help='Whether to print totals in a separate line')
82+
parser.add_argument('--format', type=str, default='html',
83+
help='Format of the output. Allowed options: html (default), pdf')
84+
args = parser.parse_args()
85+
86+
output_dir = args.output_dir
87+
if args.format == 'html':
88+
if not output_dir:
89+
output_dir = "invoices/html/"
90+
elif args.format == 'pdf':
91+
if not output_dir:
92+
output_dir = "invoices/pdf/"
93+
else:
94+
raise Exception('Unsupported output format {}'.format(args.format))
95+
96+
logger.debug("Using input YAML file: %s", args.input_yaml)
97+
logger.debug("Using Jinja2 template: %s", args.template)
98+
logger.debug("Writing to output path: %s", output_dir)
99+
100+
if not os.path.isdir(output_dir):
101+
os.makedirs(output_dir)
102+
103+
export_journals(args.input_yaml, args.year, args.print_totals, args.template, output_dir,
104+
args.format)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>
6+
Gyventojo individualios veiklos pajamų - išlaidų žurnalas
7+
</title>
8+
<style type="text/css" media="all">
9+
10+
@page {
11+
size: A4 portrait;
12+
counter-increment: page;
13+
margin: 0;
14+
15+
@bottom-right {
16+
padding-right: 1em;
17+
content: counter(page) " / " counter(pages);
18+
}
19+
}
20+
21+
html, body {
22+
/* A4 */
23+
width: 210mm;
24+
height: 297mm;
25+
26+
font-size: 10pt;
27+
margin: 0;
28+
padding: 0;
29+
30+
font-family: "DejaVu Serif";
31+
}
32+
33+
body {
34+
padding: 2em;
35+
}
36+
37+
p {
38+
padding: 0;
39+
margin: 0;
40+
}
41+
42+
table {
43+
border: 1px solid;
44+
border-collapse: collapse;
45+
}
46+
47+
td,
48+
th {
49+
border: 1px solid;
50+
padding: 0.2em 0.4em;
51+
text-align: left;
52+
vertical-align: top;
53+
}
54+
55+
th {
56+
background-color: lightgray;
57+
58+
/* Print background color */
59+
-webkit-print-color-adjust: exact;
60+
}
61+
62+
#main-heading {
63+
text-align: center;
64+
margin: 1em 4em;
65+
font-size: 2em;
66+
}
67+
68+
.caption {
69+
width: 100%;
70+
border-bottom: 1px solid silver;
71+
margin: 1em 0.5em 1em 0.5em;
72+
}
73+
74+
.invoices td:nth-child(2) {
75+
text-wrap: none;
76+
}
77+
</style>
78+
</head>
79+
80+
<body>
81+
82+
83+
<h1 id="main-heading">Gyventojo individualios veiklos pajamų - išlaidų apskaitos žurnalas</h1>
84+
85+
<div class="caption">Vardenis Pavardenis 38912010123</div>
86+
<div class="caption">Adreso g. 1-2, LT-12345 Vilnius</div>
87+
<div class="caption">620100 Kompiuterių programavimo veikla</div>
88+
89+
<table id="invoices">
90+
<tr>
91+
<th>Eilės nr.</th>
92+
<th>Data</th>
93+
<th>Dokumento data, pavadinimas ir numeris</th>
94+
<th>Operacijos turinys</th>
95+
<th>Pajamų suma (eurais)</th>
96+
<th>Išlaidos ir<br/>(arba) leidžiami atskaitymai</th>
97+
</tr>
98+
<tr>
99+
<td>1</td>
100+
<td>2015-04-03</td>
101+
<td>
102+
2015-03-31 sąskaita faktūra
103+
Serija VVP Nr. 1
104+
</td>
105+
<td>Gaunamos pajamos už:
106+
Svetainės programavimo darbai.
107+
108+
109+
</td>
110+
<td>180.00</td>
111+
<td></td>
112+
</tr>
113+
<tr>
114+
<td>2</td>
115+
<td>2015-05-02</td>
116+
<td>
117+
2015-04-29 sąskaita faktūra
118+
Serija VVP Nr. 2
119+
</td>
120+
<td>Gaunamos pajamos už:
121+
Svetainės programavimo darbai.
122+
123+
124+
</td>
125+
<td>150.00</td>
126+
<td></td>
127+
</tr>
128+
<tr>
129+
<td>3</td>
130+
<td>2015-05-02</td>
131+
<td>
132+
2015-06-26 sąskaita faktūra
133+
Serija VVP Nr. 3
134+
</td>
135+
<td>Gaunamos pajamos už:
136+
Svetainės programavimo darbai.
137+
138+
139+
</td>
140+
<td>360.00</td>
141+
<td></td>
142+
</tr>
143+
<tr>
144+
<td colspan="6"></td>
145+
</tr>
146+
<tr>
147+
<td></td>
148+
<td></td>
149+
<td></td>
150+
<td>Viso:</td>
151+
<td>690.00</td>
152+
<td>0</td>
153+
</tr>
154+
</table>
155+
</body>
156+
</html>
Binary file not shown.

0 commit comments

Comments
 (0)