kategoria. * Sluzy WYLACZNIE do podpowiedzi; nic nie jest ksiegowane automatycznie. */ class ReceiptCategoryMapModel extends Model { protected $table = 'receipt_category_map'; protected $primaryKey = 'id'; protected $returnType = 'array'; protected $useTimestamps = true; protected $dateFormat = 'datetime'; protected $createdField = ''; // tabela ma tylko updated_at protected $allowedFields = ['item_name', 'category_id', 'updated_at']; /** * Normalizacja nazwy pozycji jako klucz uczenia: * trim + lowercase + redukcja wielokrotnych bialych znakow. * ponytail: bez usuwania gramatur/liczb — zaczynamy od dokladnego dopasowania nazwy. */ public function normalize(string $name): string { $n = mb_strtolower(trim($name)); return preg_replace('/\s+/u', ' ', $n) ?? $n; } /** * Podpowiedziana kategoria dla nazwy pozycji lub null. */ public function suggest(string $name): ?int { $row = $this->where('item_name', $this->normalize($name))->first(); return $row ? (int) $row['category_id'] : null; } /** * Zapamietaj wybor uzytkownika (upsert po znormalizowanej nazwie). */ public function remember(string $name, int $categoryId): void { $key = $this->normalize($name); if ($key === '') { return; } $existing = $this->where('item_name', $key)->first(); if ($existing) { $this->update($existing['id'], ['category_id' => $categoryId, 'updated_at' => date('Y-m-d H:i:s')]); } else { $this->insert(['item_name' => $key, 'category_id' => $categoryId, 'updated_at' => date('Y-m-d H:i:s')]); } } }