Feature: Anlagen-Nummernkreis mit konfiguriertem Präfix (ANL-YYYY-NNNN)

This commit is contained in:
fds2610-bot 2026-04-12 14:07:39 +02:00
parent f22d640e4e
commit 67dd79db1b
6 changed files with 45 additions and 5 deletions

View file

@ -0,0 +1,13 @@
-- Migration 031: Anlagen-Nummernkreis mit konfiguriertem Präfix
ALTER TABLE company_settings
ADD COLUMN anlage_nr_prefix VARCHAR(10) NOT NULL DEFAULT 'ANL'
COMMENT 'Präfix für Anlagen-Nummern (z.B. ANL)'
AFTER beleg_nr_next,
ADD COLUMN anlage_nr_next INT UNSIGNED NOT NULL DEFAULT 1
COMMENT 'Nächste laufende Nummer für Anlagegüter'
AFTER anlage_nr_prefix;
ALTER TABLE assets
ADD COLUMN anlage_nr VARCHAR(30) NOT NULL DEFAULT ''
COMMENT 'Formatierte Anlagen-Nummer (z.B. ANL-2026-0001)'
AFTER lfd_nr;

View file

@ -54,6 +54,23 @@ class Asset
return (int)($row['next'] ?? 1);
}
public static function generateAnlageNr(): string
{
$settings = Database::fetchOne(
'SELECT anlage_nr_prefix, anlage_nr_next FROM company_settings WHERE id=1'
);
$prefix = $settings['anlage_nr_prefix'] ?? 'ANL';
$next = (int)($settings['anlage_nr_next'] ?? 1);
$year = date('Y');
$nr = sprintf('%s-%s-%04d', $prefix, $year, $next);
Database::execute(
'UPDATE company_settings SET anlage_nr_next = anlage_nr_next + 1 WHERE id=1'
);
return $nr;
}
public static function create(array $data): int
{
$fyId = null;
@ -63,13 +80,16 @@ class Asset
$fyId = $fy['id'];
}
$anlageNr = $data['anlage_nr'] ?? self::generateAnlageNr();
Database::execute(
'INSERT INTO assets
(lfd_nr, bezeichnung, account_id, anschaffungsdatum, anschaffungskosten,
(lfd_nr, anlage_nr, bezeichnung, account_id, anschaffungsdatum, anschaffungskosten,
zugaenge, abgaenge, abschreibung_jahr, nutzungsdauer, notizen, fiscal_year_id)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
[
$data['lfd_nr'] ?? self::nextLfdNr(),
$anlageNr,
$data['bezeichnung'],
isset($data['account_id']) && $data['account_id'] !== '' ? (int)$data['account_id'] : null,
$data['anschaffungsdatum'],

View file

@ -28,7 +28,7 @@ class Setting
ust_id=?, steuernummer=?, finanzamt=?,
iban=?, bic=?, bank_name=?,
ustva_steuernummer=?, ustva_bundesland=?,
invoice_nr_prefix=?, beleg_nr_prefix=?,
invoice_nr_prefix=?, beleg_nr_prefix=?, anlage_nr_prefix=?,
payment_days_default=?, test_mode=?, ki_vorschlag_aktiv=?, ocr_aktiv=?,
nextcloud_url=?, nextcloud_user=?, nextcloud_pass=?,
nextcloud_folder=?, nextcloud_done=?
@ -52,6 +52,7 @@ class Setting
$data['ustva_bundesland'] ?? null,
$data['invoice_nr_prefix'] ?? 'AR',
$data['beleg_nr_prefix'] ?? 'BLG',
$data['anlage_nr_prefix'] ?? 'ANL',
(int)($data['payment_days_default'] ?? 14),
isset($data['test_mode']) ? 1 : 0,
isset($data['ki_vorschlag_aktiv']) ? 1 : 0,

View file

@ -19,7 +19,7 @@
<tbody>
<?php foreach ($assets as $a): ?>
<tr>
<td class="td-mono text-sm"><?= $h($a['lfd_nr']) ?></td>
<td class="td-mono text-sm"><?= $h($a['anlage_nr'] ?: $a['lfd_nr']) ?></td>
<td class="td-muted text-sm"><?= View::formatDate($a['anschaffungsdatum']) ?></td>
<td class="td-muted text-sm">
<?php if ($a['anlageart_kontonummer']): ?>

View file

@ -273,6 +273,10 @@
<label>Beleg-Präfix</label>
<input type="text" name="beleg_nr_prefix" value="<?= $h($settings['beleg_nr_prefix'] ?? 'BLG') ?>" maxlength="10">
</div>
<div class="form-group">
<label>Anlagen-Präfix</label>
<input type="text" name="anlage_nr_prefix" value="<?= $h($settings['anlage_nr_prefix'] ?? 'ANL') ?>" maxlength="10">
</div>
</div>
<div class="form-group">
<label>Standard-Zahlungsziel (Tage)</label>

View file

@ -35,8 +35,10 @@ class AnlagevermoegensTest extends TestCase
$this->assertEquals(300.00, (float)$asset['abschreibung_jahr'], 'Abschreibung korrekt');
$this->assertEquals(5, (int)$asset['nutzungsdauer'], 'Nutzungsdauer korrekt');
// ── Lfd. Nr. wird automatisch vergeben ───────────────────────
// ── Lfd. Nr. und Anlage-Nr. werden automatisch vergeben ──────
$this->assertGreaterThan(0, (int)$asset['lfd_nr'], 'Lfd. Nr. > 0');
$this->assertNotEmpty($asset['anlage_nr'], 'Anlage-Nr. wurde generiert');
$this->assert(str_contains($asset['anlage_nr'], '-'), 'Anlage-Nr. enthält Präfix-Trenner');
// ── all() enthält das neue Asset ─────────────────────────────
$all = Asset::all();