Merge pull request 'Fix #76: Klassen der Splitzeilen in der Klassenspalte des Kontoblatts' (#88) from fds2610-bot/Finanzmanager:main into main
Reviewed-on: https://codeberg.org/fds2610/Finanzmanager/pulls/88
This commit is contained in:
commit
6f29e4644f
7 changed files with 337 additions and 15 deletions
13
Changes.md
13
Changes.md
|
|
@ -1,5 +1,18 @@
|
|||
# Änderungen
|
||||
|
||||
## Kontoblatt: Klassen der Splitzeilen in der Klassenspalte (28.09.2026)
|
||||
|
||||
Die Klassenspalte des Kontoblatts zeigte bei einer Splitbuchung nur die Klasse der Buchung
|
||||
selbst, nicht die ihrer Splitzeilen (#76).
|
||||
|
||||
- Neu `Buchung::splitKlasse()`: Tragen alle Splitzeilen dieselbe Klasse, steht sie in der
|
||||
Spalte. Unterscheiden sie sich, steht dort die Marke *Splitbuchung*, der Tooltip nennt je
|
||||
Splitzeile Kategorie und Klasse. Ohne Klasse in den Zeilen bleibt es bei der Klasse der
|
||||
Buchung.
|
||||
- Ein Klick auf die Klassenzelle einer Splitbuchung öffnet den Splitdialog, in dem die
|
||||
Klassen der Zeilen geändert werden.
|
||||
- Neuer Test `tests/47_SplitKlasseTest.php`, E2E-Prüfung in `buchungen.spec.js`.
|
||||
|
||||
## Online-Banking: Alle Umsätze abrufen (28.09.2026)
|
||||
|
||||
Über der Tabelle der Bankverbindungen steht ein Knopf *Alle Umsätze abrufen*, der jede
|
||||
|
|
|
|||
|
|
@ -140,6 +140,14 @@ Auswertungsdimension. Anders als `Buchung::zuordnen()` rührt `klasseSetzen()` d
|
|||
Kategorie noch Gegenkonto noch Splitzeilen an – auch eine gesplittete Buchung bleibt beim
|
||||
Wechsel der Klasse gesplittet. Den Monatsabschluss achtet die Methode wie alle anderen.
|
||||
|
||||
Bei einer **Splitbuchung** zählen die Klassen ihrer Zeilen (`Buchung::splitKlasse()`):
|
||||
Tragen alle Zeilen dieselbe Klasse, steht sie in der Spalte; unterscheiden sie sich – eine
|
||||
Zeile ohne Klasse zählt dabei als eigene Angabe –, steht dort die Marke *Splitbuchung*, und
|
||||
der Tooltip nennt je Zeile Kategorie (oder Gegenkonto) und Klasse. Hat keine Zeile eine
|
||||
Klasse, bleibt es bei der Klasse der Buchung selbst. Ein Klick auf die Klassenzelle einer
|
||||
Splitbuchung öffnet den Splitdialog statt der Klassenliste (`data-split`): Dort stehen ihre
|
||||
Klassen.
|
||||
|
||||
## Zeilenhöhe und Tooltips im Kontoblatt
|
||||
|
||||
Jede Buchungszeile ist **zwei Textzeilen hoch**, gleich wie viel in ihr steht, und ihr
|
||||
|
|
@ -161,8 +169,8 @@ Den vollständigen Text zeigt der Tooltip:
|
|||
Fensterbreite. Ein Tooltip, der bloß wiederholt, was ohnehin dasteht, wäre lästig.
|
||||
* **Kategorie und Klasse** tragen ihren Tooltip vom Server. Bei einer **Splitbuchung** nennt
|
||||
er die Zeilen der Aufteilung: je Zeile Kategorie (oder Gegenkonto) und Betrag, sonst
|
||||
nichts. Notiz und Klasse stünden nur im Weg; wer sie ändern will, öffnet ohnehin den
|
||||
Dialog.
|
||||
nichts. Notiz und Klasse stünden nur im Weg; die Klassen nennt bei verschiedenen Klassen
|
||||
der Tooltip der Klassenspalte (siehe oben).
|
||||
|
||||
## Splitbuchungen
|
||||
|
||||
|
|
|
|||
|
|
@ -151,6 +151,15 @@
|
|||
const klassenfeld = klassenauswahl && ereignis.target.closest('a.klassenfeld');
|
||||
if (klassenfeld) {
|
||||
ereignis.preventDefault();
|
||||
// Die Klassen einer Splitbuchung stehen an ihren Zeilen – der Klick
|
||||
// führt deshalb in den Splitdialog, nicht in die Klassenliste.
|
||||
const splitfeld = klassenfeld.dataset.split
|
||||
? klassenfeld.closest('tr').querySelector('a.zuordnungsfeld[data-splits]')
|
||||
: null;
|
||||
if (splitfeld) {
|
||||
splitOeffnen(splitfeld);
|
||||
return;
|
||||
}
|
||||
const klasse = klassenfeld.dataset.klasse || '';
|
||||
oeffnen(klassenfeld, klassenauswahl, 'klasse', klasse === '0' ? '' : klasse);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -221,6 +221,32 @@ class Buchung
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Klasse, die das Kontoblatt für eine Splitbuchung zeigt. Tragen alle
|
||||
* Splitzeilen dieselbe Klasse, gilt sie für die ganze Buchung; unterscheiden
|
||||
* sie sich, ist die Buchung gemischt und die Spalte zeigt „Splitbuchung“.
|
||||
* Eine Zeile ohne Klasse zählt dabei als eigene Angabe. Hat keine Zeile eine
|
||||
* Klasse, bleibt es bei der Klasse der Buchung selbst – so zeigen ältere
|
||||
* Splitbuchungen weiter, was an ihnen steht.
|
||||
*
|
||||
* @param list<array<string,mixed>> $splitzeilen
|
||||
* @return array{gemischt: bool, klasse_id: ?int}
|
||||
*/
|
||||
public static function splitKlasse(array $splitzeilen, ?int $eigeneKlasse): array
|
||||
{
|
||||
$klassen = [];
|
||||
foreach ($splitzeilen as $zeile) {
|
||||
$klassen[(int)($zeile['klasse_id'] ?? 0)] = true;
|
||||
}
|
||||
|
||||
if (count($klassen) > 1) {
|
||||
return ['gemischt' => true, 'klasse_id' => null];
|
||||
}
|
||||
|
||||
$klasse = (int)array_key_first($klassen);
|
||||
return ['gemischt' => false, 'klasse_id' => $klasse > 0 ? $klasse : $eigeneKlasse];
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Splitzeilen einer Buchung ersetzen – der Splitdialog des Kontoblatts.
|
||||
* Eine leere Liste hebt die Splitbuchung auf; die Buchung steht danach ohne
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
use Finanzmanager\Models\Adresse;
|
||||
use Finanzmanager\Models\Buchung;
|
||||
use Finanzmanager\Models\Wertpapier;
|
||||
use Finanzmanager\View;
|
||||
|
||||
|
|
@ -89,19 +90,36 @@ $splitdaten = static function (array $splitzeilen) use ($zuordnungswert): string
|
|||
/**
|
||||
* Der Tooltip einer Splitbuchung: je Zeile Kategorie und Betrag. In der Spalte
|
||||
* steht nur „Splitbuchung“ – wohin das Geld geht, wäre sonst erst im Dialog zu
|
||||
* sehen. Notiz und Klasse bleiben draußen; sie stünden im Weg.
|
||||
* sehen. Notiz und Klasse bleiben draußen; die Klassen nennt die Klassenspalte.
|
||||
*
|
||||
* @param list<array<string,mixed>> $splitzeilen
|
||||
*/
|
||||
$splituebersicht = static function (array $splitzeilen) use ($kategorieNamen, $kontenNamen): string {
|
||||
$splitname = static fn(array $zeile): string => match (true) {
|
||||
!empty($zeile['gegenkonto_id']) => '[' . ($kontenNamen[(int)$zeile['gegenkonto_id']] ?? '?') . ']',
|
||||
!empty($zeile['kategorie_id']) => (string)($kategorieNamen[(int)$zeile['kategorie_id']] ?? '?'),
|
||||
default => '(ohne Kategorie)',
|
||||
};
|
||||
|
||||
$splituebersicht = static function (array $splitzeilen) use ($splitname): string {
|
||||
$texte = [];
|
||||
foreach ($splitzeilen as $zeile) {
|
||||
$name = match (true) {
|
||||
!empty($zeile['gegenkonto_id']) => '[' . ($kontenNamen[(int)$zeile['gegenkonto_id']] ?? '?') . ']',
|
||||
!empty($zeile['kategorie_id']) => (string)($kategorieNamen[(int)$zeile['kategorie_id']] ?? '?'),
|
||||
default => '(ohne Kategorie)',
|
||||
};
|
||||
$texte[] = $name . ': ' . View::betrag($zeile['betrag']);
|
||||
$texte[] = $splitname($zeile) . ': ' . View::betrag($zeile['betrag']);
|
||||
}
|
||||
|
||||
return implode("\n", $texte);
|
||||
};
|
||||
|
||||
/**
|
||||
* Der Tooltip der Klassenspalte, wenn die Splitzeilen verschiedene Klassen
|
||||
* tragen: je Zeile Kategorie und Klasse.
|
||||
*
|
||||
* @param list<array<string,mixed>> $splitzeilen
|
||||
*/
|
||||
$splitklassen = static function (array $splitzeilen) use ($splitname, $klassenNamen): string {
|
||||
$texte = [];
|
||||
foreach ($splitzeilen as $zeile) {
|
||||
$texte[] = $splitname($zeile) . ': '
|
||||
. (string)($klassenNamen[(int)($zeile['klasse_id'] ?? 0)] ?? '(ohne Klasse)');
|
||||
}
|
||||
|
||||
return implode("\n", $texte);
|
||||
|
|
@ -358,19 +376,39 @@ include __DIR__ . '/../layout/kopf.php';
|
|||
</a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<?php $klassenname = (string)($klassenNamen[(int)$zeile['klasse_id']] ?? ''); ?>
|
||||
<?php
|
||||
// Bei einer Splitbuchung zählen die Klassen ihrer Zeilen – wie
|
||||
// bei der Kategorie: eine gemeinsame Klasse steht in der
|
||||
// Spalte, verschiedene nennt der Tooltip der Marke.
|
||||
$splitzeilen = !$zeile['gegensicht'] ? ($splits[(int)$zeile['id']] ?? null) : null;
|
||||
$klasse = $splitzeilen !== null
|
||||
? Buchung::splitKlasse($splitzeilen, $zeile['klasse_id'] !== null ? (int)$zeile['klasse_id'] : null)
|
||||
: ['gemischt' => false, 'klasse_id' => (int)$zeile['klasse_id']];
|
||||
$klassenname = (string)($klassenNamen[(int)$klasse['klasse_id']] ?? '');
|
||||
$klassentitel = match (true) {
|
||||
$klasse['gemischt'] => $splitklassen($splitzeilen),
|
||||
$klassenname !== '' => $klassenname,
|
||||
default => 'Klasse zuordnen',
|
||||
};
|
||||
?>
|
||||
<td class="klassenzelle nebentext">
|
||||
<?php if ($zeile['gegensicht']): ?>
|
||||
<?= View::h($klassenname) ?>
|
||||
<?php else: ?>
|
||||
<?php /* Wie bei der Zuordnung: Ohne JavaScript führt der Klick
|
||||
in die Buchungsmaske, mit ihm öffnet sich die Auswahl
|
||||
an Ort und Stelle. */ ?>
|
||||
an Ort und Stelle – bei einer Splitbuchung der
|
||||
Splitdialog, denn dort stehen ihre Klassen. */ ?>
|
||||
<a href="/buchungen/<?= (int)$zeile['id'] ?>" class="klassenfeld"
|
||||
data-buchung="<?= (int)$zeile['id'] ?>"
|
||||
data-klasse="<?= (int)$zeile['klasse_id'] ?>"
|
||||
title="<?= View::h($klassenname !== '' ? $klassenname : 'Klasse zuordnen') ?>">
|
||||
<?= View::h($klassenname) ?>
|
||||
data-klasse="<?= (int)$klasse['klasse_id'] ?>"
|
||||
<?php if ($splitzeilen !== null): ?>data-split="1"<?php endif; ?>
|
||||
title="<?= View::h($klassentitel) ?>">
|
||||
<?php if ($klasse['gemischt']): ?>
|
||||
<span class="marke">Splitbuchung</span>
|
||||
<?php else: ?>
|
||||
<?= View::h($klassenname) ?>
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
|
|
|
|||
192
tests/47_SplitKlasseTest.php
Normal file
192
tests/47_SplitKlasseTest.php
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Finanzmanager\Models\Buchung;
|
||||
use Finanzmanager\Models\Kategorie;
|
||||
use Finanzmanager\Models\Klasse;
|
||||
use Finanzmanager\Models\Konto;
|
||||
|
||||
/**
|
||||
* Fix #76: Die Klassenspalte des Kontoblatts berücksichtigt bei einer
|
||||
* Splitbuchung die Klassen ihrer Zeilen. Tragen alle Zeilen dieselbe Klasse,
|
||||
* steht sie in der Spalte; unterscheiden sie sich, steht dort die Marke
|
||||
* „Splitbuchung“ mit den Klassen je Zeile im Tooltip.
|
||||
*/
|
||||
class SplitKlasseTest extends TestCase
|
||||
{
|
||||
protected string $testName = 'Test 47: Klassen der Splitzeilen im Kontoblatt';
|
||||
|
||||
private int $konto = 0;
|
||||
private int $lebensmittel = 0;
|
||||
private int $drogerie = 0;
|
||||
private int $privat = 0;
|
||||
private int $beruf = 0;
|
||||
private int $alt = 0;
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$this->mandantAnlegen();
|
||||
|
||||
$this->konto = Konto::anlegen([
|
||||
'name' => 'Splitklasse Giro', 'kontoart' => 'bank', 'anfangssaldo' => 0, 'aktiv' => 1,
|
||||
]);
|
||||
$this->lebensmittel = Kategorie::anlegen(['name' => 'Splitklasse Lebensmittel', 'art' => 'ausgabe']);
|
||||
$this->drogerie = Kategorie::anlegen(['name' => 'Splitklasse Drogerie', 'art' => 'ausgabe']);
|
||||
$this->privat = Klasse::anlegen('Splitklasse Privat');
|
||||
$this->beruf = Klasse::anlegen('Splitklasse Beruf');
|
||||
$this->alt = Klasse::anlegen('Splitklasse Buchungsklasse');
|
||||
|
||||
$this->splitKlasseErmitteln();
|
||||
$this->kontoblattZeigtGemeinsameKlasse();
|
||||
$this->kontoblattZeigtMarkeBeiVerschiedenenKlassen();
|
||||
$this->ohneSplitBleibtEsBeiDerBuchungsklasse();
|
||||
}
|
||||
|
||||
private function splitKlasseErmitteln(): void
|
||||
{
|
||||
$gleich = [['klasse_id' => $this->privat], ['klasse_id' => (string)$this->privat]];
|
||||
$this->assertEquals(
|
||||
['gemischt' => false, 'klasse_id' => $this->privat],
|
||||
Buchung::splitKlasse($gleich, $this->alt),
|
||||
'Gleiche Klassen in allen Zeilen gelten für die ganze Buchung'
|
||||
);
|
||||
|
||||
$verschieden = [['klasse_id' => $this->privat], ['klasse_id' => $this->beruf]];
|
||||
$this->assertEquals(
|
||||
['gemischt' => true, 'klasse_id' => null],
|
||||
Buchung::splitKlasse($verschieden, $this->alt),
|
||||
'Verschiedene Klassen machen die Buchung gemischt'
|
||||
);
|
||||
|
||||
$teilweise = [['klasse_id' => $this->privat], ['klasse_id' => null]];
|
||||
$this->assertEquals(
|
||||
true,
|
||||
Buchung::splitKlasse($teilweise, null)['gemischt'],
|
||||
'Eine Zeile ohne Klasse unterscheidet sich von einer mit Klasse'
|
||||
);
|
||||
|
||||
$ohne = [['klasse_id' => null], ['klasse_id' => null]];
|
||||
$this->assertEquals(
|
||||
['gemischt' => false, 'klasse_id' => $this->alt],
|
||||
Buchung::splitKlasse($ohne, $this->alt),
|
||||
'Ohne Klasse in den Zeilen bleibt die Klasse der Buchung'
|
||||
);
|
||||
$this->assertEquals(
|
||||
['gemischt' => false, 'klasse_id' => null],
|
||||
Buchung::splitKlasse($ohne, null),
|
||||
'Ohne jede Klasse bleibt die Spalte leer'
|
||||
);
|
||||
}
|
||||
|
||||
private function kontoblattZeigtGemeinsameKlasse(): void
|
||||
{
|
||||
$id = $this->splitbuchung('Gleichmarkt', $this->privat, $this->privat);
|
||||
$zelle = $this->klassenzelle($id);
|
||||
|
||||
$this->assert(str_contains($zelle, 'Splitklasse Privat'), 'Die gemeinsame Klasse steht in der Spalte');
|
||||
$this->assert(!str_contains($zelle, 'class="marke"'), 'Ohne Marke „Splitbuchung“');
|
||||
$this->assert(str_contains($zelle, 'data-split="1"'), 'Der Klick führt in den Splitdialog');
|
||||
$this->assert(
|
||||
str_contains($zelle, 'data-klasse="' . $this->privat . '"'),
|
||||
'Die Zelle trägt die gemeinsame Klasse'
|
||||
);
|
||||
}
|
||||
|
||||
private function kontoblattZeigtMarkeBeiVerschiedenenKlassen(): void
|
||||
{
|
||||
$id = $this->splitbuchung('Mischmarkt', $this->privat, $this->beruf);
|
||||
$zelle = $this->klassenzelle($id);
|
||||
|
||||
$this->assert(
|
||||
str_contains($zelle, '<span class="marke">Splitbuchung</span>'),
|
||||
'Verschiedene Klassen zeigen die Marke „Splitbuchung“'
|
||||
);
|
||||
$this->assert(
|
||||
str_contains($zelle, 'title="Splitklasse Lebensmittel: Splitklasse Privat' . "\n"
|
||||
. 'Splitklasse Drogerie: Splitklasse Beruf"'),
|
||||
'Der Tooltip nennt je Splitzeile Kategorie und Klasse'
|
||||
);
|
||||
$this->assert(
|
||||
!str_contains($zelle, 'Splitklasse Buchungsklasse'),
|
||||
'Die Klasse der Buchung selbst spielt keine Rolle'
|
||||
);
|
||||
}
|
||||
|
||||
private function ohneSplitBleibtEsBeiDerBuchungsklasse(): void
|
||||
{
|
||||
$id = Buchung::anlegen([
|
||||
'konto_id' => $this->konto, 'datum' => '2026-05-03', 'betrag' => -12.00,
|
||||
'empfaenger' => 'Einzelmarkt', 'kategorie_id' => $this->lebensmittel, 'klasse_id' => $this->beruf,
|
||||
]);
|
||||
$zelle = $this->klassenzelle($id);
|
||||
|
||||
$this->assert(str_contains($zelle, 'Splitklasse Beruf'), 'Eine einfache Buchung zeigt ihre Klasse');
|
||||
$this->assert(!str_contains($zelle, 'data-split'), 'Und öffnet weiter die Klassenliste');
|
||||
}
|
||||
|
||||
private function splitbuchung(string $empfaenger, int $klasseA, int $klasseB): int
|
||||
{
|
||||
return Buchung::anlegen(
|
||||
[
|
||||
'konto_id' => $this->konto, 'datum' => '2026-05-02', 'betrag' => -30.00,
|
||||
'empfaenger' => $empfaenger, 'klasse_id' => $this->alt,
|
||||
],
|
||||
[
|
||||
['kategorie_id' => $this->lebensmittel, 'klasse_id' => $klasseA, 'betrag' => -20.00],
|
||||
['kategorie_id' => $this->drogerie, 'klasse_id' => $klasseB, 'betrag' => -10.00],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Klassenzelle einer Buchung aus dem gerenderten Kontoblatt.
|
||||
*/
|
||||
private function klassenzelle(int $buchungId): string
|
||||
{
|
||||
$html = $this->kontoblattHtml();
|
||||
$muster = '#<td class="klassenzelle nebentext">\s*<a href="/buchungen/' . $buchungId . '".*?</td>#s';
|
||||
|
||||
return preg_match($muster, $html, $treffer) === 1 ? $treffer[0] : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Das Kontoblatt rendern wie der Controller es täte – ohne Webserver.
|
||||
*/
|
||||
private function kontoblattHtml(): string
|
||||
{
|
||||
$zeilen = Buchung::kontoblatt($this->konto);
|
||||
$gesplittete = [];
|
||||
foreach ($zeilen as $zeile) {
|
||||
if ((int)$zeile['gesplittet'] === 1 && !$zeile['gegensicht']) {
|
||||
$gesplittete[] = (int)$zeile['id'];
|
||||
}
|
||||
}
|
||||
|
||||
$daten = [
|
||||
'konto' => Konto::mitSalden(Konto::find($this->konto)),
|
||||
'zeilen' => $zeilen,
|
||||
'gesamt' => count($zeilen),
|
||||
'seite' => 1,
|
||||
'seiten' => 1,
|
||||
'filter' => [],
|
||||
'kategorien' => Kategorie::baumFlach(),
|
||||
'klassen' => Klasse::alle(),
|
||||
'konten' => Konto::alle(),
|
||||
'splits' => Buchung::splitsJeBuchung($gesplittete),
|
||||
'wertpapiere' => [],
|
||||
'bargeld' => false,
|
||||
'titel' => 'Test',
|
||||
'flash' => [],
|
||||
'benutzer' => null,
|
||||
'csrfToken' => 'x',
|
||||
'aktuellerPfad' => '/konten/' . $this->konto,
|
||||
];
|
||||
|
||||
extract($daten, EXTR_SKIP);
|
||||
|
||||
ob_start();
|
||||
include dirname(__DIR__) . '/src/Views/buchungen/kontoblatt.php';
|
||||
return (string)ob_get_clean();
|
||||
}
|
||||
}
|
||||
|
|
@ -372,6 +372,42 @@ test.describe('Buchungen', () => {
|
|||
expect(titel).toContain(`${KATEGORIE}: -97,98`)
|
||||
})
|
||||
|
||||
test('Klassen der Splitzeilen stehen in der Klassenspalte', async ({ page }) => {
|
||||
await page.goto(`/konten/${giroId}/buchung`)
|
||||
await page.fill('#datum', '2026-05-03')
|
||||
await page.fill('#betrag', '45')
|
||||
await page.fill('#empfaenger', `Klassensplit ${MARKE}`)
|
||||
await page.selectOption('select[name="split[0][zuordnung]"]', { label: KATEGORIE })
|
||||
await page.selectOption('select[name="split[0][klasse_id]"]', { label: KLASSE })
|
||||
await page.fill('input[name="split[0][betrag]"]', '-25')
|
||||
await page.selectOption('select[name="split[1][zuordnung]"]', { label: KATEGORIE })
|
||||
await page.fill('input[name="split[1][betrag]"]', '-20')
|
||||
await page.click('.buchungsmaske button[type="submit"]')
|
||||
await expect(page.locator('.meldung-erfolg')).toBeVisible()
|
||||
|
||||
// Verschiedene Klassen: die Marke, im Tooltip die Klasse je Zeile.
|
||||
const zeile = page.locator('tr', { hasText: `Klassensplit ${MARKE}` })
|
||||
const klassenfeld = zeile.locator('a.klassenfeld')
|
||||
await expect(klassenfeld.locator('.marke')).toHaveText('Splitbuchung')
|
||||
const titel = await klassenfeld.getAttribute('title')
|
||||
expect(titel).toContain(`${KATEGORIE}: ${KLASSE}`)
|
||||
expect(titel).toContain(`${KATEGORIE}: (ohne Klasse)`)
|
||||
|
||||
// Der Klick führt in den Splitdialog, wo die Klassen der Zeilen stehen.
|
||||
await klassenfeld.click()
|
||||
const dialog = page.locator('#splitdialog')
|
||||
await expect(dialog).toBeVisible()
|
||||
await expect(page.locator('#klassenauswahl')).toBeHidden()
|
||||
await dialog.locator('select[name="split[1][klasse_id]"]').selectOption({ label: KLASSE })
|
||||
await dialog.locator('button[type="submit"].primaer').click()
|
||||
await expect(page.locator('.meldung-erfolg').last()).toContainText('Splitbuchung gespeichert')
|
||||
|
||||
// Gleiche Klassen: die Klasse selbst, ohne Marke.
|
||||
const danach = page.locator('tr', { hasText: `Klassensplit ${MARKE}` }).locator('a.klassenfeld')
|
||||
await expect(danach).toHaveText(KLASSE)
|
||||
await expect(danach.locator('.marke')).toHaveCount(0)
|
||||
})
|
||||
|
||||
test('Buchungszeilen sind gleich hoch, abgeschnittene Texte stehen im Tooltip', async ({ page }) => {
|
||||
const LANG = `Verwendungszweck ${MARKE} mit sehr vielen Wörtern, `.repeat(6).trim()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue