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

334 lines
12 KiB
PHP

<?php
namespace App\Services\WeldLogTriggers\Triggers;
use App\Services\WeldLogTriggers\Base\BaseTrigger;
use App\Models\PaintMatrix;
use App\Helpers\TransactionHelper;
use Illuminate\Support\Facades\Log;
/**
* Construction Paint Logs Trigger
*
* Aligns weld log driven construction paint sync with LineList trigger behaviour.
* - Requires matching Line List + painting cycle
* - Processes each spool once, only when shop joints exist
* - Protects finished records and cleans up orphan entries
*/
class ConstructionPaintLogsTrigger extends BaseTrigger
{
public function getName(): string
{
return 'Construction Paint Logs Sync';
}
public function getOrder(): int
{
return 9;
}
public function getDependentFields(): array
{
return [
'line_number',
'spool_number',
'type_of_joint',
'project',
'design_area',
'iso_number',
'fluid_code',
'painting_cycle',
'test_package_no',
'nps_1',
'nps_2',
'spool_status',
];
}
protected function process($data, $beforeData, array $context): array
{
$constructionPaintLogUpdatedCount = 0;
$constructionPaintLogCreatedCount = 0;
$deletedCleanupCount = 0;
try {
Log::debug('ConstructionPaintLogsTrigger: Starting process', [
'weldLogId' => $data->id
]);
$weldLog = db("weld_logs")->where("id", $data->id)->first();
if (!$weldLog) {
return ['success' => false, 'reason' => 'weld_log_not_found'];
}
if (empty($weldLog->line_number)) {
return ['success' => false, 'reason' => 'line_number_empty'];
}
$lineList = db("line_lists")
->where('line_no', $weldLog->line_number)
->first();
if (!$lineList) {
return ['success' => false, 'reason' => 'line_list_not_found'];
}
if (empty($lineList->painting_cycle)) {
return ['skipped' => true, 'reason' => 'painting_cycle_empty'];
}
$allWeldLogs = db("weld_logs")
->where("line_number", $lineList->line_no)
->where("design_area", $lineList->unit)
->where("fluid_code", $lineList->fluid_code)
->orderBy('id', 'ASC')
->get();
if ($allWeldLogs->isEmpty()) {
return ['skipped' => true, 'reason' => 'no_matching_weld_logs'];
}
$processedSpools = [];
$validShopSpools = $this->getValidShopSpools($lineList->line_no, $lineList->unit, $lineList->fluid_code);
TransactionHelper::chunkTransaction(
$allWeldLogs,
function ($weldLogChunk) use (
$lineList,
&$constructionPaintLogUpdatedCount,
&$constructionPaintLogCreatedCount,
&$processedSpools
) {
foreach ($weldLogChunk as $currentWeldLog) {
if (empty($currentWeldLog->spool_number)) {
continue;
}
if (in_array($currentWeldLog->spool_number, $processedSpools, true)) {
continue;
}
if (!$this->hasShopJoint($lineList->line_no, $currentWeldLog->spool_number)) {
continue;
}
$this->processWeldLogRecord(
$currentWeldLog,
$lineList,
$constructionPaintLogUpdatedCount,
$constructionPaintLogCreatedCount
);
$processedSpools[] = $currentWeldLog->spool_number;
}
return $weldLogChunk->count();
},
1,
10000
);
$deletedCleanupCount = $this->cleanupConstructionRecords($lineList->line_no, $validShopSpools);
} catch (\Throwable $th) {
Log::error("Construction Paint Logs sync error: " . $th->getMessage(), [
'weld_log_id' => $data->id
]);
throw $th;
}
return [
'success' => true,
'created' => $constructionPaintLogCreatedCount,
'updated' => $constructionPaintLogUpdatedCount,
'deleted_cleanup' => $deletedCleanupCount
];
}
protected function processWeldLogRecord($currentWeldLog, $lineList, &$updatedCount, &$createdCount)
{
$paintMatrix = PaintMatrix::where('line', $lineList->line_no)
->where('fluid_code', $lineList->fluid_code)
->first();
$baseConstructionPaintLogData = [
'construction_report_no' => $currentWeldLog->weld_map_no ?? '',
'test_package' => $currentWeldLog->test_package_no ?? '',
'rev' => $lineList->rev ?? '',
'engineering' => $lineList->engineering ?? '',
'area' => $currentWeldLog->project ?? '',
'unit' => $currentWeldLog->design_area ?? '',
'line' => $lineList->line_no,
'iso_drawings' => $currentWeldLog->iso_number ?? '',
'fluid_code' => $lineList->fluid_code ?? '',
'fluid_code_description' => $lineList->fluid_ru ?? '',
'isolation_info' => $lineList->external_finish_type ?? '',
'updated_at' => now()
];
if ($paintMatrix) {
$baseConstructionPaintLogData = array_merge($baseConstructionPaintLogData, [
'painting_system_type_1' => $paintMatrix->paint_cycle ?? '',
'painting_system_type_2' => $paintMatrix->paint_cycle ?? '',
'brend_name_1' => $paintMatrix->brend_name_1 ?? '',
'ral_1' => $paintMatrix->ral_code_1 ?? '',
'color_1' => $paintMatrix->colour_1 ?? '',
'thickness_1' => $paintMatrix->thickness_1 ?? '',
'brend_name_2' => $paintMatrix->brend_name_2 ?? '',
'ral_2' => $paintMatrix->ral_code_2 ?? '',
'color_2' => $paintMatrix->colour_2 ?? '',
'thickness_2' => $paintMatrix->thickness_2 ?? '',
'brend_name_3' => $paintMatrix->brend_name_3 ?? '',
'ral_3' => $paintMatrix->ral_code_3 ?? '',
'color_3' => $paintMatrix->colour_3 ?? '',
'thickness_3' => $paintMatrix->thickness_3 ?? '',
]);
}
$constructionPaintLogData = $baseConstructionPaintLogData;
$constructionPaintLogData['test_package'] = $currentWeldLog->test_package_no ?? '';
$constructionPaintLogData['spool'] = $currentWeldLog->spool_number ?? '';
$constructionPaintLogData['spool_status'] = $currentWeldLog->spool_status ?? 'Waiting';
$constructionPaintLogData['report_no'] = '';
$constructionPaintLogData['dn_1'] = $currentWeldLog->nps_1 ?? '';
$constructionPaintLogData['dn_2'] = $currentWeldLog->nps_2 ?? '';
$constructionPaintLogData['dn_3'] = '';
$uniqueConstraintCondition = [
'line' => $lineList->line_no,
'spool' => $currentWeldLog->spool_number,
'painting_system_type_1' => $paintMatrix->paint_cycle ?? ''
];
$whereCondition = [
'line' => $lineList->line_no,
'spool' => $currentWeldLog->spool_number
];
$existingRecordSameCycle = db("construction_paint_logs")
->where($uniqueConstraintCondition)
->first();
$recordsWithDifferentPaintCycle = db("construction_paint_logs")
->where($whereCondition)
->where('painting_system_type_1', '!=', $paintMatrix->paint_cycle ?? '')
->get();
if ($existingRecordSameCycle) {
$hasAllEmptyDates = $this->hasAllEmptyDates($existingRecordSameCycle);
if ($hasAllEmptyDates) {
db("construction_paint_logs")
->where('id', $existingRecordSameCycle->id)
->update($constructionPaintLogData);
$updatedCount++;
}
return;
}
if ($recordsWithDifferentPaintCycle->count() > 0) {
foreach ($recordsWithDifferentPaintCycle as $oldRecord) {
$hasAnyDateFilled = !$this->hasAllEmptyDates($oldRecord);
if (!$hasAnyDateFilled) {
db("construction_paint_logs")
->where('id', $oldRecord->id)
->update($constructionPaintLogData);
$updatedCount++;
return;
}
}
}
$constructionPaintLogData['created_at'] = now();
db("construction_paint_logs")->insert($constructionPaintLogData);
$createdCount++;
}
protected function hasAllEmptyDates($record): bool
{
$dateFields = [
'blasting_date',
'blasting_finish_date',
'painting_date_1',
'painting_finish_date_1',
'rfi_date_1',
'painting_date_2',
'painting_finish_date_2',
'rfi_date_2',
'painting_date_3',
'painting_finish_date_3',
'rfi_date_3'
];
foreach ($dateFields as $field) {
if (!empty($record->$field)) {
return false;
}
}
return true;
}
protected function hasShopJoint(string $lineNumber, string $spoolNumber): bool
{
return db("weld_logs")
->where('line_number', $lineNumber)
->where('spool_number', $spoolNumber)
->where('type_of_joint', 'S')
->exists();
}
protected function getValidShopSpools(string $lineNumber, ?string $unit, ?string $fluidCode): array
{
return db("weld_logs")
->where('line_number', $lineNumber)
->when($unit, function ($query, $unit) {
return $query->where('design_area', $unit);
})
->when($fluidCode, function ($query, $fluidCode) {
return $query->where('fluid_code', $fluidCode);
})
->where('type_of_joint', 'S')
->whereNotNull('spool_number')
->pluck('spool_number')
->unique()
->values()
->toArray();
}
protected function cleanupConstructionRecords(string $lineNumber, array $validShopSpools): int
{
$query = db("construction_paint_logs")
->where('line', $lineNumber);
if (!empty($validShopSpools)) {
$recordsToEvaluate = $query
->whereNotIn('spool', $validShopSpools)
->get();
} else {
$recordsToEvaluate = $query->get();
}
if ($recordsToEvaluate->isEmpty()) {
return 0;
}
$deletableIds = $recordsToEvaluate
->filter(function ($record) {
return $this->hasAllEmptyDates($record);
})
->pluck('id')
->toArray();
if (empty($deletableIds)) {
return 0;
}
return db("construction_paint_logs")
->whereIn('id', $deletableIds)
->delete();
}
}