GWM : policy pdf convert to md file for ai push

This commit is contained in:
Gowtham M 2026-06-05 17:10:30 +05:30
parent c751a82c19
commit d0358fcdc5
3 changed files with 258 additions and 45 deletions

1
.gitignore vendored
View File

@ -16,6 +16,7 @@
/writable/uploads/enquiry/rc/*
/writable/uploads/quotation/*
/writable/uploads/policy/policy_pdf/*
/writable/uploads/policy/policy_md/*
/writable/uploads/policy/policy_payment_receipt/*

View File

@ -817,46 +817,69 @@ class PolicyController extends ResourceController
try
{
helper('policy_pdf_helper');
// Replace with your actual Gemini API key
$apiKey = getenv('GEMINI_API_KEY');
// The model to use and the API endpoint
$model = "gemini-pro";
$model = getenv('GEMINI_MODEL');
// dd($model);
// $model = "gemini-1.5-pro";
$url = "https://generativelanguage.googleapis.com/v1beta/models/{$model}:generateContent?key={$apiKey}";
$record = $this->PolicyModel->find((int)$policyId);
$uploadedPath = WRITEPATH . 'uploads/policy/policy_pdf/';
$filePath = $uploadedPath.$record['policy_pdf_file_name'];
// dd($filePath);
// Check if the file exists
if (!file_exists($filePath)) {
log_message('info',"Error: File not found at {$filePath}");
$mdUploadedPath = WRITEPATH . 'uploads/policy/policy_md/';
$pdfFilePath = $uploadedPath . $record['policy_pdf_file_name'];
$mdFileName = preg_replace('/\.pdf$/i', '.md', $record['policy_pdf_file_name']);
$mdFilePath = $mdUploadedPath . $mdFileName;
if (!file_exists($pdfFilePath)) {
log_message('info',"Error: File not found at {$pdfFilePath}");
if($return == true)
{
return $this->respond(['status'=>"failed", 'message'=> "File not found at {$filePath}"], 200);
return $this->respond(['status'=>"failed", 'message'=> "File not found at {$pdfFilePath}"], 200);
}else{
return ['status'=>"failed", 'message'=> "File not found at {$filePath}"];
return ['status'=>"failed", 'message'=> "File not found at {$pdfFilePath}"];
}
}
$markdownResult = convert_policy_pdf_to_markdown($pdfFilePath);
if ($markdownResult['status'] !== 'success') {
log_message('info', 'Policy PDF to markdown conversion failed: ' . $markdownResult['message']);
if ($return == true) {
return $this->respond(['status' => 'failed', 'message' => $markdownResult['message']], 200);
}
return ['status' => 'failed', 'message' => $markdownResult['message']];
}
if (!file_exists($mdFilePath)) {
log_message('info',"Error: Markdown file not found at {$mdFilePath}");
if($return == true)
{
return $this->respond(['status'=>"failed", 'message'=> "Markdown file not found at {$mdFilePath}"], 200);
}else{
return ['status'=>"failed", 'message'=> "Markdown file not found at {$mdFilePath}"];
}
}
$filePath = $mdFilePath;
// Get the file's MIME type using the finfo extension
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($finfo, $filePath);
finfo_close($finfo);
// Define supported inline MIME types
$supportedInlineMimeTypes = ['application/pdf','text/csv'];
// Gemini inline supports text/plain reliably for markdown files
if (!in_array($mimeType, ['text/plain', 'text/markdown', 'text/x-markdown'], true)) {
$mimeType = 'text/plain';
}
// Read the file content and encode it to Base64
$fileContent = file_get_contents($filePath);
$base64Content = base64_encode($fileContent);
// The prompt you want to send to the model
// $prompt = "give me a json with emp data like name,age,dob,mobile and email. only json not any explanations";
$prompt = "Read the following motor policy pdf document and convert into JSON format as sample specified. Give me only JSON,not any explanations.while pick up premium break up give own damage, third party ,personal accident and taxes as mentioned in JSON format.Notes:vehicle_type should be like Two Wheeler,Four Feeler,Good Vehicle,Bus, Tractor,Commercial Vehicle.rto_state_code is first two char of reg_no and rto_city_code 3rd & 4th char of reg_no and it should be two digit numeric code. Any date should be in mysql date format.(note : while fetching TP premium do not add PA AMOUNT)";
// Define supported inline MIME types
$supportedInlineMimeTypes = ['application/pdf', 'text/csv', 'text/plain', 'text/markdown', 'text/x-markdown'];
$prompt = "Read the following motor policy document and convert into JSON format as sample specified. Give me only JSON,not any explanations.while pick up premium break up give own damage, third party ,personal accident and taxes as mentioned in JSON format.Notes:vehicle_type should be like Two Wheeler,Four Feeler,Good Vehicle,Bus, Tractor,Commercial Vehicle.rto_state_code is first two char of reg_no and rto_city_code 3rd & 4th char of reg_no and it should be two digit numeric code. Any date should be in mysql date format.(note : while fetching TP premium do not add PA AMOUNT)";
$prompt .= '"{\"policy\":{\"intermediary_name\":\"\",\"policy_number\":\"\",\"issue_date\":\"\",\"period\":{\"start\":\"\",\"end\":\"\"},\"insurer\":\"\",\"previous_policy_number\":\"\"},\"insured\":{\"name\":\"\",\"father_name\":\"\",\"address\":[\"\"],\"mobile\":\"\",\"id_proofs\":{\"aadhaar\":\"\",\"pan\":\"\"}},\"vehicle\":{\"reg_no\":\"\",\"rto_state_code\":\"\",\"rto_city_code\":\"\",\"weight\":\"\",\"fuel_type\":\"\",\"date_of_registration\":\"\",\"year_of_manufacture\":\"\",\"engine_no\":\"\",\"chassis_no\":\"\",\"make\":\"\",\"model\":\"\",\"year\":\"\",\"cubic_capacity\":\"\",\"vehicle_type\":\"\"},\"rto\":\"\",\"premium\":{\"tp\":0,\"od\":0,\"pa\":0,\"taxes\":{\"cgst\":\"\",\"sgst\":\"\",\"igst\":\"\"},\"total\":0,\"in_words\":\"\"},\"endorsements\":[{\"code\":\"\",\"desc\":\"\"}]}"';
$payloadPart = null;
@ -865,10 +888,21 @@ class PolicyController extends ResourceController
$text_part = [
"text" => $prompt
];
// Conditionally handle the file upload based on MIME type
if (in_array($mimeType, $supportedInlineMimeTypes)) {
// Handle PDF as inline data
// Read saved markdown file from policy_md directory
$fileContent = file_get_contents($filePath);
if ($fileContent === false || trim($fileContent) === '') {
log_message('info', "Markdown file is empty at {$filePath}");
if ($return == true) {
return $this->respond(['status' => 'failed', 'message' => "Markdown file is empty at {$filePath}"], 200);
}
return ['status' => 'failed', 'message' => "Markdown file is empty at {$filePath}"];
}
$base64Content = base64_encode($fileContent);
$payloadPart = [
"inlineData" => [
@ -883,33 +917,15 @@ class PolicyController extends ResourceController
$payloadPart
]
];
}
// else {
// // Handle Excel/CSV using the Files API
// // echo "Detected unsupported inline MIME type ({$mimeType}). Uploading via Files API...\n";
// $fileInfo = $this->uploadFileToGemini($filePath, $apiKey); // Pass apiKey
// // print_r($fileInfo);
// // The file part, using the URI from the Files API upload
// $file_part = [
// "fileData" => [
// "fileUri" => $fileInfo['uri'],
// "mimeType" => $fileInfo['mimeType']
// ]
// ];
// // The full content array, containing both parts
// $content_parts = [
// "parts" => [
// $text_part,
// $file_part
// ]
// ];
// }
} else {
log_message('info', "Unsupported inline MIME type ({$mimeType}) for markdown file.");
if($return == true)
{
return $this->respond(['status'=>"failed", 'message'=> "Unsupported inline MIME type ({$mimeType})"], 200);
}else{
return ['status'=>"failed", 'message'=> "Unsupported inline MIME type ({$mimeType})"];
}
}
// The final JSON payload
$data = [

View File

@ -0,0 +1,196 @@
<?php
if (!function_exists('policy_md_upload_path')) {
/**
* Full path to the saved markdown file for a policy PDF file name.
*/
function policy_md_upload_path(string $pdfFileName): string
{
$mdFileName = preg_replace('/\.pdf$/i', '.md', $pdfFileName);
if ($mdFileName === $pdfFileName) {
$mdFileName .= '.md';
}
return WRITEPATH . 'uploads/policy/policy_md/' . $mdFileName;
}
}
if (!function_exists('policy_pdf_md_path')) {
/**
* Resolve markdown path using the same base name as the PDF file.
* e.g. 1764999905_abc.pdf -> policy_md/1764999905_abc.md
*/
function policy_pdf_md_path(string $pdfPath): string
{
return policy_md_upload_path(basename($pdfPath));
}
}
if (!function_exists('policy_md_is_valid')) {
/**
* Validate that markdown content looks like extracted policy text.
*/
function policy_md_is_valid(string $content): bool
{
$content = trim($content);
if ($content === '' || strlen($content) < 500) {
return false;
}
$errorMarkers = [
'pdftotext:',
'GLIBCXX_',
'CXXABI_',
'no version information available',
];
foreach ($errorMarkers as $marker) {
if (stripos($content, $marker) !== false) {
return false;
}
}
return true;
}
}
if (!function_exists('policy_pdf_extract_text')) {
/**
* Extract plain text from a PDF using pdftotext (poppler).
* Uses a clean environment so LAMPP lib paths do not break pdftotext.
*/
function policy_pdf_extract_text(string $pdfPath): string
{
$pdftotext = getenv('PDFTOTEXT_BIN') ?: '/usr/bin/pdftotext';
if (!is_executable($pdftotext) && $pdftotext === '/usr/bin/pdftotext') {
$which = trim((string) shell_exec('command -v pdftotext 2>/dev/null'));
if ($which !== '') {
$pdftotext = $which;
}
}
$command = sprintf(
'env -i PATH=/usr/bin:/bin LD_LIBRARY_PATH= %s -layout %s - 2>&1',
escapeshellcmd($pdftotext),
escapeshellarg($pdfPath)
);
$text = shell_exec($command);
if (!is_string($text)) {
return '';
}
$text = trim($text);
if (!policy_md_is_valid($text)) {
log_message('error', 'PDF text extraction failed or returned invalid content for: ' . $pdfPath);
return '';
}
return $text;
}
}
if (!function_exists('convert_policy_pdf_to_markdown')) {
/**
* Convert a policy PDF to markdown, save to policy_md/, then read back from disk.
*
* @return array{status: string, message: string, content?: string, md_path?: string, md_file_name?: string}
*/
function convert_policy_pdf_to_markdown(string $pdfPath, bool $forceRefresh = false): array
{
if (!is_file($pdfPath)) {
return [
'status' => 'failed',
'message' => "PDF file not found at {$pdfPath}",
];
}
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($finfo, $pdfPath);
finfo_close($finfo);
if ($mimeType !== 'application/pdf') {
return [
'status' => 'failed',
'message' => "Unsupported file type ({$mimeType}). Only PDF is supported.",
];
}
$mdPath = policy_pdf_md_path($pdfPath);
$mdFileName = basename($mdPath);
$mdDir = dirname($mdPath);
if (!is_dir($mdDir) && !mkdir($mdDir, 0777, true) && !is_dir($mdDir)) {
return [
'status' => 'failed',
'message' => "Unable to create markdown directory at {$mdDir}",
];
}
if (!$forceRefresh && is_file($mdPath) && filemtime($mdPath) >= filemtime($pdfPath)) {
$cached = file_get_contents($mdPath);
if ($cached !== false && policy_md_is_valid($cached)) {
log_message('info', "Using cached policy markdown: {$mdPath}");
return [
'status' => 'success',
'message' => 'Cached markdown loaded from disk',
'content' => $cached,
'md_path' => $mdPath,
'md_file_name' => $mdFileName,
];
}
if ($cached !== false) {
log_message('info', "Invalid cached markdown detected, reconverting: {$mdPath}");
@unlink($mdPath);
}
}
$extractedText = policy_pdf_extract_text($pdfPath);
if ($extractedText === '') {
return [
'status' => 'failed',
'message' => 'PDF text extraction failed. The file may be scanned, image-based, or pdftotext is unavailable on the server.',
];
}
$markdown = "# Motor Policy Document\n\n" . $extractedText;
if (file_put_contents($mdPath, $markdown) === false) {
return [
'status' => 'failed',
'message' => "Failed to write markdown file at {$mdPath}",
];
}
$savedContent = file_get_contents($mdPath);
if ($savedContent === false || !policy_md_is_valid($savedContent)) {
@unlink($mdPath);
return [
'status' => 'failed',
'message' => 'Saved markdown file is invalid after conversion',
];
}
log_message('info', "Policy PDF converted to markdown: {$mdPath}");
return [
'status' => 'success',
'message' => 'PDF converted to markdown and saved to disk',
'content' => $savedContent,
'md_path' => $mdPath,
'md_file_name' => $mdFileName,
];
}
}