Skip to content

Commit 31d6583

Browse files
committed
update
1 parent 0ab33a5 commit 31d6583

8 files changed

Lines changed: 326 additions & 20 deletions

File tree

src/onegov/pas/export_single_parliamentarian.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
LOHNART_ALLOWANCE_TEXT,
1818
PresidentialAllowance,
1919
)
20-
from onegov.pas.utils import is_commission_president
20+
from onegov.pas.utils import is_president_for_attendance
2121
from onegov.pas.utils import format_swiss_number
2222
from onegov.core.utils import module_path
2323
from weasyprint import HTML, CSS # type: ignore[import-untyped]
@@ -269,7 +269,7 @@ def _get_parliamentarian_settlement_data(
269269

270270
result = []
271271
for attendence in attendences:
272-
is_president = is_commission_president(
272+
is_president = is_president_for_attendance(
273273
parliamentarian, attendence, settlement_run
274274
)
275275
compensation = calculate_attendance_compensation(

src/onegov/pas/models/attendence.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,9 @@ def calculate_value(self) -> Decimal:
143143
raise ValueError('Duration cannot be negative')
144144

145145
if self.type == 'plenary':
146-
return Decimal(str(self.duration)) / Decimal('60')
146+
return (Decimal(str(self.duration)) / Decimal('60')).quantize(
147+
Decimal('0.01'), rounding=ROUND_HALF_UP
148+
)
147149

148150
if self.type in ('commission', 'study', 'shortest'):
149151
# Convert minutes to hours with Decimal for precise calculation

src/onegov/pas/utils.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,38 @@ def format_swiss_number(value: Decimal | int) -> str:
129129
return format_decimal(value, format='#,##0.00', locale='de_CH')
130130

131131

132+
def is_kantonsrat_president(
133+
parliamentarian: PASParliamentarian,
134+
on_date: date,
135+
) -> bool:
136+
"""The Kantonsratspräsidium is a role on the parliamentarian and not a
137+
commission membership.
138+
139+
"""
140+
return any(
141+
role.role == 'president'
142+
and _is_kantonsrat_role(role)
143+
and (role.start is None or role.start <= on_date)
144+
and (role.end is None or role.end >= on_date)
145+
for role in parliamentarian.roles
146+
)
147+
148+
149+
def is_president_for_attendance(
150+
parliamentarian: PASParliamentarian,
151+
attendance: Attendence,
152+
settlement_run: SettlementRun,
153+
) -> bool:
154+
"""Whether the president rate applies. A plenary session has no
155+
commission, there the Kantonsratspräsidium decides.
156+
157+
"""
158+
if attendance.type == 'plenary':
159+
return is_kantonsrat_president(parliamentarian, attendance.date)
160+
161+
return is_commission_president(parliamentarian, attendance, settlement_run)
162+
163+
132164
def is_commission_president(
133165
parliamentarian: PASParliamentarian,
134166
attendance_or_commission_id: Attendence | UUID,

src/onegov/pas/views/abschlussliste.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from __future__ import annotations
22
from collections import defaultdict
33
from io import BytesIO
4-
from decimal import Decimal, ROUND_HALF_UP
4+
from decimal import Decimal
55
from operator import itemgetter
66
import xlsxwriter
77

@@ -18,7 +18,7 @@
1818
LOHNART_ALLOWANCE_TEXT,
1919
)
2020
from onegov.pas.utils import get_parliamentarians_with_settlements
21-
from onegov.pas.utils import is_commission_president
21+
from onegov.pas.utils import is_president_for_attendance
2222
from onegov.pas.models.parliamentarian_role import PASParliamentarianRole
2323
from onegov.pas.models.party import Party
2424
from sqlalchemy import or_
@@ -133,7 +133,7 @@ def get_abschlussliste_data(
133133

134134
for att in attendances:
135135
p = att.parliamentarian
136-
is_president = is_commission_president(p, att, settlement_run)
136+
is_president = is_president_for_attendance(p, att, settlement_run)
137137
compensation = calculate_attendance_compensation(
138138
rate_set=rate_set,
139139
attendence_type=att.type,
@@ -252,7 +252,7 @@ def generate_abschlussliste_xlsx(
252252
for details_row_num, att in enumerate(attendances, start=1):
253253
p = att.parliamentarian
254254
party = details_party_lookup[str(p.id)]
255-
is_president = is_commission_president(p, att, settlement_run)
255+
is_president = is_president_for_attendance(p, att, settlement_run)
256256
compensation = calculate_attendance_compensation(
257257
rate_set=rate_set,
258258
attendence_type=att.type,
@@ -349,7 +349,7 @@ def generate_buchungen_abrechnungslauf_xlsx(
349349
party_name = party.name if party else ''
350350

351351
# Calculate rates
352-
is_president = is_commission_president(
352+
is_president = is_president_for_attendance(
353353
parliamentarian,
354354
att,
355355
settlement_run,
@@ -463,11 +463,7 @@ def generate_buchungen_abrechnungslauf_xlsx(
463463
worksheet.write(
464464
row_num,
465465
5,
466-
float(
467-
row_data['value'].quantize(
468-
Decimal('0.01'), rounding=ROUND_HALF_UP
469-
)
470-
),
466+
float(row_data['value']),
471467
cell_format,
472468
)
473469
worksheet.write(

src/onegov/pas/views/pas_excel_export_nr_3_lohnart_fibu.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
LOHNART_ALLOWANCE_NR,
1818
LOHNART_ALLOWANCE_TEXT,
1919
)
20-
from onegov.pas.utils import is_commission_president
20+
from onegov.pas.utils import is_president_for_attendance
2121

2222

2323
from typing import TYPE_CHECKING
@@ -111,7 +111,7 @@ def generate_fibu_export_rows(
111111
lohnart_nr = lohnart_info['nr']
112112
lohnart_text = lohnart_info['text']
113113

114-
is_president = is_commission_president(
114+
is_president = is_president_for_attendance(
115115
parliamentarian, attendance, settlement_run
116116
)
117117
compensation = calculate_attendance_compensation(

src/onegov/pas/views/settlement_run.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
get_parliamentarians_with_settlements,
4646
get_parties_with_settlements,
4747
is_commission_president,
48+
is_president_for_attendance,
4849
)
4950
from onegov.pas.views.abschlussliste import (
5051
generate_abschlussliste_xlsx,
@@ -541,13 +542,17 @@ def generate_settlement_pdf(
541542
else:
542543
raise ValueError(f'Unsupported entity type: {entity_type}')
543544

545+
# the Amtliche Mission belongs to the person, it shall only be listed
546+
# on the parliamentarian export and on the overview across all parties
544547
allowances = (
545548
PresidentialAllowanceCollection(
546549
request.session,
547550
settlement_run_id=settlement_run.id,
548551
)
549552
.query()
550553
.all()
554+
if entity_type == 'all'
555+
else []
551556
)
552557

553558
if allowances:
@@ -668,7 +673,8 @@ def _generate_settlement_html(
668673
<td>{settlement_row[0].strftime('%d.%m.%Y')}</td>
669674
<td>{name}</td>
670675
<td>{settlement_row[2]}</td>
671-
<td class="numeric">{settlement_row[3]}</td>
676+
<td class="numeric">{format_swiss_number(
677+
settlement_row[3])}</td>
672678
<td class="numeric">{format_swiss_number(
673679
settlement_row[4])}</td>
674680
<td class="numeric">{format_swiss_number(
@@ -759,7 +765,7 @@ def _get_data_export_all(
759765
settlement_data: list[SettlementDataRow] = []
760766

761767
for attendence in attendences.query():
762-
is_president = is_commission_president(
768+
is_president = is_president_for_attendance(
763769
attendence.parliamentarian, attendence, self
764770
)
765771

@@ -838,7 +844,7 @@ def _get_party_settlement_data(
838844
continue
839845

840846
# found an export
841-
is_president = is_commission_president(
847+
is_president = is_president_for_attendance(
842848
attendence.parliamentarian, attendence, settlement_run
843849
)
844850

0 commit comments

Comments
 (0)