Files
2026-04-28 21:14:25 +03:00

207 lines
8.1 KiB
PHP

<?php
namespace App\Services\WeldLogTriggers\Triggers;
use App\Services\WeldLogTriggers\Base\BaseTrigger;
use App\Models\NdeMatrix;
use App\Helpers\TransactionHelper;
use Illuminate\Support\Facades\Log;
/**
* NDE Matrix Update Trigger
*
* Syncs data between Line Lists, NDE Matrix, and WeldLogs
* Handles type_of_welds changes and updates NDE test scope percentages
*/
class NdeMatrixUpdateTrigger extends BaseTrigger
{
public function getName(): string
{
return 'NDE Matrix Update';
}
public function getOrder(): int
{
return 3;
}
public function getDependentFields(): array
{
return [
'type_of_welds',
'fluid_code',
'type_of_joint',
'line_number',
'design_area',
'project'
];
}
protected function process($data, $beforeData, array $context): array
{
try {
// Sync data from Line Lists to NDE Matrix via view render
$ndeMatrixView = view('cron.line_lists-sync-from-linelists-nde-matrix', [
'line_number' => $data->line_number,
'design_area' => $data->design_area,
'commitSize' => 5, // Chunk size for transaction batching
'triggerMode' => true // Called from SaveTrigger
])->render();
Log::info("Line Lists to NDE Matrix sync completed via view render", [
'line_number' => $data->line_number,
'design_area' => $data->design_area
]);
// Special handling for type_of_welds change
if (!is_null($beforeData) && $beforeData->type_of_welds !== $data->type_of_welds) {
TransactionHelper::retryTransaction(function () use ($data, $beforeData) {
// Where condition for old type
$oldTypeWhereData = [
'line' => $data->line_number,
'type_of_joint' => $beforeData->type_of_welds,
'fluid' => $data->fluid_code,
];
// Check if old type is still used by other WeldLog records
$otherRecordsUsingOldType = db("weld_logs")
->where('line_number', $data->line_number)
->where('type_of_welds', $beforeData->type_of_welds)
->where('fluid_code', $data->fluid_code)
->where('id', '!=', $data->id)
->orderBy('id', 'ASC') // Deadlock prevention
->exists();
// Delete from NDE Matrix only if old type is not used elsewhere
if (!$otherRecordsUsingOldType) {
$deleteResult = db("nde_matrices")
->where($oldTypeWhereData)
->delete();
Log::info("NDE Matrix old type cleaned up - no other weld logs using it", [
'line' => $data->line_number,
'old_type_of_joint' => $beforeData->type_of_welds,
'new_type_of_joint' => $data->type_of_welds,
'fluid' => $data->fluid_code,
'delete_result' => $deleteResult
]);
} else {
Log::info("NDE Matrix old type preserved - still used by other weld logs", [
'line' => $data->line_number,
'old_type_of_joint' => $beforeData->type_of_welds,
'new_type_of_joint' => $data->type_of_welds,
'fluid' => $data->fluid_code
]);
}
}, 5); // 5 attempts with exponential backoff
}
} catch (\Throwable $th) {
Log::error("NDE Matrix sync error: " . $th->getMessage(), [
'line_number' => $data->line_number,
'design_area' => $data->design_area
]);
throw $th;
}
// Sync from NDE Matrix to WeldLog
return $this->syncNdeMatrixToWeldLog($data);
}
/**
* Sync NDE Matrix data to WeldLog
* Updates scope percentages and other NDE-related fields
*/
protected function syncNdeMatrixToWeldLog($data): array
{
// fluid_code null check - get from line_lists if needed
$currentFluidCode = $data->fluid_code ?? '';
if(empty($currentFluidCode)) {
$lineListForFluid = db("line_lists")->where('line_no', $data->line_number)->first();
if($lineListForFluid) {
$currentFluidCode = $lineListForFluid->fluid_code ?? '';
}
}
Log::info("NDE Matrix to WeldLog sync started", [
'weld_log_id' => $data->id,
'line_number' => $data->line_number,
'type_of_welds' => $data->type_of_welds,
'fluid_code' => $currentFluidCode
]);
// Skip if fluid_code is null
if(empty($currentFluidCode)) {
Log::info("NDE Matrix to WeldLog sync skipped - fluid_code is null", [
'weld_log_id' => $data->id,
'line_number' => $data->line_number
]);
return ['skipped' => true, 'reason' => 'fluid_code_null'];
}
// Get NDE Matrix records
$ndeMatrices = NdeMatrix::where("line", $data->line_number)
->where("type_of_joint", $data->type_of_welds)
->where("fluid", $currentFluidCode)
->get();
Log::debug("NDE Matrix records retrieved", [
'matrix_count' => $ndeMatrices->count(),
'matrix_examples' => $ndeMatrices->take(2)->toArray()
]);
$ndeToWeldLogUpdateCount = 0;
// Process NDE Matrix in chunks with TransactionHelper
Log::debug("NDE Matrix to WeldLog sync starting", [
'total_records' => $ndeMatrices->count()
]);
TransactionHelper::chunkTransaction(
$ndeMatrices,
function ($ndeMatrixChunk) use (&$ndeToWeldLogUpdateCount) {
foreach($ndeMatrixChunk as $ndeMatrix) {
$weldLogUpdateData = [
'vt_scope' => 100,
'rt_scope' => $ndeMatrix->rt,
'ut_scope' => $ndeMatrix->ut,
'mt_scope' => $ndeMatrix->mt,
'pt_scope' => $ndeMatrix->pt,
'pmi_scope' => $ndeMatrix->pmi,
'ht_scope' => $ndeMatrix->ht,
'pwht' => $ndeMatrix->pwht_field,
'ferrite_scope' => $ndeMatrix->fn,
'ndt_percent' => $ndeMatrix->ndt,
'operating_temperature_s' => $ndeMatrix->operation_temp,
'operating_pressure_mpa' => $ndeMatrix->operations_pressure_kg,
'fluid_group' => $ndeMatrix->piping_group,
'main_material' => $ndeMatrix->material,
'updated_at' => simdi()
];
$result = db("weld_logs")
->where("line_number", $ndeMatrix->line)
->where("type_of_welds", $ndeMatrix->type_of_joint)
->orderBy('id', 'ASC') // Deadlock prevention
->update($weldLogUpdateData);
$ndeToWeldLogUpdateCount += $result;
}
return $ndeMatrixChunk->count();
},
10, // Chunk size increased from 3 to 10 for better performance
10000 // 10ms delay (reduced from 150ms) - sufficient for deadlock prevention
);
Log::info("NDE Matrix to WeldLog sync completed", [
'total_updated_records' => $ndeToWeldLogUpdateCount
]);
return [
'success' => true,
'updated_records' => $ndeToWeldLogUpdateCount
];
}
}