Restructure catalog to root categories + collapsible groups
- Migration: replace 45 leaf categories (diag.scan, engine.mech…) with 17 root categories (diag, engine…); update labors.category by taking the prefix before the first dot; delete the leaf LaborCategory rows - ImportLaborCatalogCommand: rewritten to use root categories directly so future imports go to the right level from the start - LaborResource: add ->collapsible() to groups so user can collapse/ expand each category section to see only headers or only one group - entrypoint.sh: remove one-time catalog import (was already done) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -85,41 +85,37 @@ class ImportLaborCatalogCommand extends Command
|
||||
$operations = $data['operations'] ?? [];
|
||||
$catMap = collect($allCats)->keyBy('id');
|
||||
|
||||
$usedCatIds = collect($operations)->pluck('service_category_id')->unique();
|
||||
$leafCats = $catMap->only($usedCatIds->all());
|
||||
// Build root-category map: leaf cat_id → root code (prefix before first dot)
|
||||
$rootCats = collect($allCats)->filter(fn ($c) => $c['parent_id'] === null)->keyBy('id');
|
||||
$leafToRoot = []; // leaf_cat_id → root_code
|
||||
foreach ($allCats as $cat) {
|
||||
$rootCode = explode('.', $cat['code'])[0];
|
||||
$leafToRoot[$cat['id']] = $rootCode;
|
||||
}
|
||||
$rootsNeeded = collect($operations)
|
||||
->map(fn ($op) => $leafToRoot[$op['service_category_id']] ?? null)
|
||||
->filter()->unique();
|
||||
|
||||
$this->line("── {$company->name} (id={$company->id}) ── cats:{$leafCats->count()} ops:" . count($operations));
|
||||
$this->line("── {$company->name} (id={$company->id}) ── root-cats:{$rootsNeeded->count()} ops:" . count($operations));
|
||||
|
||||
// ── 1. Labor categories ───────────────────────────────────────────
|
||||
$catCodeToId = [];
|
||||
$sortBase = 100;
|
||||
|
||||
foreach ($leafCats as $leaf) {
|
||||
$parent = $catMap->get($leaf['parent_id']);
|
||||
$nameRu = ($parent ? $parent['name'] . ' · ' : '') . $leaf['name'];
|
||||
$code = $leaf['code'];
|
||||
// ── 1. Root labor categories (17 tops) ───────────────────────────
|
||||
foreach ($rootCats as $root) {
|
||||
if (! $rootsNeeded->contains($root['code'])) continue;
|
||||
|
||||
$existing = LaborCategory::withoutGlobalScope(TenantScope::class)
|
||||
->where('company_id', $company->id)
|
||||
->where('name', $code)
|
||||
->first();
|
||||
->where('name', $root['code'])
|
||||
->exists();
|
||||
|
||||
if ($existing) {
|
||||
if ($force) {
|
||||
$existing->update(['name_ru' => $nameRu]);
|
||||
}
|
||||
} else {
|
||||
$existing = LaborCategory::withoutGlobalScope(TenantScope::class)->create([
|
||||
if (! $existing) {
|
||||
LaborCategory::withoutGlobalScope(TenantScope::class)->create([
|
||||
'company_id' => $company->id,
|
||||
'name' => $code,
|
||||
'name_ro' => $nameRu,
|
||||
'name_ru' => $nameRu,
|
||||
'sort_order' => $sortBase + ($leaf['sort_order'] ?? 0),
|
||||
'name' => $root['code'],
|
||||
'name_ro' => $root['name'],
|
||||
'name_ru' => $root['name'],
|
||||
'sort_order' => $root['sort_order'],
|
||||
]);
|
||||
}
|
||||
|
||||
$catCodeToId[$leaf['id']] = $code;
|
||||
$sortBase += 5;
|
||||
}
|
||||
|
||||
// ── 2. Labors ─────────────────────────────────────────────────────
|
||||
@@ -127,7 +123,7 @@ class ImportLaborCatalogCommand extends Command
|
||||
$skipped = 0;
|
||||
|
||||
foreach ($operations as $op) {
|
||||
$catKey = $catCodeToId[$op['service_category_id']] ?? null;
|
||||
$catKey = $leafToRoot[$op['service_category_id']] ?? null;
|
||||
if (! $catKey) { $skipped++; continue; }
|
||||
|
||||
$existing = Labor::withoutGlobalScope(TenantScope::class)
|
||||
|
||||
Reference in New Issue
Block a user