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

274 lines
11 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
/**
* @group Spool Release Workflow
*
* API endpoints for managing spool release workflow steps and rollbacks.
*/
class SpoolReleaseWorkflowController extends Controller
{
/**
* Advance Spool Release Workflow
*
* Advance the status of a spool through the quality control and painting workflow.
*
* @authenticated
*
* @bodyParam action string required The action to perform (paint, ndt_release, ndt_paint_release, spool_release). Example: paint
* @bodyParam iso_number string Filter by ISO Number (for single operation). Example: 10-BFW-RS1-0001
* @bodyParam spool_number string Filter by Spool Number (for single operation). Example: SPL-001
* @bodyParam iso_spool_pairs string Comma-separated ISO|SPOOL pairs for bulk operations. Example: ISO-001|SPL-001,ISO-001|SPL-002
*
* @response {
* "status": "success",
* "message": "1 row affected",
* "count": 1
* }
*/
public function advance(Request $request)
{
$action = $request->input('action');
$isoNumber = $request->input('iso_number');
$spoolNumber = $request->input('spool_number');
$isoSpoolPairs = $request->input('iso_spool_pairs');
if (!$isoSpoolPairs && (!$isoNumber || !$spoolNumber)) {
return response()->json(['status' => 'error', 'message' => 'Missing ISO and Spool information']);
}
// Prepare pairs array
$pairs = [];
if ($isoSpoolPairs) {
$rawPairs = explode(",", $isoSpoolPairs);
foreach ($rawPairs as $p) {
$parts = explode("|", trim($p));
if (count($parts) == 2) {
$pairs[] = ['iso' => trim($parts[0]), 'spool' => trim($parts[1])];
}
}
} else {
$pairs[] = ['iso' => trim($isoNumber), 'spool' => trim($spoolNumber)];
}
if (empty($pairs)) {
return response()->json(['status' => 'error', 'message' => 'No valid ISO|Spool pairs found']);
}
// Reconstruct pairs string for side effects if needed
$reconstructedPairs = implode(',', array_map(fn($p) => "{$p['iso']}|{$p['spool']}", $pairs));
// Mock $_POST for legacy view calls (side effects)
$_POST['iso_spool_pairs'] = $reconstructedPairs;
$_POST['iso_number'] = implode(',', array_column($pairs, 'iso'));
$_POST['spool_number'] = implode(',', array_column($pairs, 'spool'));
// Ensure legacy u() function works
if ($request->user()) {
\Session::put('cached_user', $request->user());
\Session::put('uid', $request->user()->id);
}
$userId = $request->user() ? $request->user()->id : 0;
$totalAffected = 0;
try {
DB::beginTransaction();
if ($action == 'paint') {
$pattern = setting("paint_release_number_pattern");
$checkNo = str_replace("{number}", get_counter($pattern), $pattern);
foreach ($pairs as $pair) {
$affected = db("weld_logs")
->where("iso_number", $pair['iso'])
->where("spool_number", $pair['spool'])
->whereNotIn("spool_status", ['Completed'])
->whereIn("spool_status", ['Paint', 'Spool Release', 'NDT Release', 'QC', 'Manufacturing', 'Weld Complete'])
->update([
"spool_paint_check" => $userId,
"paint_release_no" => $checkNo,
"paint_release_date" => simdi(),
"spool_status" => "Completed"
]);
$totalAffected += $affected;
if ($affected > 0) {
try {
ob_start();
view('admin.type.spool-release.paint-follow-up-updater', [
'isoNumber' => $pair['iso'],
'spoolNumber' => $pair['spool'],
])->render();
ob_end_clean();
} catch (\Exception $e) {
ob_end_clean();
\Log::warning("Paint follow up updater error: " . $e->getMessage());
}
}
}
} elseif ($action == 'ndt_release') {
$pattern = setting("ndt_release_number_pattern");
$newReleaseNo = str_replace("{number}", get_counter($pattern), $pattern);
foreach ($pairs as $pair) {
$affected = db("weld_logs")
->where("iso_number", $pair['iso'])
->where("spool_number", $pair['spool'])
->whereNotNull("spool_ndt_check_no")
->whereNull("ndt_release_no")
->update([
"ndt_release_no" => $newReleaseNo,
"ndt_release_check" => $userId,
"ndt_release_date" => Carbon::now(),
'spool_status' => "Paint",
]);
$totalAffected += $affected;
}
} elseif ($action == 'ndt_paint_release') {
$pattern = setting("paint_release_number_pattern");
foreach ($pairs as $pair) {
$newRequestNo = str_replace("{number}", get_counter($pattern), $pattern);
$checkPaintingCycle = db("weld_logs")
->where('iso_number', $pair['iso'])
->where('spool_number', $pair['spool'])
->select("painting_cycle")
->first();
$spoolStatus = (!empty($checkPaintingCycle) && !empty($checkPaintingCycle->painting_cycle)) ? "Paint" : "Completed";
$affected = db("weld_logs")
->where('iso_number', $pair['iso'])
->where('spool_number', $pair['spool'])
->whereNotNull("spool_ndt_check_no")
->whereNull("ndt_release_date")
->update([
"ndt_release_no" => $newRequestNo,
"ndt_release_check" => $userId,
"ndt_release_date" => Carbon::now(),
'spool_status' => $spoolStatus,
]);
$totalAffected += $affected;
if ($affected > 0) {
try {
ob_start();
view('admin.type.spool-release.paint-follow-up-updater', [
'isoNumber' => $pair['iso'],
'spoolNumber' => $pair['spool'],
])->render();
ob_end_clean();
} catch (\Exception $e) {
ob_end_clean();
\Log::warning("Paint follow up updater error: " . $e->getMessage());
}
}
}
} elseif ($action == 'spool_release' || $action == 'checklist_ok') {
$pattern = setting("spool_release_check_number_pattern");
$checkNo = str_replace("{number}", get_counter($pattern), $pattern);
foreach ($pairs as $pair) {
$affected = db("weld_logs")
->where("iso_number", $pair['iso'])
->where("spool_number", $pair['spool'])
->whereIn("spool_status", ["Spool Release", "Manufacturing", "Weld Complete"])
->update([
"spool_ndt_check" => $userId,
"spool_ndt_check_no" => $checkNo,
"spool_ndt_check_date" => simdi(),
"spool_status" => "NDT Release"
]);
$totalAffected += $affected;
}
// Side effects
ob_start();
view('admin.type.spool-release.spool-document-generate')->render();
view('cron.spool-status-changer', ['iso_spool_pairs' => $reconstructedPairs])->render();
ob_end_clean();
} else {
DB::rollBack();
return response()->json(['status' => 'error', 'message' => 'Invalid action']);
}
dispatchCacheBladeViews();
DB::commit();
return response()->json([
'status' => 'success',
'message' => $totalAffected . ' row(s) affected',
'count' => $totalAffected
]);
} catch (\Exception $e) {
DB::rollBack();
\Log::error("SpoolReleaseWorkflow error: " . $e->getMessage());
return response()->json([
'status' => 'error',
'message' => 'Internal server error: ' . $e->getMessage()
], 500);
}
}
/**
* Rollback Spool Release
*
* Reverts a spool release action using the legacy rollback system.
*
* @authenticated
*
* @bodyParam id integer required The ID of the spool or record to rollback. Example: 123
* @bodyParam iso_number string required The ISO number to rollback. Example: 10-BFW-RS1-0001
* @bodyParam spool_number string required The Spool number to rollback. Example: SPL-001
*
* @response {
* "status": "success",
* "message": "Rollback applied"
* }
* @response {
* "status": "error",
* "message": "Missing parameters for rollback"
* }
*/
public function rollback(Request $request)
{
$id = $request->input('id');
$isoNumber = $request->input('iso_number');
$spoolNumber = $request->input('spool_number');
if (!$id || !$isoNumber || !$spoolNumber) {
return response()->json(['status' => 'error', 'message' => 'Missing parameters for rollback']);
}
// Ensure u() acts like authenticated API user inside rollback
$_GET['rollback'] = $id;
$_GET['iso_number'] = $isoNumber;
$_GET['spool_number'] = $spoolNumber;
ob_start();
include resource_path('views/admin/type/spool-release/rollback.blade.php');
$output = ob_get_clean();
// Rollback outputs bilgi() which sets session flash and might render a Pjax wrapper
// But the rollback was successful if it gets to the end. Let's just return success JSON
return response()->json([
'status' => 'success',
'message' => 'Rollback applied'
]);
}
}