829 lines
33 KiB
PHP
829 lines
33 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers\Api;
|
||
|
||
use App\Http\Controllers\Controller;
|
||
use App\Models\Annotation;
|
||
use App\Models\DocumentRevision;
|
||
use App\Models\WeldLog;
|
||
use Illuminate\Http\Request;
|
||
use Illuminate\Http\JsonResponse;
|
||
use Illuminate\Support\Facades\DB;
|
||
use Illuminate\Support\Facades\Validator;
|
||
use Illuminate\Support\Facades\Schema;
|
||
|
||
class AnnotationController extends Controller
|
||
{
|
||
public function store(Request $request): JsonResponse
|
||
{
|
||
$request->validate([
|
||
'annotations' => 'required|array',
|
||
'annotations.*.shape_id' => 'required|string',
|
||
'annotations.*.spool_no' => 'nullable|string',
|
||
'annotations.*.joint_type' => 'nullable|string',
|
||
'annotations.*.welder_id' => 'nullable|string',
|
||
'annotations.*.classification' => 'nullable|string',
|
||
'annotations.*.page_number' => 'required|integer',
|
||
'annotations.*.x_coordinate' => 'required|numeric',
|
||
'annotations.*.y_coordinate' => 'required|numeric',
|
||
'annotations.*.width' => 'required|numeric',
|
||
'annotations.*.height' => 'required|numeric',
|
||
'annotations.*.shape_type' => 'required|in:rect,circle,triangle,spool,weld,shop_weld,leader_line,text,line',
|
||
'annotations.*.pdf_file_path' => 'required|string',
|
||
'annotations.*.created_by' => 'required|integer',
|
||
'annotations.*.original_start_point' => 'nullable|string',
|
||
'annotations.*.connected_shape_id' => 'nullable|string',
|
||
]);
|
||
|
||
try {
|
||
$annotations = [];
|
||
foreach ($request->annotations as $annotationData) {
|
||
// Check if annotation already exists
|
||
$existingAnnotation = Annotation::where('shape_id', $annotationData['shape_id'])->first();
|
||
|
||
if ($existingAnnotation) {
|
||
// Update existing annotation
|
||
$existingAnnotation->update($annotationData);
|
||
$annotations[] = $existingAnnotation;
|
||
} else {
|
||
// Create new annotation
|
||
$annotations[] = Annotation::create($annotationData);
|
||
}
|
||
}
|
||
|
||
return response()->json([
|
||
'success' => true,
|
||
'data' => $annotations,
|
||
'message' => 'Annotations saved successfully!'
|
||
], 201);
|
||
} catch (\Exception $e) {
|
||
return response()->json([
|
||
'success' => false,
|
||
'error' => $e->getMessage(),
|
||
'message' => 'Failed to save annotations'
|
||
], 500);
|
||
}
|
||
}
|
||
|
||
public function index(Request $request): JsonResponse
|
||
{
|
||
$pdfFile = $request->get('pdf_file');
|
||
|
||
$annotations = Annotation::when($pdfFile, function ($query, $pdfFile) {
|
||
return $query->where('pdf_file_path', $pdfFile);
|
||
})
|
||
->where('is_active', 1)
|
||
->orderBy('created_at', 'asc')
|
||
->get();
|
||
|
||
return response()->json([
|
||
'success' => true,
|
||
'data' => $annotations
|
||
]);
|
||
}
|
||
|
||
|
||
public function show(Annotation $annotation): JsonResponse
|
||
{
|
||
return response()->json([
|
||
'success' => true,
|
||
'data' => $annotation
|
||
]);
|
||
}
|
||
|
||
public function update(Request $request, Annotation $annotation): JsonResponse
|
||
{
|
||
$request->validate([
|
||
'spool_no' => 'nullable|string',
|
||
'joint_type' => 'nullable|string',
|
||
'welder_id' => 'nullable|string',
|
||
'classification' => 'nullable|string',
|
||
]);
|
||
|
||
$annotation->update($request->only(['spool_no', 'joint_type', 'welder_id', 'classification']));
|
||
|
||
return response()->json([
|
||
'success' => true,
|
||
'data' => $annotation
|
||
]);
|
||
}
|
||
|
||
public function destroy(Annotation $annotation): JsonResponse
|
||
{
|
||
$annotation->delete();
|
||
|
||
return response()->json([
|
||
'success' => true,
|
||
'message' => 'Annotation deleted successfully'
|
||
]);
|
||
}
|
||
|
||
public function deleteMultiple(Request $request): JsonResponse
|
||
{
|
||
$request->validate([
|
||
'shape_ids' => 'required|array',
|
||
'shape_ids.*' => 'required|string',
|
||
'pdf_file' => 'required|string',
|
||
'page_number' => 'required|integer'
|
||
]);
|
||
|
||
try {
|
||
$deletedCount = Annotation::whereIn('shape_id', $request->shape_ids)
|
||
->where('pdf_file_path', $request->pdf_file)
|
||
->where('page_number', $request->page_number)
|
||
->delete();
|
||
|
||
return response()->json([
|
||
'success' => true,
|
||
'deleted_count' => $deletedCount,
|
||
'message' => "Successfully deleted {$deletedCount} annotations from page {$request->page_number}"
|
||
]);
|
||
} catch (\Exception $e) {
|
||
return response()->json([
|
||
'success' => false,
|
||
'error' => $e->getMessage(),
|
||
'message' => 'Failed to delete annotations'
|
||
], 500);
|
||
}
|
||
}
|
||
|
||
public function sync(Request $request): JsonResponse
|
||
{
|
||
$request->validate([
|
||
'annotations' => 'required|array',
|
||
'pdf_file' => 'required|string',
|
||
'page_number' => 'required|integer'
|
||
]);
|
||
|
||
try {
|
||
$pdfFile = $request->pdf_file;
|
||
$pageNumber = $request->page_number;
|
||
$userId = $request->user_id ?? auth()->id() ?? 1;
|
||
|
||
$lastVersion = Annotation::where('pdf_file_path', 'like', '%' . basename($pdfFile) . '%')
|
||
->where('page_number', $pageNumber)
|
||
->max('version');
|
||
$newVersion = ($lastVersion ?? 0) + 1;
|
||
|
||
$saved = [];
|
||
foreach ($request->annotations as $data) {
|
||
// Use updateOrCreate to prevent duplicates - update existing annotation with same shape_id, pdf_file_path, page_number
|
||
// Only create new version if shape_id doesn't exist in current version
|
||
$annotation = Annotation::updateOrCreate(
|
||
[
|
||
'shape_id' => $data['shape_id'],
|
||
'pdf_file_path' => $pdfFile,
|
||
'page_number' => $pageNumber,
|
||
'version' => $newVersion,
|
||
'is_active' => 1
|
||
],
|
||
[
|
||
'spool_no' => $data['spool_no'] ?? null,
|
||
'joint_type' => $data['joint_type'] ?? null,
|
||
'welder_id' => $data['welder_id'] ?? null,
|
||
'classification' => $data['classification'] ?? null,
|
||
'x_coordinate' => $data['x_coordinate'] ?? 0,
|
||
'y_coordinate' => $data['y_coordinate'] ?? 0,
|
||
'width' => $data['width'] ?? 0,
|
||
'height' => $data['height'] ?? 0,
|
||
'shape_type' => $data['shape_type'] ?? 'rect',
|
||
'qr_code_data' => $data['qr_code_data'] ?? null,
|
||
'created_by' => $data['created_by'] ?? $userId,
|
||
'original_start_point' => $data['original_start_point'] ?? null,
|
||
'connected_shape_id' => $data['connected_shape_id'] ?? null,
|
||
'stroke_color' => $data['stroke_color'] ?? '#000000',
|
||
'stroke_width' => $data['stroke_width'] ?? 2,
|
||
]
|
||
);
|
||
$saved[] = $annotation;
|
||
}
|
||
|
||
return response()->json([
|
||
'success' => true,
|
||
'message' => "Page synced successfully as version {$newVersion}",
|
||
'version' => $newVersion,
|
||
'data' => $saved
|
||
]);
|
||
} catch (\Exception $e) {
|
||
return response()->json([
|
||
'success' => false,
|
||
'error' => $e->getMessage(),
|
||
'message' => 'Failed to sync annotations'
|
||
], 500);
|
||
}
|
||
}
|
||
|
||
public function exportPDF(Request $request)
|
||
{
|
||
try {
|
||
$request->validate([
|
||
'pdf_file' => 'required|string',
|
||
'annotations' => 'required|array',
|
||
'canvas_image' => 'required|string',
|
||
'export_format' => 'required|string',
|
||
// Optional parameters for saving to Document Revision
|
||
'save_to_revision' => 'nullable|boolean',
|
||
'stage' => 'nullable|in:pdf_spool_iso,pdf_as_build',
|
||
'drawing_no' => 'nullable|string',
|
||
'revision_id' => 'nullable|integer',
|
||
]);
|
||
|
||
// Canvas image'i decode et
|
||
$imageData = $request->canvas_image;
|
||
|
||
// Remove data:image/png;base64, part
|
||
$imageData = str_replace('data:image/png;base64,', '', $imageData);
|
||
$imageData = str_replace(' ', '+', $imageData);
|
||
$decodedImage = base64_decode($imageData);
|
||
|
||
// Temporary image file oluştur
|
||
$tempImagePath = storage_path('app/temp_export_' . time() . '.png');
|
||
file_put_contents($tempImagePath, $decodedImage);
|
||
|
||
// mPDF ile PDF oluştur
|
||
$mpdf = new \Mpdf\Mpdf([
|
||
'mode' => 'utf-8',
|
||
'format' => 'A4-L', // Landscape orientation
|
||
'margin_left' => 0,
|
||
'margin_right' => 0,
|
||
'margin_top' => 0,
|
||
'margin_bottom' => 0
|
||
]);
|
||
|
||
// Image'i PDF'e ekle
|
||
$html = '<img src="' . $tempImagePath . '" style="width: 100%; height: auto;" />';
|
||
$mpdf->WriteHTML($html);
|
||
|
||
// Generate filename
|
||
$originalFilename = basename($request->pdf_file, '.pdf');
|
||
$filename = 'annotated_' . $originalFilename . '_' . time() . '.pdf';
|
||
|
||
// Temporary file'ı sil
|
||
if (file_exists($tempImagePath)) {
|
||
unlink($tempImagePath);
|
||
}
|
||
|
||
// Check if we should save to Document Revision
|
||
$saveToRevision = $request->input('save_to_revision', false);
|
||
|
||
if ($saveToRevision && $request->filled('stage') && $request->filled('drawing_no')) {
|
||
$stage = $request->input('stage');
|
||
$drawingNo = $request->input('drawing_no');
|
||
$revisionId = $request->input('revision_id');
|
||
|
||
// Determine storage folder based on stage
|
||
$folderMap = [
|
||
'pdf_spool_iso' => 'storage/documents/001_Drawings/002_Iso',
|
||
'pdf_as_build' => 'storage/documents/001_Drawings/003_As_Build(ID)',
|
||
];
|
||
|
||
$folder = $folderMap[$stage] ?? 'storage/documents/001_Drawings/003_As_Build(ID)';
|
||
$storagePath = public_path($folder);
|
||
|
||
// Ensure directory exists
|
||
if (!is_dir($storagePath)) {
|
||
mkdir($storagePath, 0755, true);
|
||
}
|
||
|
||
// Generate unique filename with drawing number
|
||
$safeDrawingNo = preg_replace('/[^A-Za-z0-9\-\_\.]/', '_', $drawingNo);
|
||
$savedFilename = $safeDrawingNo . '_annotated_' . date('Ymd_His') . '.pdf';
|
||
$fullSavePath = $storagePath . '/' . $savedFilename;
|
||
|
||
// Save PDF to storage
|
||
$pdfContent = $mpdf->Output('', 'S');
|
||
file_put_contents($fullSavePath, $pdfContent);
|
||
|
||
\Log::info('PDF saved to storage', [
|
||
'path' => $fullSavePath,
|
||
'stage' => $stage,
|
||
'drawing_no' => $drawingNo
|
||
]);
|
||
|
||
// Update document_revisions table
|
||
$relativePath = $folder . '/' . $savedFilename;
|
||
|
||
$query = DocumentRevision::query()
|
||
->where('drawing_no', $drawingNo);
|
||
|
||
if ($revisionId) {
|
||
$query->where('id', $revisionId);
|
||
}
|
||
|
||
$updatedRows = $query->update([
|
||
$stage => $relativePath,
|
||
]);
|
||
|
||
\Log::info('Document revision updated', [
|
||
'updated_rows' => $updatedRows,
|
||
'stage' => $stage,
|
||
'pdf_path' => $relativePath
|
||
]);
|
||
|
||
return response()->json([
|
||
'success' => true,
|
||
'message' => 'PDF saved to ' . $stage . ' successfully',
|
||
'pdf_path' => $relativePath,
|
||
'updated_rows' => $updatedRows,
|
||
'filename' => $savedFilename,
|
||
]);
|
||
}
|
||
|
||
// Return as download (default behavior)
|
||
return response($mpdf->Output($filename, 'S'), 200)
|
||
->header('Content-Type', 'application/pdf')
|
||
->header('Content-Disposition', 'attachment; filename="' . $filename . '"');
|
||
|
||
} catch (\Exception $e) {
|
||
\Log::error('Export PDF failed', [
|
||
'error' => $e->getMessage(),
|
||
'trace' => $e->getTraceAsString()
|
||
]);
|
||
return response()->json([
|
||
'success' => false,
|
||
'error' => $e->getMessage(),
|
||
'message' => 'Failed to export PDF'
|
||
], 500);
|
||
}
|
||
}
|
||
|
||
public function actionHistory(Request $request): JsonResponse
|
||
{
|
||
$pdfFile = $request->query('pdf_file');
|
||
|
||
$logs = Annotation::query()
|
||
->with(['updatedUser:id,name'])
|
||
->when($pdfFile, fn($q) => $q->where('pdf_file_path', 'like', "%{$pdfFile}%"))
|
||
->orderByDesc('updated_at')
|
||
->select('version', 'updated_by', 'updated_at', 'is_active')
|
||
->limit(200)
|
||
->get();
|
||
|
||
$grouped = $logs
|
||
->sortByDesc('updated_at')
|
||
->groupBy('version')
|
||
->map(fn($items) => $items->sortByDesc('updated_at')->first());
|
||
|
||
return response()->json([
|
||
'success' => true,
|
||
'data' => $grouped->map(fn($log) => [
|
||
'version' => $log->version,
|
||
'user' => $log->updatedUser->name ?? 'System',
|
||
'action' => $log->version == 1 ? 'New Record' : 'Updated',
|
||
'time' => $log->updated_at?->format('Y-m-d H:i:s'),
|
||
])->values(),
|
||
]);
|
||
}
|
||
|
||
public function versionAnnotations(Request $request): JsonResponse
|
||
{
|
||
$request->validate([
|
||
'pdf_file' => 'required|string',
|
||
'page_number' => 'required|integer',
|
||
'version' => 'required|integer',
|
||
]);
|
||
|
||
$pdfFile = $request->pdf_file;
|
||
$page = (int) $request->page_number;
|
||
$version = (int) $request->version;
|
||
|
||
$items = Annotation::where('pdf_file_path', 'like', '%' . basename($pdfFile) . '%')
|
||
->where('page_number', $page)
|
||
->where('version', $version)
|
||
->orderBy('id', 'asc')
|
||
->get();
|
||
|
||
return response()->json([
|
||
'success' => true,
|
||
'data' => $items,
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* Save joint data to Base Weldmap (weld_logs table)
|
||
* Phase 3.2: Base Weldmap Integration
|
||
*/
|
||
public function saveJointData(Request $request): JsonResponse
|
||
{
|
||
$validator = Validator::make($request->all(), [
|
||
'drawing_number' => 'required|string',
|
||
'joint_data' => 'required|array',
|
||
'joint_data.*.joint_no' => 'nullable|string',
|
||
'joint_data.*.type_of_joint' => 'nullable|string|in:F,S',
|
||
'joint_data.*.type_of_welds' => 'nullable|string',
|
||
'joint_data.*.welding_date' => 'nullable|date',
|
||
'joint_data.*.spool_no1' => 'nullable|string',
|
||
'joint_data.*.spool_no2' => 'nullable|string',
|
||
'joint_data.*.pose_no1' => 'nullable|string',
|
||
'joint_data.*.pose_no2' => 'nullable|string',
|
||
'joint_data.*.member1' => 'nullable|string',
|
||
'joint_data.*.member2' => 'nullable|string',
|
||
'joint_data.*.material' => 'nullable|string',
|
||
'joint_data.*.dia1' => 'nullable|numeric',
|
||
'joint_data.*.dia2' => 'nullable|numeric',
|
||
'joint_data.*.nps1' => 'nullable|string',
|
||
'joint_data.*.nps2' => 'nullable|string',
|
||
'joint_data.*.thickness1' => 'nullable|numeric',
|
||
'joint_data.*.thickness2' => 'nullable|numeric',
|
||
]);
|
||
|
||
if ($validator->fails()) {
|
||
return response()->json([
|
||
'success' => false,
|
||
'message' => 'Validation failed',
|
||
'errors' => $validator->errors()
|
||
], 422);
|
||
}
|
||
|
||
try {
|
||
DB::beginTransaction();
|
||
|
||
$drawingNumber = $request->drawing_number;
|
||
$jointDataArray = $request->joint_data;
|
||
$savedJoints = [];
|
||
|
||
foreach ($jointDataArray as $jointData) {
|
||
// Map widget form data to weld_logs table structure
|
||
$weldLogData = [
|
||
'iso_number' => $drawingNumber,
|
||
'no_of_the_joint_as_per_as_built_survey' => $jointData['joint_no'] ?? null,
|
||
'type_of_joint' => $jointData['type_of_joint'] ?? null,
|
||
'type_of_welds' => $jointData['type_of_welds'] ?? null,
|
||
'welding_date' => $jointData['welding_date'] ?? null,
|
||
];
|
||
|
||
// Handle spool numbers - use spool_number_1/2 if exists, otherwise use spool_number/spool_number2
|
||
if (isset($jointData['spool_no1'])) {
|
||
if (Schema::hasColumn('weld_logs', 'spool_number_1')) {
|
||
$weldLogData['spool_number_1'] = $jointData['spool_no1'];
|
||
} else {
|
||
$weldLogData['spool_number'] = $jointData['spool_no1'];
|
||
}
|
||
}
|
||
if (isset($jointData['spool_no2'])) {
|
||
if (Schema::hasColumn('weld_logs', 'spool_number_2')) {
|
||
$weldLogData['spool_number_2'] = $jointData['spool_no2'];
|
||
} elseif (Schema::hasColumn('weld_logs', 'spool_number2')) {
|
||
$weldLogData['spool_number2'] = $jointData['spool_no2'];
|
||
}
|
||
}
|
||
|
||
// Handle pose numbers - use pose_number_1/2 if exists, otherwise use pose_no_1/2
|
||
if (isset($jointData['pose_no1'])) {
|
||
if (Schema::hasColumn('weld_logs', 'pose_number_1')) {
|
||
$weldLogData['pose_number_1'] = $jointData['pose_no1'];
|
||
} else {
|
||
$weldLogData['pose_no_1'] = $jointData['pose_no1'];
|
||
}
|
||
}
|
||
if (isset($jointData['pose_no2'])) {
|
||
if (Schema::hasColumn('weld_logs', 'pose_number_2')) {
|
||
$weldLogData['pose_number_2'] = $jointData['pose_no2'];
|
||
} else {
|
||
$weldLogData['pose_no_2'] = $jointData['pose_no2'];
|
||
}
|
||
}
|
||
|
||
// Handle members - use member_1/2 if exists, otherwise use member_no_1/2
|
||
if (isset($jointData['member1'])) {
|
||
if (Schema::hasColumn('weld_logs', 'member_1')) {
|
||
$weldLogData['member_1'] = $jointData['member1'];
|
||
} else {
|
||
$weldLogData['member_no_1'] = $jointData['member1'];
|
||
}
|
||
}
|
||
if (isset($jointData['member2'])) {
|
||
if (Schema::hasColumn('weld_logs', 'member_2')) {
|
||
$weldLogData['member_2'] = $jointData['member2'];
|
||
} else {
|
||
$weldLogData['member_no_2'] = $jointData['member2'];
|
||
}
|
||
}
|
||
|
||
// Handle material - use material_1/2 if exists, otherwise use material_no_1/2
|
||
if (isset($jointData['material'])) {
|
||
if (Schema::hasColumn('weld_logs', 'material_1')) {
|
||
$weldLogData['material_1'] = $jointData['material'];
|
||
$weldLogData['material_2'] = $jointData['material'];
|
||
} else {
|
||
$weldLogData['material_no_1'] = $jointData['material'];
|
||
$weldLogData['material_no_2'] = $jointData['material'];
|
||
}
|
||
}
|
||
|
||
// Handle diameter - use dia_1/2 if exists, otherwise use outside_diameter_1/2
|
||
if (isset($jointData['dia1'])) {
|
||
if (Schema::hasColumn('weld_logs', 'dia_1')) {
|
||
$weldLogData['dia_1'] = $jointData['dia1'];
|
||
} else {
|
||
$weldLogData['outside_diameter_1'] = $jointData['dia1'];
|
||
}
|
||
}
|
||
if (isset($jointData['dia2'])) {
|
||
if (Schema::hasColumn('weld_logs', 'dia_2')) {
|
||
$weldLogData['dia_2'] = $jointData['dia2'];
|
||
} else {
|
||
$weldLogData['outside_diameter_2'] = $jointData['dia2'];
|
||
}
|
||
}
|
||
|
||
// Handle NPS - nps_1/2 should exist in both cases
|
||
if (isset($jointData['nps1'])) {
|
||
$weldLogData['nps_1'] = $jointData['nps1'];
|
||
}
|
||
if (isset($jointData['nps2'])) {
|
||
$weldLogData['nps_2'] = $jointData['nps2'];
|
||
}
|
||
|
||
// Handle thickness - use thickness_1/2 if exists, otherwise use wall_thickness_1/2
|
||
if (isset($jointData['thickness1'])) {
|
||
if (Schema::hasColumn('weld_logs', 'thickness_1')) {
|
||
$weldLogData['thickness_1'] = $jointData['thickness1'];
|
||
} else {
|
||
$weldLogData['wall_thickness_1'] = $jointData['thickness1'];
|
||
}
|
||
}
|
||
if (isset($jointData['thickness2'])) {
|
||
if (Schema::hasColumn('weld_logs', 'thickness_2')) {
|
||
$weldLogData['thickness_2'] = $jointData['thickness2'];
|
||
} else {
|
||
$weldLogData['wall_thickness_2'] = $jointData['thickness2'];
|
||
}
|
||
}
|
||
|
||
// Use updateOrCreate to prevent duplicates
|
||
// Match by iso_number and joint_no (if provided)
|
||
// CRITICAL: Try multiple matching strategies to find existing records
|
||
$matchConditions = [
|
||
'iso_number' => $drawingNumber,
|
||
];
|
||
|
||
// CRITICAL: Try to find existing record using multiple strategies
|
||
// Strategy 1: Match by joint_no (e.g., "53A")
|
||
// Strategy 2: Match by draw_joint_no (e.g., "F53A") if joint_no doesn't match
|
||
// Strategy 3: Match by type_of_joint + joint_no combination
|
||
$existingRecord = null;
|
||
|
||
if (!empty($jointData['joint_no'])) {
|
||
$jointNo = trim($jointData['joint_no']);
|
||
|
||
// Strategy 1: Try exact match with joint_no
|
||
$existingRecord = WeldLog::where('iso_number', $drawingNumber)
|
||
->where('no_of_the_joint_as_per_as_built_survey', $jointNo)
|
||
->first();
|
||
|
||
// Strategy 2: If not found, try with draw_joint_no (Type + Joint No, e.g., "F53A")
|
||
if (!$existingRecord && !empty($jointData['draw_joint_no'])) {
|
||
$drawJointNo = trim($jointData['draw_joint_no']);
|
||
$existingRecord = WeldLog::where('iso_number', $drawingNumber)
|
||
->where('no_of_the_joint_as_per_as_built_survey', $drawJointNo)
|
||
->first();
|
||
}
|
||
|
||
// Strategy 3: If still not found, try with type_of_joint + joint_no
|
||
if (!$existingRecord && !empty($jointData['type_of_joint'])) {
|
||
$existingRecord = WeldLog::where('iso_number', $drawingNumber)
|
||
->where('type_of_joint', $jointData['type_of_joint'])
|
||
->where('no_of_the_joint_as_per_as_built_survey', $jointNo)
|
||
->first();
|
||
}
|
||
|
||
// Set match conditions based on what we found
|
||
if ($existingRecord) {
|
||
// If we found an existing record, match by its ID to ensure update
|
||
$matchConditions = [
|
||
'id' => $existingRecord->id
|
||
];
|
||
} else {
|
||
// If no existing record, match by iso_number + joint_no for new record
|
||
$matchConditions['no_of_the_joint_as_per_as_built_survey'] = $jointNo;
|
||
}
|
||
}
|
||
|
||
$weldLog = WeldLog::updateOrCreate(
|
||
$matchConditions,
|
||
$weldLogData
|
||
);
|
||
|
||
$savedJoints[] = $weldLog;
|
||
}
|
||
|
||
DB::commit();
|
||
|
||
return response()->json([
|
||
'success' => true,
|
||
'message' => 'Joint data saved successfully',
|
||
'data' => $savedJoints,
|
||
'count' => count($savedJoints)
|
||
]);
|
||
} catch (\Exception $e) {
|
||
DB::rollBack();
|
||
|
||
return response()->json([
|
||
'success' => false,
|
||
'message' => 'Failed to save joint data',
|
||
'error' => $e->getMessage()
|
||
], 500);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get joint data by shape_id or joint_no
|
||
* Phase 3.1: API Endpoints for Joint Data
|
||
*/
|
||
public function getJointData(Request $request): JsonResponse
|
||
{
|
||
$validator = Validator::make($request->all(), [
|
||
'drawing_number' => 'required|string',
|
||
'joint_no' => 'nullable|string',
|
||
'shape_id' => 'nullable|string',
|
||
]);
|
||
|
||
if ($validator->fails()) {
|
||
return response()->json([
|
||
'success' => false,
|
||
'message' => 'Validation failed',
|
||
'errors' => $validator->errors()
|
||
], 422);
|
||
}
|
||
|
||
try {
|
||
$drawingNumber = $request->drawing_number;
|
||
$query = WeldLog::where('iso_number', $drawingNumber);
|
||
|
||
if ($request->has('joint_no') && !empty($request->joint_no)) {
|
||
$query->where('no_of_the_joint_as_per_as_built_survey', $request->joint_no);
|
||
}
|
||
|
||
// Dynamic column selection based on schema
|
||
$selectColumns = [
|
||
'id',
|
||
'no_of_the_joint_as_per_as_built_survey as joint_no',
|
||
'type_of_joint',
|
||
'type_of_welds',
|
||
'welding_date',
|
||
];
|
||
|
||
// Add spool numbers (check which columns exist)
|
||
if (Schema::hasColumn('weld_logs', 'spool_number_1')) {
|
||
$selectColumns[] = 'spool_number_1 as spool_no1';
|
||
} else {
|
||
$selectColumns[] = 'spool_number as spool_no1';
|
||
}
|
||
if (Schema::hasColumn('weld_logs', 'spool_number_2')) {
|
||
$selectColumns[] = 'spool_number_2 as spool_no2';
|
||
} elseif (Schema::hasColumn('weld_logs', 'spool_number2')) {
|
||
$selectColumns[] = 'spool_number2 as spool_no2';
|
||
}
|
||
|
||
// Add pose numbers
|
||
if (Schema::hasColumn('weld_logs', 'pose_number_1')) {
|
||
$selectColumns[] = 'pose_number_1 as pose_no1';
|
||
} else {
|
||
$selectColumns[] = 'pose_no_1 as pose_no1';
|
||
}
|
||
if (Schema::hasColumn('weld_logs', 'pose_number_2')) {
|
||
$selectColumns[] = 'pose_number_2 as pose_no2';
|
||
} else {
|
||
$selectColumns[] = 'pose_no_2 as pose_no2';
|
||
}
|
||
|
||
// Add members
|
||
if (Schema::hasColumn('weld_logs', 'member_1')) {
|
||
$selectColumns[] = 'member_1 as member1';
|
||
} else {
|
||
$selectColumns[] = 'member_no_1 as member1';
|
||
}
|
||
if (Schema::hasColumn('weld_logs', 'member_2')) {
|
||
$selectColumns[] = 'member_2 as member2';
|
||
} else {
|
||
$selectColumns[] = 'member_no_2 as member2';
|
||
}
|
||
|
||
// Add material
|
||
if (Schema::hasColumn('weld_logs', 'material_1')) {
|
||
$selectColumns[] = 'material_1 as material';
|
||
} else {
|
||
$selectColumns[] = 'material_no_1 as material';
|
||
}
|
||
|
||
// Add diameter
|
||
if (Schema::hasColumn('weld_logs', 'dia_1')) {
|
||
$selectColumns[] = 'dia_1 as dia1';
|
||
} else {
|
||
$selectColumns[] = 'outside_diameter_1 as dia1';
|
||
}
|
||
if (Schema::hasColumn('weld_logs', 'dia_2')) {
|
||
$selectColumns[] = 'dia_2 as dia2';
|
||
} else {
|
||
$selectColumns[] = 'outside_diameter_2 as dia2';
|
||
}
|
||
|
||
// Add NPS
|
||
$selectColumns[] = 'nps_1 as nps1';
|
||
$selectColumns[] = 'nps_2 as nps2';
|
||
|
||
// Add thickness
|
||
if (Schema::hasColumn('weld_logs', 'thickness_1')) {
|
||
$selectColumns[] = 'thickness_1 as thickness1';
|
||
} else {
|
||
$selectColumns[] = 'wall_thickness_1 as thickness1';
|
||
}
|
||
if (Schema::hasColumn('weld_logs', 'thickness_2')) {
|
||
$selectColumns[] = 'thickness_2 as thickness2';
|
||
} else {
|
||
$selectColumns[] = 'wall_thickness_2 as thickness2';
|
||
}
|
||
|
||
// Add welders
|
||
$selectColumns[] = 'welder_1';
|
||
$selectColumns[] = 'welder_2';
|
||
|
||
$joints = $query->get($selectColumns);
|
||
|
||
return response()->json([
|
||
'success' => true,
|
||
'data' => $joints
|
||
]);
|
||
} catch (\Exception $e) {
|
||
return response()->json([
|
||
'success' => false,
|
||
'message' => 'Failed to get joint data',
|
||
'error' => $e->getMessage()
|
||
], 500);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Update welder assignment in Weldlog
|
||
* Phase 3.3: Weldlog Integration
|
||
*/
|
||
public function updateWelderAssignment(Request $request): JsonResponse
|
||
{
|
||
$validator = Validator::make($request->all(), [
|
||
'drawing_number' => 'required|string',
|
||
'joint_no' => 'required|string',
|
||
'welder_id1' => 'nullable|string',
|
||
'welder_id2' => 'nullable|string',
|
||
]);
|
||
|
||
if ($validator->fails()) {
|
||
return response()->json([
|
||
'success' => false,
|
||
'message' => 'Validation failed',
|
||
'errors' => $validator->errors()
|
||
], 422);
|
||
}
|
||
|
||
try {
|
||
DB::beginTransaction();
|
||
|
||
$weldLog = WeldLog::where('iso_number', $request->drawing_number)
|
||
->where('no_of_the_joint_as_per_as_built_survey', $request->joint_no)
|
||
->first();
|
||
|
||
if (!$weldLog) {
|
||
return response()->json([
|
||
'success' => false,
|
||
'message' => 'Joint not found'
|
||
], 404);
|
||
}
|
||
|
||
// Update welder assignments
|
||
if ($request->has('welder_id1')) {
|
||
$weldLog->welder_1 = $request->welder_id1;
|
||
// Also update real_welder_1 if it exists
|
||
if (Schema::hasColumn('weld_logs', 'real_welder_1')) {
|
||
$weldLog->real_welder_1 = $request->welder_id1;
|
||
}
|
||
}
|
||
|
||
if ($request->has('welder_id2')) {
|
||
$weldLog->welder_2 = $request->welder_id2;
|
||
// Also update real_welder_2 if it exists
|
||
if (Schema::hasColumn('weld_logs', 'real_welder_2')) {
|
||
$weldLog->real_welder_2 = $request->welder_id2;
|
||
}
|
||
}
|
||
|
||
$weldLog->save();
|
||
|
||
DB::commit();
|
||
|
||
return response()->json([
|
||
'success' => true,
|
||
'message' => 'Welder assignment updated successfully',
|
||
'data' => $weldLog
|
||
]);
|
||
} catch (\Exception $e) {
|
||
DB::rollBack();
|
||
|
||
return response()->json([
|
||
'success' => false,
|
||
'message' => 'Failed to update welder assignment',
|
||
'error' => $e->getMessage()
|
||
], 500);
|
||
}
|
||
}
|
||
|
||
} |