Files
citrus-cms/app/Http/Controllers/Api/AnnotationController.php
T
2026-04-28 21:14:25 +03:00

829 lines
33 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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);
}
}
}