invoiceModel->update($invoiceId, ['status' => 'extracting']); try { $extractedData = $this->aiExtraction->extractInvoiceData($filePath, $mimeType); // Map AI data to schema columns $this->invoiceModel->update($invoiceId, [ 'status' => 'extracted', 'invoice_number' => $extractedData['invoice_number'] ?? null, 'invoice_date' => $extractedData['invoice_date'] ?? null, 'supplier_name' => $extractedData['supplier_name'] ?? null, 'supplier_tin' => $extractedData['supplier_tin'] ?? null, 'buyer_name' => $extractedData['buyer_name'] ?? null, 'buyer_tin' => $extractedData['buyer_tin'] ?? null, 'subtotal' => $extractedData['subtotal'] ?? 0, 'tax_amount' => $extractedData['tax_amount'] ?? 0, 'discount_total' => $extractedData['discount_total'] ?? 0, 'grand_total' => $extractedData['grand_total'] ?? 0, 'ai_confidence_score' => $extractedData['confidence'] ?? null, 'ai_provider' => $extractedData['provider'] ?? 'gemini', 'ai_raw_response' => json_encode($extractedData, JSON_UNESCAPED_UNICODE), ]); // Also insert invoice_lines: if (!empty($extractedData['lines'])) { $db = \App\Core\Database::getInstance(); $db->prepare("DELETE FROM invoice_lines WHERE invoice_id = ?")->execute([$invoiceId]); foreach ($extractedData['lines'] as $i => $line) { $db->prepare("INSERT INTO invoice_lines (id, invoice_id, line_number, description, quantity, unit_price, discount, tax_rate, tax_amount, line_total) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") ->execute([ \Ramsey\Uuid\Uuid::uuid4()->toString(), $invoiceId, $i + 1, $line['description'] ?? '', $line['quantity'] ?? 1, $line['unit_price'] ?? 0, $line['discount'] ?? 0, $line['tax_rate'] ?? 0.16, $line['tax_amount'] ?? 0, $line['line_total'] ?? 0, ]); } } } catch (Throwable $e) { $this->invoiceModel->update($invoiceId, [ 'status' => 'validation_failed' ]); throw $e; } } }