test: full E2E audit + fix CsvImportExport vehicle.brand → make
Audit pass (33 new tests in tests/Feature/Audit/): - CrmFunnelE2ETest: full Lead→Deal→Appointment→WO→Payment journey, covering 5 previously-untested models. Verifies WO.balanceDue updates correctly after payments, including refunds (negative amount → balance increases). - WorkOrderTotalsTest: works+parts+subcontract+discount sum correctly, cancelled subcontract excluded, deleting lines triggers recalc, status=done consumes part reservations into issues, cancelled releases reservations. - ShopJourneyE2ETest: register→cart→checkout→email confirmation→tracking page reachable→admin fulfills→stock drops→warehouse event recorded. Also guest checkout still works without account. - CsvImportExportTest: round-trip, dedup-by-phone, **caught real bug** — Vehicle export wrote $row->brand (no such property) and import set 'brand' => row['brand'] in Vehicle::create (column is `make`). Fix applied to both paths. - TenantBackupServiceTest: zip contains valid manifest with counts + data/*.json per model + works embedded with WorkOrder. - WorkOrderPdfServiceTest: generated PDF starts with %PDF, includes WO data, non-trivial size, handles empty WO. - PayrollCalculatorTest: base + works_pct + parts_pct + bonus - fine - advance, scoped to user + period. - NotificationFallbackTest: Telegram wins when chat_id present, falls back to email when not, returns false when neither, tenant disable flag stops both. - AiProvidersCrossCheckTest: OpenAI request shape, Gemini URL with model, no-key friendly message, tenant model override propagates into HTTP body. - SettingsPersistenceTest: 25-key settings JSON round-trips, partial update via array_replace_recursive preserves other keys. - CompanyProvisionerTest: suspend / reactivate / archive behavior. Bug fixed: CsvImportExport used `brand` on Vehicle which has column `make`. The export silently emitted empty values, the import silently dropped the brand. Now both paths use `make`. Full suite: 173 passed (468 assertions). 0 failed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -47,7 +47,7 @@ class CsvImportExport
|
||||
Vehicle::with('client:id,phone')->orderBy('plate')->chunk(500, function ($rows) use ($out) {
|
||||
foreach ($rows as $row) {
|
||||
fputcsv($out, [
|
||||
$row->plate, $row->vin, $row->brand, $row->model, $row->year,
|
||||
$row->plate, $row->vin, $row->make, $row->model, $row->year,
|
||||
$row->engine, $row->gearbox, $row->fuel, $row->mileage,
|
||||
$row->color, $row->notes, $row->client?->phone,
|
||||
]);
|
||||
@@ -108,7 +108,8 @@ class CsvImportExport
|
||||
'client_id' => $client->id,
|
||||
'plate' => $row['plate'],
|
||||
'vin' => $row['vin'] ?? null,
|
||||
'brand' => $row['brand'] ?? null,
|
||||
// CSV header keeps the user-friendly "brand" name, but the column is `make`.
|
||||
'make' => $row['brand'] ?? null,
|
||||
'model' => $row['model'] ?? null,
|
||||
'year' => (int) ($row['year'] ?? 0) ?: null,
|
||||
'engine' => $row['engine'] ?? null,
|
||||
|
||||
Reference in New Issue
Block a user