From edifact
This skill should be used when the user says "/klassifikationspflege", "klassifikationsnummern pflegen", "unkategorisierte klassifikationsnummern", "fehlende kategorien fixen", "klassifikationsnummern prüfen", "category_id NULL", or wants to find and fix uncategorized Klassifikationsnummern entries in the Contradoo EDI system. Covers the full workflow: find uncategorized entries, auto-match against existing references, review with user, and generate a production migration.
How this skill is triggered — by the user, by Claude, or both
Slash command
/edifact:klassifikationspflegeThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Wartungs-Workflow für die `klassifikationsnummern`-Tabelle in Contradoo. Neue Klassifikationsnummern
Wartungs-Workflow für die klassifikationsnummern-Tabelle in Contradoo. Neue Klassifikationsnummern
werden beim EDI-Import automatisch angelegt, oft ohne category_id. Fehlende Kategorien führen dazu,
dass CostOverviewService::shouldShowInCostTable() diese ignoriert und Kostenpositionen in der
PDF-Kostenübersicht fehlen.
Tinker-Abfrage ausführen, um alle Einträge ohne category_id zu identifizieren:
$uncategorized = \App\Models\Klassifikationsnummer::whereNull('category_id')->count();
Falls 0: Dem User mitteilen, dass keine offenen Einträge existieren. Workflow beenden.
Drei Gruppen unterscheiden:
ELMO-Format (Telekom) — 12-stellige numerische ELMONUMBER (z.B. 010000046989):
->whereRaw("\"ELMONUMBER\" ~ '^[0-9]{12}$'")
Text-basiert (O2/Vodafone) — ELMOTEXT-basierte Nummern mit Datums-/Lizenz-Suffixen.
Leer — Leerer ELMOTEXT (Kundennummern etc.), in der Regel irrelevant.
Referenz-Einträge anhand von ELMONUMBER-Prefix und Namensmustern finden:
| Prefix | Typische Kategorie | type-Flag |
|---|---|---|
010 | 2 (Basispreise) oder 10 (Optionspreise) | tariff=true oder costs=true |
020 | 12 (Gebuchte Datenpässe) oder 31 (Datenpässe Roaming TZ) | costs=true |
080 | 26 (Einmalige Gebühren) | costs=true |
090 | 1 (Rabatte auf Basispreise) oder 8 (Rabatte auf Optionen) | tariffrebate=true oder costsrebate=true |
Wichtig: Prefix allein reicht nicht! Immer einen kategorisierten Referenz-Eintrag mit ähnlichem ELMOTEXT suchen und die Zuordnung bestätigen:
$ref = \App\Models\Klassifikationsnummer::with('category')
->whereNotNull('category_id')
->where('ELMONUMBER', 'like', $prefix . '%')
->where('ELMOTEXT', 'like', '%' . substr($elmotext, 0, 20) . '%')
->first();
ELMOTEXT bereinigen (Datums-Suffixe, Lizenzanzahlen, anteilige Tage entfernen) und dann die ersten 25 Zeichen gegen bestehende kategorisierte Einträge vergleichen:
$clean = preg_replace('/\s*-\s*\d{2}\.\d{2}\.\d{4}$/', '', $text);
$clean = preg_replace('/\s*\(?\d{2}\.\d{2}\.\d{4}\s*-\s*\d{2}\.\d{2}\.\d{4}\)?/', '', $clean);
$clean = preg_replace('/\s*\(anteilig \d+ Tage\)/', '', $clean);
$clean = preg_replace('/\s*\d+\s*Lizenz(en)?/', '', $clean);
$clean = preg_replace('/\s*\d+\s*Minute\(n\)/', '', $clean);
$clean = preg_replace('/\s*\d+\s*(MB|GB)/', '', $clean);
$short = substr(trim($clean), 0, 25);
$match = \App\Models\Klassifikationsnummer::with('category')
->whereNotNull('category_id')
->where('ELMOTEXT', 'like', $short . '%')
->first();
Übersichtliche Tabelle mit allen gefundenen Einträgen zeigen, gruppiert nach:
Dem User die Zahlen und vorgeschlagenen Zuordnungen zeigen. Erst nach User-Bestätigung weiter.
Nach Bestätigung eine Laravel-Migration generieren mit folgenden Anforderungen:
hotfix/fix-missing-klassifikationsnummer-categories (oder ähnlich)category_id IS NULLdown() setzt category_id auf NULL zurückMigrations-Template:
public function up(): void
{
if (! DB::getSchemaBuilder()->hasTable('klassifikationsnummern')) {
return;
}
$mappings = $this->getMappings();
$existingIds = DB::table('klassifikationsnummern')
->whereIn('id', array_keys($mappings))
->whereNull('category_id')
->pluck('id')
->all();
if (empty($existingIds)) {
Log::info('Migration: No matching Klassifikationsnummern to fix');
return;
}
$updated = 0;
foreach ($existingIds as $id) {
[$categoryId, $type] = $mappings[$id];
DB::table('klassifikationsnummern')
->where('id', $id)
->update([
'category_id' => $categoryId,
'type' => json_encode($type),
'updated_at' => now(),
]);
$updated++;
}
Log::info("Migration: Fixed {$updated} Klassifikationsnummern");
}
Den User darauf hinweisen, dass nach dem Deployment die PDF-Kostenübersichten für betroffene Kunden neu generiert werden müssen. Betroffene EdiCostOverviews identifizieren durch Verknüpfung der gefixten Klassifikationsnummern mit EdiFactDocuments.
| ID | Name | Beschreibung |
|---|---|---|
| 1 | Rabatte auf Basispreise | Rabatte auf Tarif-Grundpreise |
| 2 | Basispreise | Tarif-Grundpreise (Mobilfunk, Festnetz) |
| 8 | Rabatte auf Optionen | Rabatte auf gebuchte Optionen |
| 10 | Optionspreise | Gebuchte Optionen/Zusatzpakete |
| 12 | Gebuchte Datenpässe | Datenpässe national |
| 18 | # INFOTEXT | Info-Texte, keine Kosten |
| 21 | # Undefiniert | Undefiniert, wird ausgeblendet |
| 26 | Einmalige Gebühren | Bereitstellung, Anschlusspreise |
| 27 | Drittanbieterkosten (brutto) | Kosten von Drittanbietern |
| 31 | Datenpässe Roaming (TZ) | Roaming-Datenpässe |
Jede Klassifikationsnummer hat ein type JSON-Feld mit 5 Flags:
| Flag | Bedeutung | Wann true |
|---|---|---|
tariff | Ist ein Tarif | Basispreise (010-Prefix) |
costs | Kostenposition | Optionen, Einmalige, Datenpässe |
costsrebate | Rabatt auf Kosten | Rabatte auf Optionen (090 + Option) |
tariffrebate | Rabatt auf Tarif | Rabatte auf Basispreise (090 + Basis) |
info | Nur Info | INFOTEXT-Kategorie |
shouldShowInCostTable() prüft zuerst category_id != NULL, dann ob Kategorie in
COST_CATEGORIES ist oder type.costs/type.costsrebate true istcategory_id = NULL werden immer ignoriert — sie tauchen nie in Kostenübersichten aufklassifikationsnummern-Tabelle hat Soft Deletes (deleted_at)\App\Models\KlassifikationsnummerCategory::all(['id', 'name'])npx claudepluginhub weslinkde/weslink-claude-marketplace --plugin edifactSuggests SKR03/SKR04 account codes for SME bookkeeping categories via code search or OpenAI semantic matching. Lists existing categories and creates custom ones for DATEV setups.
Classifies knowledge entries by type and triages the review queue for low-confidence predictions.
Provides data classification framework with sensitivity levels (Public to Top Secret), handling requirements for access, encryption, sharing, retention, disposal, and labeling.