18 Commits

15 changed files with 427 additions and 73 deletions

1
.gitignore vendored
View File

@ -3,6 +3,7 @@ ENV
api/config/dbconfig.ini api/config/dbconfig.ini
api/config/authservice.pub api/config/authservice.pub
cli/config/dbconfig.ini cli/config/dbconfig.ini
cli/output/
*~ *~
.*~ .*~
.vscode/ .vscode/

54
cli/AccountStatement.py Normal file
View File

@ -0,0 +1,54 @@
from db import dbGetMany, dbGetOne
from loguru import logger
import datetime
import iso8601
from utils import getParam
from Cheetah.Template import Template
def perform(dbh, params):
year = getParam(params, 'year', datetime.datetime.today().year)
accountEntries = dbGetMany(
dbh,
{
"statement": "SELECT * FROM account_statement_v WHERE fiscal_year = %(year)s",
"params": {
'year': year
}
}
)
overview = dbGetMany(
dbh,
{
"statement": "select sum(amount), category from account_statement_v where fiscal_year = %(year)s group by category",
"params": {
'year': year
}
}
)
sum_related = dbGetOne(
dbh,
{
"statement": "select coalesce(sum(amount), 0::numeric(10,2)) as sum from account_statement_v where fiscal_year = %(year)s and category != 'nicht abrechenbare Positionen'",
"params": {
'year': year
}
}
)
sum_unrelated = dbGetOne(
dbh,
{
"statement": "select coalesce(sum(amount), 0::numeric(10,2)) as sum from account_statement_v where fiscal_year = %(year)s and category = 'nicht abrechenbare Positionen'",
"params": {
'year': year
}
}
)
template = getParam(params, 'template', 'accountStatement.tmpl')
input = { 'year': year, 'entries': accountEntries, 'overview': overview, 'related': sum_related, 'unrelated': sum_unrelated }
tmpl = Template(file=template, searchList=[ input ])
print(tmpl)

51
cli/AccountStatement.sh Executable file
View File

@ -0,0 +1,51 @@
#!/bin/bash
SHOW="0"
PRINT="0"
while getopts "y:sphP:" flag
do
case "${flag}" in
h)
echo "y ... year for statement";
echo "s ... show output using evince";
echo "p ... print output";
echo "P ... printer name";
exit 1;
;;
y)
YEAR=${OPTARG}
;;
s)
SHOW="1"
;;
p)
PRINT="1"
;;
P)
PRINTER="-P ${OPTARG}"
;;
esac
done
if [ "$YEAR" = "" ]; then
echo "give year for statement as argument"
exit 1
fi
python3.10 hv2cli.py -o AccountStatement -p '{"year":'$YEAR'}' > ./output/$YEAR.tex
pushd ./output
pdflatex $YEAR.tex
pdflatex $YEAR.tex
pdflatex $YEAR.tex
if [ "$SHOW" = "1" ]; then
evince $YEAR.pdf
fi
if [ "$PRINT" = "1" ]; then
lpr $PRINTER $YEAR.pdf
fi
popd

View File

@ -23,7 +23,7 @@ def perform(dbh, params):
{ {
"statement": "statement":
""" """
select sum(ae.amount) as sum, select (coalesce(sum(ae.amount), 0::numeric(10,2)) * -1) as sum,
aec.description as category, aec.description as category,
aec.considerminusarea as considerminusarea aec.considerminusarea as considerminusarea
from account_t a, from account_t a,
@ -48,13 +48,13 @@ def perform(dbh, params):
where p.account = a.id and where p.account = a.id and
ae.account = a.id and ae.account = a.id and
aec.overhead_relevant = 't' and aec.overhead_relevant = 't' and
aec.id not in (select distinct account_entry_category from account_entry_t) and aec.id not in (select distinct account_entry_category from account_entry_t where fiscal_year = %(year)s) and
ae.fiscal_year = %(year)s and ae.fiscal_year = %(year)s and
p.id = %(premise)s p.id = %(premise)s
group by category, considerminusarea group by category, considerminusarea
union union
select 120 as sum, select 120 as sum,
'Waschmaschine' as category, '16. Waschmaschine' as category,
false as considerminusarea false as considerminusarea
from premise_t from premise_t
where id = %(premise)s where id = %(premise)s
@ -181,7 +181,7 @@ def perform(dbh, params):
for house in houses.values(): for house in houses.values():
logger.debug(f"Processing item: {house}") logger.debug(f"Processing item: {house}")
outputFile = f"{overviewPrefix}-{house['details']['id']}.{overviewSuffix}" outputFile = f"./output/{overviewPrefix}-{house['details']['id']}.{overviewSuffix}"
tmpl = Template(file=overviewTemplate, searchList=[ house ]) tmpl = Template(file=overviewTemplate, searchList=[ house ])
logger.debug(tmpl) logger.debug(tmpl)
with open(outputFile, 'w') as f: with open(outputFile, 'w') as f:
@ -301,7 +301,7 @@ def perform(dbh, params):
for letter in letters: for letter in letters:
logger.debug(f"Processing item: {letter}") logger.debug(f"Processing item: {letter}")
outputFile = f"{letterPrefix}-{letter['tenant']['tenant_id']}.{letterSuffix}" outputFile = f"./output/{letterPrefix}-{letter['tenant']['tenant_id']}.{letterSuffix}"
tmpl = Template(file=letterTemplate, searchList=[ letter ]) tmpl = Template(file=letterTemplate, searchList=[ letter ])
logger.debug(tmpl) logger.debug(tmpl)
with open(outputFile, 'w') as f: with open(outputFile, 'w') as f:

55
cli/OverheadAccounts.sh Executable file
View File

@ -0,0 +1,55 @@
#!/bin/bash
PRINT="0"
while getopts "y:phP:" flag
do
case "${flag}" in
h)
echo "y ... year for statement";
echo "p ... print output";
echo "P ... printer name";
exit 1;
;;
y)
YEAR=${OPTARG}
;;
p)
PRINT="1"
;;
P)
PRINTER="-P ${OPTARG}"
;;
esac
done
if [ "$YEAR" = "" ]; then
echo "give year for statement as argument"
exit 1
fi
python3.10 hv2cli.py -o OverheadAccounts -p '{"year":'$YEAR'}'
pushd ./output
for I in letter-*.tex; do
pdflatex $I
pdflatex $I
pdflatex $I
done
for I in overview-*.tex; do
pdflatex $I
pdflatex $I
pdflatex $I
done
if [ "$PRINT" = "1" ]; then
for I in letter-*.pdf; do
lpr $PRINTER $I
done
for I in overview-*.pdf; do
lpr $PRINTER $I
done
fi
popd

59
cli/accountStatement.tmpl Normal file
View File

@ -0,0 +1,59 @@
\documentclass[10pt]{article}
\usepackage{german}
\usepackage{eurosym}
\usepackage[a4paper, landscape=true, left=2cm, right=2cm, top=2cm]{geometry}
\usepackage{icomma}
\usepackage{longtable}
\usepackage{color}
\setlength{\parindent}{0pt}
\begin{document}
\subsection*{Account Statement $year}
\begin{longtable}{|r|r|p{6cm}|r|r|r|p{3cm}|r|p{5cm}|}
\hline \textcolor{blue}{\bf{ID}} & \textcolor{blue}{\bf{Date}} & \textcolor{blue}{\bf{Description}} & \textcolor{blue}{\bf{Amount}} & \textcolor{blue}{\bf{DocNo}} & \textcolor{blue}{\bf{Year}} & \textcolor{blue}{\bf{Category}} & \textcolor{blue}{\bf{IsRef}} & \textcolor{blue}{\bf{BaseAccount}} \\ \hline \hline
\endfirsthead
\hline \textcolor{blue}{\bf{ID}} & \textcolor{blue}{\bf{Date}} & \textcolor{blue}{\bf{Description}} & \textcolor{blue}{\bf{Amount}} & \textcolor{blue}{\bf{DocNo}} & \textcolor{blue}{\bf{Year}} & \textcolor{blue}{\bf{Category}} & \textcolor{blue}{\bf{IsRef}} & \textcolor{blue}{\bf{BaseAccount}} \\ \hline \hline
\endhead
\multicolumn{9}{r}{\em{to be continued}}
\endfoot
\endlastfoot
#for $entry in $entries
\tt{$entry['id']} & \tt{$entry['created_at']} & \tt{$entry['description']} & #slurp
#if $entry['amount'] <= 0
\textcolor{red}{#slurp
#end if
\tt{$entry['amount']} \,\euro{}#slurp
#if $entry['amount'] <= 0
}#slurp
#end if
& \tt{$entry['document_no']} & \tt{$entry['fiscal_year']} & \tt{$entry['category']} & \tt{$entry['is_reference']} & \tt{{$entry['base_account'].replace('_', ' ') }} \\ \hline
#end for
\end{longtable}
\pagebreak
\subsection*{Overviews}
\begin{tabular}{|l|r|} \hline
\hline \textcolor{blue}{\bf{category}} & \textcolor{blue}{\bf{sum}} \\
#for $entry in $overview
\hline \tt{$entry['category']} & #slurp
#if $entry['sum'] <= 0
\textcolor{red}{#slurp
#end if
\tt{$entry['sum']} \,\euro{}#slurp
#if $entry['sum'] <= 0
}#slurp
#end if
\\
#end for
\hline \hline related & \tt{$related['sum']} \,\euro{} \\
\hline unrelated & \tt{$unrelated['sum']} \,\euro{} \\
\hline \hline
\end{tabular}
\end{document}

View File

@ -1,4 +1,5 @@
\documentclass[12pt]{article} \documentclass[12pt]{article}
\renewcommand{\familydefault}{\sfdefault}
\usepackage{german} \usepackage{german}
\usepackage{eurosym} \usepackage{eurosym}
\usepackage[a4paper, left=2cm, right=2cm, top=2cm]{geometry} \usepackage[a4paper, left=2cm, right=2cm, top=2cm]{geometry}
@ -7,8 +8,10 @@
\begin{document} \begin{document}
\subsection*{Betriebskostenabrechnung} \subsection*{Aufstellung}
über die Ermittlung der Betriebskosten gemäß §27 II. BV
\vspace{15mm}
\begin{tabular}{ll} \begin{tabular}{ll}
Objekt & $details['description'] \\ Objekt & $details['description'] \\
@ -18,23 +21,25 @@ Eigent"umer & Nober Grundbesitz GmbH \\
\addvspace{1cm} \addvspace{1cm}
\begin{tabular}{|p{5cm}|r|r|r|} \begin{tabular}{|p{7cm}|r|r|r|}
\hline Art & Wohnungen & andere Fl"achen & Gesamtfl"ache \\ \hline Art & Wohnungen & andere Fl"achen & Gesamtfl"ache \\
\hline \hline
\hline Fl"ache & \tt{$areas['flat_area']\,m\textsuperscript{2}} & \tt{$areas['other_area']\,m\textsuperscript{2}} & \tt{$areas['total_area']\,m\textsuperscript{2}} \\ \hline Fl"ache & \tt{$areas['flat_area']\,m\textsuperscript{2}} & \tt{$areas['other_area']\,m\textsuperscript{2}} & \tt{$areas['total_area']\,m\textsuperscript{2}} \\
\hline Faktor & \tt{#echo '%.10f' % $areas['flat_factor'] #} & \tt{#echo '%.10f' % $areas['other_factor'] #} & \\ \hline Faktor & \tt{#echo '%.10f' % $areas['flat_factor'] #} & \tt{#echo '%.10f' % $areas['other_factor'] #} & \\
\hline \hline \hline
#for $item in $overhead_items #for $item in $overhead_items
\hline $item['category'] & \tt{#echo '%.2f' % $item['flat_part'] #\,\euro{}} & \tt{#echo '%.2f' % $item['other_part'] #\,\euro{}} & \tt{#echo '%.2f' % $item['sum'] #\,\euro{}} \\ \hline $item['category'] & \tt{#echo '%.2f' % $item['flat_part'] #\,\euro{}} & \tt{#echo '%.2f' % $item['other_part'] #\,\euro{}} & \tt{#echo '%.2f' % $item['sum'] #\,\euro{}} \\
#end for #end for
\hline \multicolumn{4}{c}{ } \\ \hline
% \hline \multicolumn{4}{c}{ } \\
\hline Zwischensumme & \tt{#echo '%.2f' % $flat_sum #\,\euro{}} & \tt{#echo '%.2f' % $other_sum #\,\euro{}} & \tt{#echo '%.2f' % $total_sum #\,\euro{}} \\ \hline Zwischensumme & \tt{#echo '%.2f' % $flat_sum #\,\euro{}} & \tt{#echo '%.2f' % $other_sum #\,\euro{}} & \tt{#echo '%.2f' % $total_sum #\,\euro{}} \\
\hline Umlageausfallwagnis & \tt{#echo '%.2f' % $umlage_ausfall_wagnis #\,\euro{}} & & \\ \hline Umlageausfallwagnis & \tt{#echo '%.2f' % $umlage_ausfall_wagnis #\,\euro{}} & & \\
\hline Summe & \tt{#echo '%.2f' % $flat_sum_2 #\,\euro{}} & & \\ \hline Summe & \tt{#echo '%.2f' % $flat_sum_2 #\,\euro{}} & & \\
\hline \multicolumn{4}{c}{ } \\ \hline
% \hline \multicolumn{4}{c}{ } \\
\hline Anteil pro Monat und m\textsuperscript{2} & \tt{#echo '%.10f' % $part_by_montharea #\,\euro{}} & & \\ \hline Anteil pro Monat und m\textsuperscript{2} & \tt{#echo '%.10f' % $part_by_montharea #\,\euro{}} & & \\
\hline \hline
\end{tabular} \end{tabular}

View File

@ -0,0 +1,23 @@
create or replace view account_statement_v as
select ae.id as id,
ae.description as description,
ae.created_at::timestamp::date as created_at,
ae.amount as amount,
ae.document_no as document_no,
ae.fiscal_year as fiscal_year,
aec.description as category,
ac.description as account,
ae.is_reference as is_reference,
bac.description as base_account
from joined_account_entry_v ae,
account_entry_category_t aec,
account_t ac,
account_t bac
where ae.account_entry_category = aec.id and
ae.account = ac.id and
ae.base_account = bac.id and
ac.id = 1000
order by created_at;
grant select on account_statement_v to hv2;

126
schema/changes02.sql Normal file
View File

@ -0,0 +1,126 @@
CREATE TABLE account_entry_reference_t (
id serial not null primary key,
account integer not null references account_t (id),
account_entry integer not null references account_entry_t (id)
);
CREATE OR REPLACE VIEW joined_account_entry_v AS
SELECT ae.id as id,
ae.description as description,
ae.account as account,
ae.created_at as created_at,
ae.amount as amount,
ae.account_entry_category as account_entry_category,
ae.document_no as document_no,
ae.fiscal_year as fiscal_year,
false as is_reference,
0 as base_account
FROM account_entry_t ae
UNION
SELECT ae.id as id,
ae.description as description,
aer.account as account,
ae.created_at as created_at,
ae.amount as amount,
ae.account_entry_category as account_entry_category,
ae.document_no as document_no,
ae.fiscal_year as fiscal_year,
true as is_reference,
ae.account as base_account
FROM account_entry_t ae,
account_entry_reference_t aer
WHERE ae.id = aer.account_entry;
update account_t set description = 'fallback_account' where id = 33;
delete from account_t where id = 32;
insert into account_t (id, description) values (1000, 'ledger');
update account_entry_t set amount = amount * -1.0 where account=33;
update account_entry_t set amount = amount * -1.0 where account in (34,35,36,37);
DO $$
DECLARE
entry_id integer;
BEGIN
RAISE NOTICE 'Start migration';
FOR entry_id IN
SELECT id
FROM account_entry_t
WHERE account IN (33,34,35,36,37)
LOOP
RAISE NOTICE 'About to migrate entry %', entry_id;
INSERT INTO account_entry_reference_t (account, account_entry) VALUES (1000, entry_id);
END LOOP;
END;
$$;
update account_entry_t
set description = 'Miete ' || extract(year from created_at)::text || ' ' || to_char(to_date(extract(month from created_at)::text, 'MM'), 'Month')
where account_entry_category = 2 and description = 'Miete';
DO $$
DECLARE
entry RECORD;
tenant RECORD;
BEGIN
RAISE NOTICE 'Start migration of tenant accounts';
FOR entry IN
SELECT id, description, account
FROM account_entry_t
WHERE account_entry_category = 2
LOOP
RAISE NOTICE 'About to migrate entry %', entry.id;
INSERT INTO account_entry_reference_t (account, account_entry) VALUES (1000, entry.id);
SELECT *
INTO tenant
FROM tenant_t
WHERE account = entry.account;
RAISE NOTICE 'Tenant: % %', tenant.firstname, tenant.lastname;
UPDATE account_entry_t
SET description = description || ' ' || tenant.firstname || ' ' || tenant.lastname
WHERE id = entry.id;
END LOOP;
END;
$$;
CREATE OR REPLACE FUNCTION maintain_ledger()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
DECLARE
tenant RECORD;
adjusted_description text;
BEGIN
IF ((NEW.description = 'Miete') AND (NEW.account_entry_category = 2)) THEN
SELECT firstname, lastname
INTO tenant
FROM tenant_t
WHERE account = NEW.account;
adjusted_description := 'Miete ' || extract(year from NEW.created_at)::text || ' ' || to_char(to_date(extract(month from NEW.created_at)::text, 'MM'), 'Month') || tenant.firstname || ' ' || tenant.lastname;
UPDATE account_entry_t
SET description = adjusted_description
WHERE id = NEW.id;
END IF;
INSERT INTO account_entry_reference_t (account, account_entry) VALUES (1000, NEW.id);
RETURN NEW;
END;
$$;
CREATE TRIGGER maintain_ledger_trigger
AFTER INSERT ON account_entry_t
FOR EACH ROW
WHEN (NEW.account != 1000 AND NEW.account_entry_category NOT IN (3, 4, 29))
EXECUTE FUNCTION maintain_ledger();
grant select, update on account_entry_reference_t_id_seq to hv2;
grant insert on account_entry_reference_t to hv2;
grant update on account_entry_t to hv2;

View File

@ -10,9 +10,9 @@
<mat-label>Jahr</mat-label> <mat-label>Jahr</mat-label>
<input matInput type="number" name="fiscalYear" [formControl]="presetFiscalYear" ngModel/> <input matInput type="number" name="fiscalYear" [formControl]="presetFiscalYear" ngModel/>
</mat-form-field> </mat-form-field>
<mat-form-field appearance="outline" *ngIf="!shallBeRentPayment"> <mat-form-field appearance="outline">
<mat-label>Kategorie</mat-label> <mat-label>Kategorie</mat-label>
<mat-select ngModel name="category" [disabled]="shallBeRentPayment"> <mat-select ngModel name="category" [formControl]="presetCategory" >
<mat-option *ngFor="let p of accountEntryCategories" [value]="p.id">{{p.description}}</mat-option> <mat-option *ngFor="let p of accountEntryCategories" [value]="p.id">{{p.description}}</mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
@ -20,9 +20,9 @@
<mat-label>Betrag (€)</mat-label> <mat-label>Betrag (€)</mat-label>
<input matInput type="number" name="amount" ngModel/> <input matInput type="number" name="amount" ngModel/>
</mat-form-field> </mat-form-field>
<mat-form-field appearance="outline" *ngIf="!shallBeRentPayment"> <mat-form-field appearance="outline">
<mat-label>Beschreibung</mat-label> <mat-label>Beschreibung</mat-label>
<input matInput name="description" [disabled]="shallBeRentPayment" ngModel/> <input matInput name="description" [formControl]="presetDescription" ngModel/>
</mat-form-field> </mat-form-field>
<button #addAccountEntryButton type="submit" mat-raised-button color="primary">Buchung speichern</button> <button #addAccountEntryButton type="submit" mat-raised-button color="primary">Buchung speichern</button>
</form> </form>
@ -33,11 +33,11 @@ Saldo: {{saldo?.saldo | number:'1.2-2'}} €
<div id="secondBlock"> <div id="secondBlock">
<table mat-table [dataSource]="accountEntriesDataSource" #zftable> <table mat-table [dataSource]="accountEntriesDataSource" #zftable>
<ng-container matColumnDef="createdAt"> <ng-container matColumnDef="createdAt">
<th mat-header-cell *matHeaderCellDef>Datum</th> <th mat-header-cell *matHeaderCellDef >Datum</th>
<td mat-cell *matCellDef="let element">{{element.rawAccountEntry.created_at | date}}</td> <td mat-cell *matCellDef="let element">{{element.rawAccountEntry.created_at | date}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="fiscalYear"> <ng-container matColumnDef="fiscalYear">
<th mat-header-cell *matHeaderCellDef>Jahr</th> <th mat-header-cell *matHeaderCellDef >Jahr</th>
<td mat-cell *matCellDef="let element">{{element.rawAccountEntry.fiscal_year}}</td> <td mat-cell *matCellDef="let element">{{element.rawAccountEntry.fiscal_year}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="description"> <ng-container matColumnDef="description">
@ -45,7 +45,7 @@ Saldo: {{saldo?.saldo | number:'1.2-2'}} €
<td mat-cell *matCellDef="let element">{{element.rawAccountEntry.description}}</td> <td mat-cell *matCellDef="let element">{{element.rawAccountEntry.description}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="document_no"> <ng-container matColumnDef="document_no">
<th mat-header-cell *matHeaderCellDef>Belegnummer</th> <th mat-header-cell *matHeaderCellDef >Belegnummer</th>
<td mat-cell *matCellDef="let element">{{element.rawAccountEntry.document_no}}</td> <td mat-cell *matCellDef="let element">{{element.rawAccountEntry.document_no}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="amount"> <ng-container matColumnDef="amount">
@ -53,11 +53,11 @@ Saldo: {{saldo?.saldo | number:'1.2-2'}} €
<td mat-cell *matCellDef="let element" class="rightaligned">{{element.rawAccountEntry.amount | number:'1.2-2'}} €</td> <td mat-cell *matCellDef="let element" class="rightaligned">{{element.rawAccountEntry.amount | number:'1.2-2'}} €</td>
</ng-container> </ng-container>
<ng-container matColumnDef="category"> <ng-container matColumnDef="category">
<th mat-header-cell *matHeaderCellDef>Kategorie</th> <th mat-header-cell *matHeaderCellDef >Kategorie</th>
<td mat-cell *matCellDef="let element">{{element.accountEntryCategory}}</td> <td mat-cell *matCellDef="let element">{{element.accountEntryCategory}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="overhead_relevant"> <ng-container matColumnDef="overhead_relevant">
<th mat-header-cell *matHeaderCellDef>BK relevant</th> <th mat-header-cell *matHeaderCellDef >BK relevant</th>
<td mat-cell *matCellDef="let element">{{element.overheadRelevant}}</td> <td mat-cell *matCellDef="let element">{{element.overheadRelevant}}</td>
</ng-container> </ng-container>
<tr mat-header-row *matHeaderRowDef="accountEntriesDisplayedColumns"></tr> <tr mat-header-row *matHeaderRowDef="accountEntriesDisplayedColumns"></tr>

View File

@ -31,6 +31,7 @@ export class AccountComponent implements OnInit {
@Input() shallBeRentPayment: boolean @Input() shallBeRentPayment: boolean
@ViewChild('addAccountEntryButton') addAccountEntryButton: MatButton @ViewChild('addAccountEntryButton') addAccountEntryButton: MatButton
account: Account account: Account
accountEntries: DN_AccountEntry[] accountEntries: DN_AccountEntry[]
accountEntriesDataSource: MatTableDataSource<DN_AccountEntry> accountEntriesDataSource: MatTableDataSource<DN_AccountEntry>
@ -42,6 +43,8 @@ export class AccountComponent implements OnInit {
accountEntryCategoriesInverseMap: Map<string, AccountEntryCategory> accountEntryCategoriesInverseMap: Map<string, AccountEntryCategory>
presetFiscalYear: FormControl presetFiscalYear: FormControl
presetCategory: FormControl
presetDescription: FormControl
constructor( constructor(
private accountService: AccountService, private accountService: AccountService,
@ -96,23 +99,14 @@ export class AccountComponent implements OnInit {
let uniquenumber: UniqueNumber = await this.extApiService.getUniqueNumber(); let uniquenumber: UniqueNumber = await this.extApiService.getUniqueNumber();
this.messageService.add(`Got unique number as document_no: ${uniquenumber.number}`) this.messageService.add(`Got unique number as document_no: ${uniquenumber.number}`)
let newAccountEntry: AccountEntry = { let newAccountEntry: AccountEntry = {
description: formData.value.description, description: this.presetDescription.value,
account: this.account.id, account: this.account.id,
created_at: formData.value.createdAt, created_at: formData.value.createdAt,
fiscal_year: this.presetFiscalYear.value, fiscal_year: this.presetFiscalYear.value,
amount: formData.value.amount, amount: formData.value.amount,
id: 0, id: 0,
document_no: uniquenumber.number, document_no: uniquenumber.number,
account_entry_category: 0 account_entry_category: this.presetCategory.value
}
if (this.shallBeRentPayment) {
newAccountEntry.account_entry_category = this.accountEntryCategoriesInverseMap.get('Mietzahlung').id
newAccountEntry.description = "Miete"
this.messageService.add(`shall be rentpayment, category is ${newAccountEntry.account_entry_category}`)
} else {
newAccountEntry.account_entry_category = formData.value.category
this.messageService.add(`category is ${newAccountEntry.account_entry_category}`)
} }
this.messageService.add(`addAccountEntry: ${ JSON.stringify(newAccountEntry, undefined, 4) }`) this.messageService.add(`addAccountEntry: ${ JSON.stringify(newAccountEntry, undefined, 4) }`)
@ -146,12 +140,28 @@ export class AccountComponent implements OnInit {
} }
private async init(): Promise<void> { private async init(): Promise<void> {
this.messageService.add(`AccountComponent.init start, account: ${this.selectedAccountId}`)
let currentDate = new Date() let currentDate = new Date()
let y = currentDate.getFullYear().toString() let y = currentDate.getFullYear()
this.presetFiscalYear = new FormControl(y) this.presetFiscalYear = new FormControl(y)
this.messageService.add(`AccountComponent.init a, account: ${this.selectedAccountId}`)
await this.getAccountEntryCategories()
if (this.shallBeRentPayment) {
this.messageService.add(`AccountComponent.init b, account: ${this.selectedAccountId}`)
this.presetCategory = new FormControl(this.accountEntryCategoriesInverseMap.get('Mietzahlung').id)
this.messageService.add(`AccountComponent.init c, account: ${this.selectedAccountId}`)
this.presetDescription = new FormControl("Miete")
this.messageService.add(`shall be rentpayment`)
this.messageService.add(`AccountComponent.init d, account: ${this.selectedAccountId}`)
} else {
this.presetCategory = new FormControl()
this.presetDescription = new FormControl()
}
this.messageService.add(`AccountComponent.init, account: ${this.selectedAccountId}`) this.messageService.add(`AccountComponent.init, account: ${this.selectedAccountId}`)
this.getAccount() this.getAccount()
await this.getAccountEntryCategories()
} }
@ -163,5 +173,4 @@ export class AccountComponent implements OnInit {
this.init() this.init()
} }
} }

View File

@ -50,6 +50,7 @@ import { EnterPaymentComponent } from './enter-payment/enter-payment.component';
import { HomeComponent } from './home/home.component'; import { HomeComponent } from './home/home.component';
import { LedgerComponent } from './ledger/ledger.component'; import { LedgerComponent } from './ledger/ledger.component';
import { ErrorDialogComponent } from './error-dialog/error-dialog.component' import { ErrorDialogComponent } from './error-dialog/error-dialog.component'
import { MatSortModule } from '@angular/material/sort';
registerLocaleData(localeDe) registerLocaleData(localeDe)
@ -102,7 +103,8 @@ registerLocaleData(localeDe)
MatSelectModule, MatSelectModule,
MatDatepickerModule, MatDatepickerModule,
MatNativeDateModule, MatNativeDateModule,
MatExpansionModule MatExpansionModule,
MatSortModule
], ],
exports: [ exports: [
MatMomentDateModule MatMomentDateModule

View File

@ -1,5 +1,5 @@
export const serviceBaseUrl = "https://api.hv.nober.de"; export const serviceBaseUrl = "https://api.hv.nober.de";
// export const serviceBaseUrl = "http://172.16.10.38:5000"; // export const serviceBaseUrl = "http://172.16.3.96:8080";
// export const serviceBaseUrl = "http://localhost:8080" // export const serviceBaseUrl = "http://localhost:8080"
export const authserviceBaseUrl = "https://authservice.hottis.de" export const authserviceBaseUrl = "https://authservice.hottis.de"
export const applicationId = "hv2" export const applicationId = "hv2"

View File

@ -5,30 +5,6 @@
</mat-card-title> </mat-card-title>
</mat-card-header> </mat-card-header>
<mat-card-content> <mat-card-content>
<mat-accordion> <app-account #fallbackAccountComponent [selectedAccountId]="fallbackAccountId" [shallBeRentPayment]="false"></app-account>
<mat-expansion-panel (opened)="collapseExpenseDetails = true"
(closed)="collapseExpenseDetails = false">
<mat-expansion-panel-header>
<mat-panel-title>
Ausgaben
</mat-panel-title>
<mat-panel-description>
<div>Betriebskosten-relevante Ausgaben nicht hier sondern im Betriebskostenkonto unter "Meine Häuser" erfassen.</div>
</mat-panel-description>
</mat-expansion-panel-header>
<app-account #expenseAccountComponent [selectedAccountId]="expenseAccountId" [shallBeRentPayment]="false"></app-account>
</mat-expansion-panel>
<mat-expansion-panel (opened)="collapseIncomeDetails = true"
(closed)="collapseIncomeDetails = false">
<mat-expansion-panel-header>
<mat-panel-title>
Einnahmen
</mat-panel-title>
<mat-panel-description>
</mat-panel-description>
</mat-expansion-panel-header>
<app-account #incomeAccountComponent [selectedAccountId]="incomeAccountId" [shallBeRentPayment]="false"></app-account>
</mat-expansion-panel>
</mat-accordion>
</mat-card-content> </mat-card-content>
</mat-card> </mat-card>

View File

@ -11,16 +11,11 @@ import { MessageService } from '../message.service';
}) })
export class LedgerComponent implements OnInit { export class LedgerComponent implements OnInit {
incomeAccount: Account fallbackAccount: Account
incomeAccountId: number fallbackAccountId: number
expenseAccount: Account
expenseAccountId: number
collapseIncomeDetails: boolean = false
collapseExpenseDetails: boolean = false
@ViewChild('incomeAccountComponent') incomeAccountComponent: AccountComponent @ViewChild('fallbackAccountComponent') fallbackAccountComponent: AccountComponent
@ViewChild('expenseAccountComponent') expenseAccountComponent: AccountComponent
constructor( constructor(
@ -30,9 +25,8 @@ export class LedgerComponent implements OnInit {
async getAccount(): Promise<void> { async getAccount(): Promise<void> {
try { try {
this.messageService.add("Trying to load ledger account") this.messageService.add("Trying to load fallback account")
this.incomeAccount = await this.extApiService.getAccountByDescription('LedgerIncome') this.fallbackAccount = await this.extApiService.getAccountByDescription('fallback_account')
this.expenseAccount = await this.extApiService.getAccountByDescription('LedgerExpense')
this.messageService.add("Account loaded") this.messageService.add("Account loaded")
} catch (err) { } catch (err) {
this.messageService.add(JSON.stringify(err, undefined, 4)) this.messageService.add(JSON.stringify(err, undefined, 4))
@ -41,8 +35,7 @@ export class LedgerComponent implements OnInit {
async ngOnInit(): Promise<void> { async ngOnInit(): Promise<void> {
await this.getAccount() await this.getAccount()
this.incomeAccountId = this.incomeAccount.id this.fallbackAccountId = this.fallbackAccount.id
this.expenseAccountId = this.expenseAccount.id
} }
} }