210 lines
9.3 KiB
PHP
210 lines
9.3 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Support\Str;
|
|
use setasign\Fpdi\Fpdi;
|
|
use SimpleSoftwareIO\QrCode\Facades\QrCode;
|
|
|
|
class ConclusionController extends Controller
|
|
{
|
|
public function create($id, $type)
|
|
{
|
|
// type is enum name: 'AUTO' or 'ESTATE'
|
|
$orderType = $type === 'AUTO' ? 'auto_' : 'estate_';
|
|
$table = $type === 'AUTO' ? 'auto_orders' : 'estate_orders';
|
|
|
|
$order = DB::table($table . ' as o')
|
|
->selectRaw('o.*, o.ordered_customer as customer, CONCAT_WS(\' \', o.owner_last_name, o.owner_first_name, o.owner_patronymic) as owner')
|
|
->where('o.id', $id)->first();
|
|
|
|
if ($order) {
|
|
$dillerUser = $order->diller_id ? DB::table('users')->find($order->diller_id) : null;
|
|
$order->diller = $dillerUser->name ?? '';
|
|
}
|
|
|
|
return view('conclusion.add', compact('id', 'type', 'order'));
|
|
}
|
|
|
|
public function store(Request $request)
|
|
{
|
|
$orderId = $request->input('order_id');
|
|
$orderType = $request->input('order_type'); // 'AUTO' or 'ESTATE'
|
|
$dbType = $orderType === 'AUTO' ? 'auto_' : 'estate_';
|
|
$table = $orderType === 'AUTO' ? 'auto_orders' : 'estate_orders';
|
|
|
|
// Update order prices
|
|
$updateData = ['updated_at' => now()];
|
|
if ($request->filled('object_price')) {
|
|
$updateData['object_price'] = preg_replace('/\D/', '', $request->object_price);
|
|
}
|
|
if ($request->filled('price')) {
|
|
$updateData['price'] = preg_replace('/\D/', '', $request->price);
|
|
}
|
|
DB::table($table)->where('id', $orderId)->update($updateData);
|
|
|
|
// Create debit if is_diller = yes
|
|
if ($request->input('is_diller') === 'yes') {
|
|
$order = DB::table($table)->find($orderId);
|
|
DB::table('debits')->insert([
|
|
'order_id' => $orderId,
|
|
'order_type' => $dbType,
|
|
'appraiser_id' => auth()->id(),
|
|
'cost' => $order->cost ?? 0,
|
|
'status' => 'nopaid',
|
|
'expired' => $request->input('expired'),
|
|
'customer' => $order->ordered_customer ?? '',
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
}
|
|
|
|
// Handle PDF file upload with QR watermark
|
|
if ($request->hasFile('file')) {
|
|
$file = $request->file('file');
|
|
$ext = strtolower($file->getClientOriginalExtension());
|
|
$name = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
|
|
$size = $file->getSize();
|
|
|
|
$dir = 'public/attachments/' . $dbType . $orderId;
|
|
Storage::makeDirectory($dir);
|
|
|
|
$tmpPath = $file->getPathname();
|
|
$outputName = Str::uuid() . '.pdf';
|
|
$outputPath = storage_path('app/' . $dir . '/' . $outputName);
|
|
|
|
if ($ext === 'pdf') {
|
|
// Add QR watermark to PDF
|
|
try {
|
|
$qrPath = storage_path('app/public/attachments/' . $dbType . $orderId . '/qr.png');
|
|
if (!file_exists($qrPath)) {
|
|
Storage::makeDirectory('public/attachments/' . $dbType . $orderId);
|
|
$cleanType = strtolower($orderType);
|
|
$qrContent = route('qr.verify', ['type' => $cleanType, 'id' => $orderId]);
|
|
$qrImage = QrCode::format('png')->size(150)->generate($qrContent);
|
|
file_put_contents($qrPath, $qrImage);
|
|
chmod($qrPath, 0644);
|
|
}
|
|
|
|
// Convert PDF to 1.4 compatible format so FPDI can parse any PDF version
|
|
$gsTmp = tempnam(sys_get_temp_dir(), 'gs_') . '.pdf';
|
|
exec('gs -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -sOutputFile=' . escapeshellarg($gsTmp) . ' ' . escapeshellarg($tmpPath) . ' 2>/dev/null', $gsOut, $gsCode);
|
|
if ($gsCode === 0 && file_exists($gsTmp) && filesize($gsTmp) > 0) {
|
|
$tmpPath = $gsTmp;
|
|
}
|
|
|
|
$pdf = new Fpdi();
|
|
$pageCount = $pdf->setSourceFile($tmpPath);
|
|
$qrSize = 30; // mm
|
|
|
|
for ($i = 1; $i <= $pageCount; $i++) {
|
|
$tpl = $pdf->importPage($i);
|
|
$size2 = $pdf->getTemplateSize($tpl);
|
|
$pdf->AddPage($size2['orientation'], [$size2['width'], $size2['height']]);
|
|
$pdf->useTemplate($tpl);
|
|
|
|
if ($i === 1) {
|
|
// First page: right side, in the blank area below header separator lines
|
|
$sz = 35;
|
|
$qrX = $size2['width'] - $sz - 18;
|
|
$qrY = 15;
|
|
} else {
|
|
// Other pages: bottom-right
|
|
$sz = 22;
|
|
$qrX = $size2['width'] - $sz - 8;
|
|
$qrY = $size2['height'] - $sz - 6;
|
|
}
|
|
$pdf->SetFillColor(255, 255, 255);
|
|
$pdf->Rect($qrX - 1, $qrY - 1, $sz + 2, $sz + 2, 'F');
|
|
$pdf->Image($qrPath, $qrX, $qrY, $sz, $sz);
|
|
}
|
|
|
|
// Append certificates from the database
|
|
$certificates = DB::table('certificates')->orderBy('sort')->get();
|
|
foreach ($certificates as $certificate) {
|
|
$certPath = storage_path('app/' . $certificate->path);
|
|
if (file_exists($certPath)) {
|
|
$extCert = strtolower(pathinfo($certPath, PATHINFO_EXTENSION));
|
|
if ($extCert === 'pdf') {
|
|
$certPageCount = $pdf->setSourceFile($certPath);
|
|
for ($j = 1; $j <= $certPageCount; $j++) {
|
|
$tplCert = $pdf->importPage($j);
|
|
$sizeCert = $pdf->getTemplateSize($tplCert);
|
|
$pdf->AddPage($sizeCert['orientation'], [$sizeCert['width'], $sizeCert['height']]);
|
|
$pdf->useTemplate($tplCert);
|
|
$cqX = $sizeCert['width'] - 22 - 8;
|
|
$cqY = $sizeCert['height'] - 22 - 6;
|
|
$pdf->SetFillColor(255, 255, 255);
|
|
$pdf->Rect($cqX - 1, $cqY - 1, 24, 24, 'F');
|
|
$pdf->Image($qrPath, $cqX, $cqY, 22, 22);
|
|
}
|
|
} elseif (in_array($extCert, ['jpg', 'jpeg', 'png'])) {
|
|
$pdf->AddPage('P', 'A4');
|
|
$pdf->Image($certPath, 0, 0, 210, 297);
|
|
$pdf->SetFillColor(255, 255, 255);
|
|
$pdf->Rect(210 - 22 - 8 - 1, 297 - 22 - 6 - 1, 24, 24, 'F');
|
|
$pdf->Image($qrPath, 210 - 22 - 8, 297 - 22 - 6, 22, 22);
|
|
}
|
|
}
|
|
}
|
|
|
|
$pdf->Output('F', $outputPath);
|
|
} catch (\Exception $e) {
|
|
\Illuminate\Support\Facades\Log::error('ConclusionController PDF/QR failed: ' . $e->getMessage(), [
|
|
'order_id' => $orderId, 'type' => $orderType, 'file' => $e->getFile(), 'line' => $e->getLine(),
|
|
]);
|
|
copy($tmpPath, $outputPath);
|
|
}
|
|
} else {
|
|
$file->move(storage_path('app/' . $dir), $outputName);
|
|
}
|
|
|
|
$storagePath = '/storage/attachments/' . $dbType . $orderId . '/' . $outputName;
|
|
|
|
DB::table('files')->insert([
|
|
'id' => (string) Str::uuid(),
|
|
'path' => $storagePath,
|
|
'extension' => $ext,
|
|
'order_id' => $orderId,
|
|
'order_type' => 'conclusion_',
|
|
'type' => 'conclusion',
|
|
'name' => $name,
|
|
'size' => round($size / 1024 / 1024, 2),
|
|
'size_in_bytes' => $size,
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
|
|
DB::table($table)->where('id', $orderId)->update([
|
|
'status' => \App\Enums\OrderStatusEnum::FINISHED->name,
|
|
'updated_at' => now(),
|
|
]);
|
|
}
|
|
|
|
$route = $orderType === 'AUTO' ? 'auto.show' : 'estate.show';
|
|
return redirect()->route($route, $orderId);
|
|
}
|
|
|
|
public function reject(Request $request)
|
|
{
|
|
$orderId = $request->input('order_id');
|
|
$orderType = $request->input('order_type'); // 'AUTO' or 'ESTATE'
|
|
$table = $orderType === 'AUTO' ? 'auto_orders' : 'estate_orders';
|
|
|
|
DB::table($table)->where('id', $orderId)->update([
|
|
'status' => 'rejected',
|
|
'updated_at' => now(),
|
|
]);
|
|
|
|
return redirect()->back();
|
|
}
|
|
|
|
public function testWaterMark()
|
|
{
|
|
return view('conclusion.watermark');
|
|
}
|
|
}
|