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

402 lines
17 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
/**
* @group Read Only Endpoints
*
* APIs for retrieving read-only data from various system modules.
*/
class ApiReadOnlyController extends Controller
{
public function __construct()
{
// Auth handled at route level with 'auth:sanctum,web' to support both token and session auth
}
private function renderLegacyScript($scriptPath, Request $request)
{
try {
// Merge request parameters into global $_GET for legacy script compatibility
if (!empty($request->all())) {
$_GET = array_merge($_GET, $request->all());
}
// Define path to the view
$fullPath = resource_path("views/admin-ajax/{$scriptPath}");
if (!file_exists($fullPath)) {
return response()->json(['error' => 'Module not found: ' . $scriptPath], 404);
}
// Capture output
ob_start();
include($fullPath);
$output = ob_get_clean();
// Attempt to decode JSON to ensure it's valid, otherwise return raw string if appropriate or wrap it
$json = json_decode($output);
if (json_last_error() === JSON_ERROR_NONE) {
return response()->json($json);
}
// If not JSON, it might be an error or HTML. For this API, we expect JSON.
// We'll return it as a 'raw_output' field if it's not valid JSON
return response()->json(['raw_output' => $output]);
} catch (\Exception $e) {
return response()->json(['error' => $e->getMessage()], 500);
}
}
public function ndtRequest(Request $request)
{
return $this->renderLegacyScript('request-ndt.blade.php', $request);
}
public function ndtCalculation(Request $request)
{
return $this->renderLegacyScript('ndt-calculation.blade.php', $request);
}
/**
* Spool Area Release
*
* Get spool area release data with pagination and filtering.
*
* @queryParam take int Number of items to take (pagination). Default: 100. Example: 10
* @queryParam skip int Number of items to skip (pagination). Default: 0. Example: 0
* @queryParam filter_iso_number string Filter by ISO Number. Example: 10-BFW-RS1-0001-AH06HS-HC
* @queryParam filter_spool_number string Filter by Spool Number. Example: SPL-0004
* @queryParam filter_line_number string Filter by Line Number. Example: LN-001
* @queryParam filter_painting_cycle string Filter by Painting Cycle. Example: C1
* @queryParam filter_spool_status string Filter by Spool Status. Example: Completed
* @queryParam module string Specific module filter (e.g., 'spool-release-paint'). Example: spool-release-paint
*
* @response {
* "summary": {"Completed": 10, "Waiting": 5},
* "esummary": {"Completed": 2},
* "datagrid": [
* {
* "id": 1,
* "iso_number": "ISO-001",
* "spool_number": "SPL-001",
* "spool_status": "Completed",
* "project": "PROJECT A"
* }
* ]
* }
*/
public function spoolAreaRelease(Request $request)
{
$limit = $request->get('take', 100);
$offset = $request->get('skip', 0);
$isFiltered = $request->has('filter_iso_number') || $request->has('filter_spool_number');
$module = $request->get('module');
// Spool status order mapping
$statusOrder = [
'Waiting' => 1,
'Manufacturing' => 2,
'QC' => 3,
'Paint' => 4,
'Completed' => 5,
];
$caseSql = "CASE spool_status ";
foreach ($statusOrder as $status => $order) {
$caseSql .= "WHEN '$status' THEN $order ";
}
$caseSql .= "ELSE 99 END";
// Subquery for min status order
$minStatusSub = apply_welded_filter(db("weld_logs"))
->select(
'iso_number',
'spool_number',
\DB::raw("MIN(CASE WHEN type_of_joint = 'S' THEN {$caseSql} END) as min_status_order")
)
->groupBy('iso_number', 'spool_number');
// Base query
$query = apply_welded_filter(db("weld_logs"))
->leftJoinSub($minStatusSub, 'min_status_order_tbl', function($join) {
$join->on('weld_logs.iso_number', '=', 'min_status_order_tbl.iso_number')
->on('weld_logs.spool_number', '=', 'min_status_order_tbl.spool_number');
});
// Apply filters
if ($request->has('filter_iso_number')) {
$query->where("weld_logs.iso_number", "like", "%" . $request->get("filter_iso_number") . "%");
}
if ($request->has('filter_spool_number')) {
$query->where("weld_logs.spool_number", "like", "%" . $request->get("filter_spool_number") . "%");
}
if ($request->has('filter_line_number')) {
$query->where("weld_logs.line_number", "like", "%" . $request->get("filter_line_number") . "%");
}
if ($request->has('filter_painting_cycle')) {
$query->where("weld_logs.painting_cycle", "like", "%" . $request->get("filter_painting_cycle") . "%");
}
if ($request->has('filter_spool_status')) {
$query->where("weld_logs.spool_status", $request->get("filter_spool_status"));
}
if ($module === "spool-release-paint") {
$query->whereNotNull("painting_cycle");
}
// Field selection - always group by ISO and Spool to get single row per spool
$query->select(
'weld_logs.id',
'weld_logs.iso_number',
'weld_logs.spool_number',
\DB::raw("GROUP_CONCAT(DISTINCT no_of_the_joint_as_per_as_built_survey ORDER BY CAST(no_of_the_joint_as_per_as_built_survey AS UNSIGNED) SEPARATOR ', ') AS joint_no"),
\DB::raw("GROUP_CONCAT(DISTINCT type_of_joint SEPARATOR '/') as type_of_joint"),
'project',
'iso_rev',
'painting_cycle',
'spool_status',
\DB::raw("MAX(CASE WHEN type_of_joint = 'S' THEN clearance_no END) as clearance_no"),
\DB::raw("MIN(CASE WHEN type_of_joint = 'S' THEN clearance_date END) as min_clearance_date"),
\DB::raw("MAX(CASE WHEN type_of_joint = 'S' THEN clearance_date END) as clearance_date"),
\DB::raw("COUNT(DISTINCT CASE WHEN type_of_joint = 'S' THEN COALESCE(clearance_date, 'NULL_VALUE') END) as clearance_date_count"),
\DB::raw("MIN(CASE WHEN type_of_joint = 'S' THEN ndt_release_date END) as min_ndt_release_date"),
\DB::raw("MAX(CASE WHEN type_of_joint = 'S' THEN ndt_release_date END) as ndt_release_date"),
\DB::raw("COUNT(DISTINCT CASE WHEN type_of_joint = 'S' THEN COALESCE(ndt_release_date, 'NULL_VALUE') END) as ndt_release_date_count"),
\DB::raw("MAX(CASE WHEN type_of_joint = 'S' THEN register_paint_no END) as register_paint_no"),
\DB::raw("MIN(CASE WHEN type_of_joint = 'S' THEN register_date END) as min_register_date"),
\DB::raw("MAX(CASE WHEN type_of_joint = 'S' THEN register_date END) as register_date"),
\DB::raw("COUNT(DISTINCT CASE WHEN type_of_joint = 'S' THEN COALESCE(register_date, 'NULL_VALUE') END) as register_date_count"),
\DB::raw("MAX(CASE WHEN type_of_joint = 'S' THEN ndt_release_no END) as ndt_release_no"),
\DB::raw("MIN(CASE WHEN type_of_joint = 'S' THEN paint_release_date END) as min_paint_release_date"),
\DB::raw("MAX(CASE WHEN type_of_joint = 'S' THEN paint_release_date END) as paint_release_date"),
\DB::raw("COUNT(DISTINCT CASE WHEN type_of_joint = 'S' THEN COALESCE(paint_release_date, 'NULL_VALUE') END) as paint_release_date_count"),
\DB::raw("MAX(CASE WHEN type_of_joint = 'S' THEN paint_release_no END) as paint_release_no"),
\DB::raw("MAX(CASE WHEN type_of_joint = 'S' THEN spool_zone END) as spool_zone"),
\DB::raw("MAX(CASE WHEN type_of_joint = 'S' THEN spool_ndt_check END) as spool_ndt_check"),
\DB::raw("MAX(CASE WHEN type_of_joint = 'S' THEN spool_paint_check END) as spool_paint_check"),
\DB::raw("MAX(CASE WHEN type_of_joint = 'S' THEN spool_ndt_check_no END) as spool_ndt_check_no"),
\DB::raw("MAX(CASE WHEN type_of_joint = 'S' THEN ndt_release_check END) as ndt_release_check"),
\DB::raw("MIN(CASE WHEN type_of_joint = 'S' THEN spool_ndt_check_date END) as min_spool_ndt_check_date"),
\DB::raw("MAX(CASE WHEN type_of_joint = 'S' THEN spool_ndt_check_date END) as spool_ndt_check_date"),
\DB::raw("COUNT(DISTINCT CASE WHEN type_of_joint = 'S' THEN COALESCE(spool_ndt_check_date, 'NULL_VALUE') END) as spool_ndt_check_date_count"),
\DB::raw("MAX(CASE WHEN type_of_joint = 'S' THEN paint_release_check END) as paint_release_check"),
\DB::raw("MAX(CASE WHEN type_of_joint = 'S' THEN spool_remarks END) as spool_remarks"),
'min_status_order_tbl.min_status_order'
)
->groupBy("weld_logs.iso_number", "weld_logs.spool_number");
// Get total results before pagination for summaries
$allResults = $query->get();
// Summary calculations
$summary = [];
$esummary = [];
$users = usersArray();
$documentRevisions = [];
$revisionQuery = db("document_revisions")->select('drawing_no', 'revision_no')->get();
foreach ($revisionQuery as $revision) {
$documentRevisions[$revision->drawing_no] = $revision->revision_no;
}
$allSpoolStatusesQuery = db("weld_logs")
->select('spool_status', 'iso_number', 'spool_number')->where("type_of_joint", "S")->get();
$allSpoolStatuses = [];
foreach ($allSpoolStatusesQuery as $statusQuery) {
$allSpoolStatuses[$statusQuery->iso_number][$statusQuery->spool_number][] = $statusQuery->spool_status;
}
$orderToStatus = array_flip($statusOrder);
foreach ($allResults as $q) {
// Processing logic from Blade
if (strpos($q->type_of_joint, 'S') !== false && isset($q->min_status_order) && $q->min_status_order >= 1 && $q->min_status_order <= 5) {
$q->spool_status = $orderToStatus[$q->min_status_order];
}
$q->revision_no = $documentRevisions[$q->iso_number] ?? null;
$q->project = strtoupper($q->project);
if ($q->spool_ndt_check != "") {
foreach (['spool_ndt_check', 'spool_paint_check', 'ndt_release_check', 'paint_release_check'] as $field) {
if (isset($users[$q->$field])) {
$q->$field = "✒️" . $users[$q->$field]->name;
}
}
}
if (isset($q->spool_status)) {
$types = explode('/', $q->type_of_joint);
$hasS = in_array('S', $types) || in_array('F/S', $types);
$hasF = in_array('F', $types);
if ($hasS) {
if (!isset($summary[$q->spool_status])) $summary[$q->spool_status] = 0;
$summary[$q->spool_status]++;
}
if ($hasF) {
if (!isset($esummary[$q->spool_status])) $esummary[$q->spool_status] = 0;
$esummary[$q->spool_status]++;
}
}
$spoolStatuses = $allSpoolStatuses[$q->iso_number][$q->spool_number] ?? [];
$q->spool_status = getLowestSpoolStatus($spoolStatuses);
$q->latest_status = getLatestSpoolStatus($spoolStatuses);
$dateWarnings = [
'ndt_release_date_count' => ['min_ndt_release_date', 'ndt_release_date'],
'clearance_date_count' => ['min_clearance_date', 'clearance_date'],
'register_date_count' => ['min_register_date', 'register_date'],
'paint_release_date_count' => ['min_paint_release_date', 'paint_release_date'],
'spool_ndt_check_date_count' => ['min_spool_ndt_check_date', 'spool_ndt_check_date'],
];
foreach ($dateWarnings as $countField => $dateFields) {
if ($q->$countField > 1 || $q->{$dateFields[0]} != $q->{$dateFields[1]}) {
$q->spool_status .= "⚠️";
break;
}
}
}
// Apply skip/take to datagrid
$datagrid = array_slice($allResults->toArray(), $offset, $limit);
return response()->json([
'summary' => $summary,
'esummary' => $esummary,
'datagrid' => $datagrid,
], 200, [], JSON_UNESCAPED_UNICODE);
}
public function rfiDashboard(Request $request)
{
return $this->renderLegacyScript('rfi-dashboard.blade.php', $request);
}
public function welderQualificationStatus(Request $request)
{
return $this->renderLegacyScript('welder-qualification-status.php', $request);
}
public function punchList(Request $request)
{
return $this->renderLegacyScript('punch-summary/punch-list.blade.php', $request);
}
public function naksWelders(Request $request)
{
// "Naks (Welder, Consu, Equipment)" - Checking specific files usually in admin-ajax
// Assuming welder-qualification-status covers welders.
// Need to check for Consumables and Equipment if separate files exist.
return $this->renderLegacyScript('welder-qualification-status.php', $request);
}
public function testPackagePivot(Request $request) {
return $this->renderLegacyScript('test-package/pivot.blade.php', $request);
}
public function testPackageStatusPivot(Request $request) {
return $this->renderLegacyScript('test-package/status-pivot.blade.php', $request);
}
public function testPackageSummary(Request $request) {
return $this->renderLegacyScript('test-package/summary.blade.php', $request);
}
public function testPackageSummary2(Request $request) {
return $this->renderLegacyScript('test-package/summary2.blade.php', $request);
}
/**
* Spool Release Detail
*
* Get detailed spool release information with filtering options.
*
* @queryParam filter_iso_number string Filter by ISO Number. Example: 10-BFW-RS1-0001-AH06HS-HC
* @queryParam filter_spool_number string Filter by Spool Number. Example: SPL-0004
*/
public function spoolReleaseDetail(Request $request) {
return $this->renderLegacyScript('spool-release-detail.blade.php', $request);
}
/**
* Repair Table Statistics
*
* Get repair table statistics including defect types by welder, NPS, and material.
*
* @queryParam d1 string Start date (YYYY-MM-DD). Example: 2024-01-01
* @queryParam d2 string End date (YYYY-MM-DD). Example: 2024-03-31
*/
public function repairTable(Request $request)
{
return $this->renderLegacyScript('repair-table.blade.php', $request);
}
public function welderBasedRepairRatioDistribution(Request $request)
{
return $this->renderLegacyScript('repair-table/welder-based-repair-ratio-distribution.blade.php', $request);
}
public function defectTypeByWelder(Request $request)
{
return $this->renderLegacyScript('repair-table/defect-type-by-welder.blade.php', $request);
}
public function welderQualificationTable(Request $request)
{
return $this->renderLegacyScript('welder-qualification-table.blade.php', $request);
}
public function rfiTasks(Request $request)
{
return $this->renderLegacyScript('rfi-tasks.blade.php', $request);
}
public function rfiStatus(Request $request)
{
$settingValue = setting('rfi-status');
$data = json_decode($settingValue, true);
if (json_last_error() !== JSON_ERROR_NONE) {
$data = $settingValue;
}
return response()->json([
'status' => 'success',
'data' => $data
]);
}
/**
* NDT Release List
*
* Get list of NDT ready spools grouped by ISO and spool number.
*/
public function ndtReleaseList(Request $request)
{
return $this->renderLegacyScript('ndt-list.blade.php', $request);
}
/**
* Paint Release List
*
* Get list of paint released spools with paint release details.
*/
public function paintReleaseList(Request $request)
{
return $this->renderLegacyScript('ndt-paint-list.blade.php', $request);
}
// Placeholder for other modules as they are identified
}