İlk temizlik tamamlandı bir önceki projeden

This commit is contained in:
Ümit Tunç
2026-04-28 21:14:25 +03:00
commit f80443aec0
10000 changed files with 959965 additions and 0 deletions
@@ -0,0 +1,656 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Models\WeldLog;
use App\Models\Handover;
use App\Models\WeldingEquipment;
/**
* @group Stats
*
* İstatistikler ve Hesaplamalar ile ilgili endpointler.
*/
class StatsController extends Controller
{
/**
* NDT Calculation (General)
*
* Genel NDT hesaplama istatistiklerini getirir.
* Bu endpoint varsayılan 'ndt-calculation' blade cache sonucunu döndürür.
*
* @response 200 {
* "status": "success",
* "type": "general",
* "content": "..."
* }
*/
public function ndtCalculation()
{
// Varsayılan hesaplama (cacheBladeLoad('ndt-calculation'))
// cacheBladeLoad echo yaptığı için çıktıyı yakalıyoruz.
ob_start();
cacheBladeLoad('ndt-calculation');
$content = ob_get_clean();
// Eğer content bir JSON string ise decode et
$decoded = json_decode($content);
if (json_last_error() === JSON_ERROR_NONE) {
$content = $decoded;
}
return response()->json([
'status' => 'success',
'type' => 'general',
'content' => $content
]);
}
/**
* NDT Calculation (Test Packs)
*
* Test Paketleri için NDT hesaplama istatistiklerini getirir.
* 'ndtCalculationTestPack' ayarını döndürür.
*
* @response 200 {
* "status": "success",
* "type": "test_packs",
* "content": "..."
* }
*/
public function ndtCalculationTestPacks()
{
$content = setting('ndtCalculationTestPack');
// Eğer content bir JSON string ise decode et
$decoded = json_decode($content);
if (json_last_error() === JSON_ERROR_NONE) {
$content = $decoded;
}
return response()->json([
'status' => 'success',
'type' => 'test_packs',
'content' => $content
]);
}
/**
* NDT Calculation (Backlogs)
*
* Backloglar için NDT hesaplama istatistiklerini getirir.
* 'ndtCalculationBacklogs' ayarını döndürür.
*
* @queryParam type string Filtreleme türü (opsiyonel). Example: backlogs
*
* @response 200 {
* "status": "success",
* "type": "backlogs",
* "content": "..."
* }
*/
public function ndtCalculationBacklogs()
{
request()->merge(['type' => 'backlogs']);
$_GET['type'] = 'backlogs';
ob_start();
cacheBladeLoad('ndt-calculation');
$content = ob_get_clean();
// Eğer content bir JSON string ise decode et
$decoded = json_decode($content);
if (json_last_error() === JSON_ERROR_NONE) {
$content = $decoded;
}
return response()->json([
'status' => 'success',
'type' => 'backlogs',
'content' => $content
]);
}
/**
* Dashboard Overview Stats
*
* Get aggregated statistics for project overview dashboard.
* This endpoint is protected by a static hash.
* Includes:
* - WDI Monthly (Shop/Field/Total)
* - Spool Progress
* - NDT/Repair Backlog
* - Hand-over Status
* - Welding Equipment Status
*
* @header X-Api-Hash string required The static API hash for authentication. Example: your-secret-hash-key
*
* @response 200 {
* "status": "success",
* "data": {
* "wdi_monthly": [...],
* "spool_progress": [...],
* "ndt_backlog": [...],
* "handover_status": [...],
* "welding_equipment": [...]
* }
* }
*/
public function dashboardStats(\Illuminate\Http\Request $request)
{
$year = $request->input('year', date('Y'));
// 1. WDI Monthly Data (Global Aggregate) - Calendar Year
$wdiMonthly = WeldLog::selectRaw("
DATE_FORMAT(welding_date, '%Y-%m') as month,
MONTH(welding_date) as month_num,
SUM(CASE WHEN type_of_joint = 'S' THEN nps_1 ELSE 0 END) as shop,
SUM(CASE WHEN type_of_joint != 'S' OR type_of_joint IS NULL THEN nps_1 ELSE 0 END) as field,
SUM(nps_1) as total
")
->whereNotNull('welding_date')
// ->whereYear('welding_date', $year) // Removed to allow client-side filtering
->groupBy('month', 'month_num')
->orderBy('month', 'asc')
->get();
// 1b. WDI Monthly Data (By Project)
$wdiByProjectRaw = WeldLog::selectRaw("
project,
DATE_FORMAT(welding_date, '%Y-%m') as month,
MONTH(welding_date) as month_num,
SUM(CASE WHEN type_of_joint = 'S' THEN nps_1 ELSE 0 END) as shop,
SUM(CASE WHEN type_of_joint != 'S' OR type_of_joint IS NULL THEN nps_1 ELSE 0 END) as field,
SUM(nps_1) as total
")
->whereNotNull('welding_date')
->whereNotNull('project')
->where('project', '!=', '')
->whereYear('welding_date', $year) // Keep this for now or remove if needed, but it's unused by dashboard
->groupBy('project', 'month', 'month_num')
->get();
$wdiByProject = [];
foreach($wdiByProjectRaw as $row) {
// Use month_num (1-12) as key for the frontend table columns which expect 1..12
// For the new 'wdiByProject' which is custom for the table, we simply need the integer month key
// because the table logic iterates 1 through 12.
$wdiByProject[$row->project][$row->month_num] = [
'shop' => (float)$row->shop,
'field' => (float)$row->field,
'total' => (float)$row->total,
'month_str' => $row->month // Useful for debugging or generic logic
];
}
// 2. Spool Progress (Time-independent)
// Logic: Group by iso_number + spool_number (Shop only), find effective status based on priority logic.
// Priority: Waiting < Manufacturing < QC < Paint < Completed
$statusCase = "CASE spool_status
WHEN 'Waiting' THEN 1
WHEN 'Manufacturing' THEN 2
WHEN 'QC' THEN 3
WHEN 'Paint' THEN 4
WHEN 'Completed' THEN 5
ELSE 99 END";
$spoolStats = DB::table('weld_logs')
->selectRaw("status_val, COUNT(*) as count")
->fromSub(function($query) use ($statusCase) {
$query->select('iso_number', 'spool_number')
->selectRaw("MIN($statusCase) as status_order")
->selectRaw("
CASE MIN($statusCase)
WHEN 1 THEN 'Waiting'
WHEN 2 THEN 'Manufacturing'
WHEN 3 THEN 'QC'
WHEN 4 THEN 'Paint'
WHEN 5 THEN 'Completed'
ELSE 'Other'
END as status_val
")
->from('weld_logs')
->where('type_of_joint', 'S') // Shop joints drive spool status
->whereNotNull('spool_number')
->where('spool_number', '!=', '')
->whereNotNull('welding_date')
->groupBy('iso_number', 'spool_number');
}, 'sub')
->groupBy('status_val')
->get();
// Transform to array format for frontend
$spoolProgress = [];
foreach ($spoolStats as $row) {
$spoolProgress[] = [
'status' => $row->status_val,
'count' => (int)$row->count
];
}
// 3. NDT/Repair Backlog
// Using existing setting logic from ndt-backlog.blade.php
$ndtData = json_decode(setting("ndtCalculation"), true);
$ndtBacklogStats = [];
if (is_array($ndtData)) {
foreach($ndtData as $d) {
foreach($d as $field => $value) {
if(strpos($field, "backlog") !== false) {
$key = strtoupper(str_replace("_backlog", "", $field));
if(!isset($ndtBacklogStats[$key])) {
$ndtBacklogStats[$key] = 0;
}
if($value > 0) {
$ndtBacklogStats[$key] += $value;
}
}
}
}
}
// Add dynamic limits from Settings
$ndtBacklogStats['ndt_limit'] = setting('ndt_limit');
$ndtBacklogStats['ndt_wdi'] = setting('ndt_wdi');
$ndtBacklogStats['repair_limit'] = setting('repair_limit');
$ndtBacklogStats['repair_wdi'] = setting('repair_wdi');
// 4. Hand-over Status
// Statuses: Dynamically fetched from id_status
$handoverProgress = Handover::selectRaw('id_status, COUNT(*) as count')
->whereNotNull('id_status')
->where('id_status', '!=', '')
->groupBy('id_status')
->pluck('count', 'id_status')
->toArray();
// 5. Welding Equipment Status
// Statuses: Working, Repair, Out of use
$equipmentStats = WeldingEquipment::selectRaw('working_status, COUNT(*) as count')
->whereNotNull('working_status')
->groupBy('working_status')
->get()
->pluck('count', 'working_status');
$targetEquipmentStatuses = ['Working', 'Repair', 'Out of use'];
$equipmentProgress = [];
foreach ($targetEquipmentStatuses as $status) {
$equipmentProgress[$status] = $equipmentStats[$status] ?? 0;
}
// Add others
$otherEquipmentCount = 0;
foreach ($equipmentStats as $status => $count) {
if (!in_array($status, $targetEquipmentStatuses)) {
$otherEquipmentCount += $count;
}
}
if ($otherEquipmentCount > 0) {
$equipmentProgress['Other'] = $otherEquipmentCount;
}
// 6. Welding Status (Welder Distribution by Site)
// Logic: Group by project (Site).
// CS = distinct real_welder_1 & real_welder_2 where ru_material_group_1 matches 'M01'
// SS/AS = distinct real_welder_1 & real_welder_2 where ru_material_group_1 does NOT match 'M01'
$weldingStatusData = DB::table(function ($query) {
$query->select('project', 'type_of_joint', 'ru_material_group_1', 'real_welder_1 as welder', 'welding_date')
->from('weld_logs')
->whereNotNull('real_welder_1')
->where('real_welder_1', '!=', '')
->whereNotNull('welding_date')
->unionAll(
DB::table('weld_logs')
->select('project', 'type_of_joint', 'ru_material_group_2', 'real_welder_1 as welder', 'welding_date')
->from('weld_logs')
->whereNotNull('real_welder_2')
->where('real_welder_2', '!=', '')
->whereNotNull('welding_date')
);
}, 'u')
->select('project')
->selectRaw("YEAR(welding_date) as year")
->selectRaw("MONTH(welding_date) as month")
->selectRaw("COUNT(DISTINCT CASE WHEN type_of_joint = 'S' THEN welder END) as shop")
->selectRaw("COUNT(DISTINCT CASE WHEN type_of_joint != 'S' OR type_of_joint IS NULL THEN welder END) as field")
->selectRaw("COUNT(DISTINCT CASE WHEN (ru_material_group_1 LIKE '%M01%' OR ru_material_group_1 LIKE '%М01%') THEN welder END) as cs")
->selectRaw("COUNT(DISTINCT CASE WHEN (ru_material_group_1 NOT LIKE '%M01%' AND ru_material_group_1 NOT LIKE '%М01%') OR ru_material_group_1 IS NULL THEN welder END) as ss")
->selectRaw("COUNT(DISTINCT welder) as actual_total")
->whereNotNull('project')
->where('project', '!=', '')
->groupBy('project', 'year', 'month')
->get();
$weldingStatus = [];
foreach($weldingStatusData as $row) {
$weldingStatus[] = [
'site' => $row->project,
'year' => (int)$row->year,
'month' => (int)$row->month,
'shop' => (int)$row->shop,
'field' => (int)$row->field,
'cs' => (int)$row->cs,
'ss' => (int)$row->ss,
'total' => (int)$row->actual_total
];
}
// 7. Welding Status Overall Summary (No Site Breakdown)
// Count unique welders across ALL projects for Shop and Field
// 7. Welding Status Overall Summary (No Site Breakdown)
// Count unique welders across ALL projects for Shop and Field
$weldingSummaryRaw = DB::table(function ($query) {
$query->select('type_of_joint', 'real_welder_1 as welder')
->from('weld_logs')
->whereNotNull('real_welder_1')
->where('real_welder_1', '!=', '')
->whereNotNull('welding_date')
->unionAll(
DB::table('weld_logs')
->select('type_of_joint', 'real_welder_2 as welder')
->from('weld_logs')
->whereNotNull('real_welder_2')
->where('real_welder_2', '!=', '')
->whereNotNull('welding_date')
);
}, 'u')
->selectRaw("COUNT(DISTINCT CASE WHEN type_of_joint = 'S' THEN welder END) as shop")
->selectRaw("COUNT(DISTINCT CASE WHEN type_of_joint != 'S' OR type_of_joint IS NULL THEN welder END) as field")
->selectRaw("COUNT(DISTINCT welder) as actual_total")
->first();
$weldingStatusSummary = [
'shop' => (int)$weldingSummaryRaw->shop,
'field' => (int)$weldingSummaryRaw->field,
'total' => (int)$weldingSummaryRaw->actual_total
];
// 8. Welding Status Monthly (Shop/Field/Total per Month)
// Groups distinct welders by month and project
// 8. Welding Status Monthly (Shop/Field/Total per Month)
// Groups distinct welders by month (Global Site Scope)
$weldingStatusMonthly = DB::table(function ($query) use ($year) {
$query->select('project', 'welding_date', 'type_of_joint', 'real_welder_1 as welder')
->from('weld_logs')
->whereNotNull('real_welder_1')
->where('real_welder_1', '!=', '')
->whereNotNull('welding_date')
->unionAll(
DB::table('weld_logs')
->select('project', 'welding_date', 'type_of_joint', 'real_welder_2 as welder')
->from('weld_logs')
->whereNotNull('real_welder_2')
->where('real_welder_2', '!=', '')
->whereNotNull('welding_date')
);
}, 'u')
->selectRaw("
DATE_FORMAT(welding_date, '%Y-%m') as month_key,
MONTH(welding_date) as month,
YEAR(welding_date) as year,
COUNT(DISTINCT CASE WHEN type_of_joint = 'S' THEN welder END) as shop,
COUNT(DISTINCT CASE WHEN type_of_joint != 'S' OR type_of_joint IS NULL THEN welder END) as field,
COUNT(DISTINCT welder) as actual_total
")
->groupBy('month_key', 'month', 'year')
->orderBy('month_key', 'asc')
->get()
->map(function($item) {
return [
'project' => 'Total', // Value is now aggregated for the whole site
'month_key' => $item->month_key,
'month' => (int)$item->month,
'year' => (int)$item->year,
'shop' => (int)$item->shop,
'field' => (int)$item->field,
'total' => (int)$item->actual_total
];
});
// 9. NDT Summary (RT & UT)
// New calculation logic mirrored from summary-nocache.blade.php
$ndtSummary = [];
// RT Logic
$rtTotal = DB::table('radiographic_tests')->whereNotNull('rt_result')->count();
$rtWDI = DB::table('radiographic_tests')->whereNotNull('rt_result')->sum('nps_1');
$rtAccepted = DB::table('radiographic_tests')->where('rt_result', 'Accept / Годен')->count();
$rtRejected = DB::table('radiographic_tests')->whereNotNull('rt_result')->whereNotIn('rt_result', ['', 'Accept / Годен'])->count();
// RT Repair Rate logic: (ShopRepair + FieldRepair) / (ShopTotal + FieldTotal)
$rtShopTotal = DB::table('radiographic_tests')->where('type_of_joint', 'S')->whereNotIn('rt_result', [''])->count();
$rtShopRepair = DB::table('radiographic_tests')->where('type_of_joint', 'S')->whereNotIn('rt_result', ['', 'Accept / Годен'])->count();
$rtFieldTotal = DB::table('radiographic_tests')->where('type_of_joint', 'F')->whereNotIn('rt_result', [''])->count();
$rtFieldRepair = DB::table('radiographic_tests')->where('type_of_joint', 'F')->whereNotIn('rt_result', ['', 'Accept / Годен'])->count();
$rtRepairRate = ($rtShopTotal + $rtFieldTotal) > 0
? round(($rtShopRepair + $rtFieldRepair) * 100 / ($rtShopTotal + $rtFieldTotal), 2)
: 0;
$ndtSummary['rt'] = [
'total' => $rtTotal,
'wdi' => (float)$rtWDI,
'accepted' => $rtAccepted,
'rejected' => $rtRejected,
'repair_rate' => $rtRepairRate
];
// UT Logic
$utTotal = DB::table('ultrasonic_tests')->whereNotNull('ut_result')->count();
$utWDI = DB::table('ultrasonic_tests')->whereNotNull('ut_result')->sum('nps_1');
$utAccepted = DB::table('ultrasonic_tests')->where('ut_result', 'Accept / Годен')->count();
$utRejected = DB::table('ultrasonic_tests')->whereNotNull('ut_result')->where('ut_result', '!=', 'Accept / Годен')->count();
// UT Repair Rate
$utShopTotal = DB::table('ultrasonic_tests')->where('type_of_joint', 'S')->whereNotIn('ut_result', [''])->count();
$utShopRepair = DB::table('ultrasonic_tests')->where('type_of_joint', 'S')->whereNotIn('ut_result', ['', 'Accept / Годен'])->count();
$utFieldTotal = DB::table('ultrasonic_tests')->where('type_of_joint', 'F')->whereNotIn('ut_result', [''])->count();
$utFieldRepair = DB::table('ultrasonic_tests')->where('type_of_joint', 'F')->whereNotIn('ut_result', ['', 'Accept / Годен'])->count();
$utRepairRate = ($utShopTotal + $utFieldTotal) > 0
? round(($utShopRepair + $utFieldRepair) * 100 / ($utShopTotal + $utFieldTotal), 2)
: 0;
$ndtSummary['ut'] = [
'total' => $utTotal,
'wdi' => (float)$utWDI,
'accepted' => $utAccepted,
'rejected' => $utRejected,
'repair_rate' => $utRepairRate
];
// 10. WDI Statistics (CS vs SS/AS) by Project
// CS: Material Group contains M01
// SS: Material Group does not contain M01
$wdiStatsData = DB::table('weld_logs')
->select('project')
->selectRaw("YEAR(welding_date) as year")
->selectRaw("MONTH(welding_date) as month")
->selectRaw("SUM(CASE WHEN (ru_material_group_1 LIKE '%M01%' OR ru_material_group_1 LIKE '%М01%') THEN nps_1 ELSE 0 END) as cs_wdi")
->selectRaw("SUM(CASE WHEN (ru_material_group_1 NOT LIKE '%M01%' AND ru_material_group_1 NOT LIKE '%М01%') OR ru_material_group_1 IS NULL THEN nps_1 ELSE 0 END) as ss_wdi")
->whereNotNull('welding_date')
->where('project', '!=', '')
->whereNotNull('project')
->groupBy('project', 'year', 'month')
->get();
$wdiStats = [];
foreach($wdiStatsData as $row) {
$wdiStats[] = [
'project' => $row->project,
'year' => (int)$row->year,
'month' => (int)$row->month,
'cs' => (float)$row->cs_wdi,
'ss' => (float)$row->ss_wdi,
'total' => (float)$row->cs_wdi + (float)$row->ss_wdi
];
}
// 11. Weld Backlog (Prefab vs Field) by Project
// Backlog: Items with no welding date, grouped by year/month from fit_up_date for frontend filtering
$weldBacklogData = DB::table('weld_logs')
->select('project')
->selectRaw("SUM(CASE WHEN type_of_joint = 'S' THEN nps_1 ELSE 0 END) as prefab_backlog")
->selectRaw("SUM(CASE WHEN type_of_joint != 'S' OR type_of_joint IS NULL THEN nps_1 ELSE 0 END) as field_backlog")
->selectRaw("SUM(nps_1) as total_backlog")
->whereNull('welding_date')
->where('project', '!=', '')
->whereNotNull('project')
->groupBy('project')
->get();
$weldBacklog = [];
foreach($weldBacklogData as $row) {
$weldBacklog[] = [
'project' => $row->project,
'prefab' => (float)$row->prefab_backlog,
'field' => (float)$row->field_backlog,
'total' => (float)$row->total_backlog
];
}
// 12. Welder Current (from naks_welders table)
// Total unique welders at each site, categorized by CS/SS
// CS: material_1 contains М01 or M01
// SS: material_1 does NOT contain М01/M01
// No date filter - shows total registered welders per site
$welderCurrentData = DB::table('welder_tests')
->selectRaw("COUNT(DISTINCT CASE WHEN (material_group_1 LIKE '%M01%' OR material_group_1 LIKE '%М01%') THEN naks_id END) as cs")
->selectRaw("COUNT(DISTINCT CASE WHEN (material_group_1 NOT LIKE '%M01%' AND material_group_1 NOT LIKE '%М01%') OR material_group_1 IS NULL THEN naks_id END) as ss")
->selectRaw("COUNT(DISTINCT naks_id) as total")
->where('status', 'Active')
->get();
$welderCurrent = [];
foreach($welderCurrentData as $row) {
$welderCurrent[] = [
'project' => '',
'cs' => (int)$row->cs,
'ss' => (int)$row->ss,
'total' => (int)$row->total
];
}
return response()->json([
'status' => 'success',
'data' => [
'wdi_monthly' => $wdiMonthly,
'spool_progress' => $spoolProgress,
'ndt_backlog' => $ndtBacklogStats,
'handover_status' => $handoverProgress,
'welding_equipment' => $equipmentProgress,
'welding_status' => $weldingStatus,
'welding_status_monthly' => $weldingStatusMonthly,
'welding_status_summary' => $weldingStatusSummary,
'ndt_summary' => $ndtSummary,
'wdi_by_project' => $wdiByProject,
'wdi_stats' => $wdiStats,
'weld_backlog' => $weldBacklog,
'repair_stats_monthly' => DB::table('weld_logs')
->selectRaw("
DATE_FORMAT(welding_date, '%Y-%m') as month_key,
YEAR(welding_date) as year,
MONTH(welding_date) as month,
SUM(CASE WHEN type_of_joint = 'S' AND rt_result IS NOT NULL AND rt_result != '' THEN 1 ELSE 0 END) as rt_shop_total,
SUM(CASE WHEN type_of_joint = 'S' AND rt_result NOT IN ('', 'Accept / Годен') THEN 1 ELSE 0 END) as rt_shop_repair,
SUM(CASE WHEN type_of_joint = 'F' AND rt_result IS NOT NULL AND rt_result != '' THEN 1 ELSE 0 END) as rt_field_total,
SUM(CASE WHEN type_of_joint = 'F' AND rt_result NOT IN ('', 'Accept / Годен') THEN 1 ELSE 0 END) as rt_field_repair,
SUM(CASE WHEN type_of_joint = 'S' AND ut_result IS NOT NULL AND ut_result != '' THEN 1 ELSE 0 END) as ut_shop_total,
SUM(CASE WHEN type_of_joint = 'S' AND ut_result NOT IN ('', 'Accept / Годен') THEN 1 ELSE 0 END) as ut_shop_repair,
SUM(CASE WHEN type_of_joint = 'F' AND ut_result IS NOT NULL AND ut_result != '' THEN 1 ELSE 0 END) as ut_field_total,
SUM(CASE WHEN type_of_joint = 'F' AND ut_result NOT IN ('', 'Accept / Годен') THEN 1 ELSE 0 END) as ut_field_repair
")
->whereNotNull('welding_date')
->groupBy('month_key', 'year', 'month')
->get(),
'test_packages' => DB::table('test_packages')
->leftJoinSub(function ($query) {
$query->from('weld_logs')
->select(
'test_package_no',
DB::raw('MAX(project) as project'),
DB::raw('MAX(welding_date) as last_weld_date')
)
->whereNotNull('test_package_no')
->where('test_package_no', '!=', '')
->whereNotNull('welding_date')
->groupBy('test_package_no');
}, 'projects', 'projects.test_package_no', '=', 'test_packages.test_package_number')
->selectRaw("
COALESCE(projects.project, 'Unknown') as project,
count(test_packages.id) as total_tp,
SUM(CASE WHEN walkdown_date IS NOT NULL THEN 1 ELSE 0 END) as line_check,
SUM(COALESCE(a_punch_point_open, 0)) as punch_a,
SUM(CASE WHEN test_date IS NOT NULL THEN 1 ELSE 0 END) as test,
SUM(CASE WHEN reinstatement_date IS NOT NULL THEN 1 ELSE 0 END) as reinstatement
")
->groupBy(
DB::raw("COALESCE(projects.project, 'Unknown')")
)
->get(),
'welder_current' => $welderCurrent,
]
]);
}
/**
* Welding Status By Project
*
* Get summary data for "Sahaya Göre Kaynak Durumu" (Welding Status by Site).
* Breakdown of WDI (NPS-1) by project, grouped into SHOP and FIELD.
*
* @response 200 {
* "status": "success",
* "data": [
* {
* "project": "COOLER TOWER",
* "shop": 82,
* "field": 122,
* "total": 204,
* "percentage": 93
* },
* ...
* ]
* }
*/
public function weldingByProject()
{
$weldingData = DB::table('weld_logs')
->select('project')
->selectRaw("SUM(CASE WHEN type_of_joint = 'S' AND welding_date IS NOT NULL THEN nps_1 ELSE 0 END) as shop")
->selectRaw("SUM(CASE WHEN (type_of_joint != 'S' OR type_of_joint IS NULL) AND welding_date IS NOT NULL THEN nps_1 ELSE 0 END) as field")
->selectRaw("SUM(CASE WHEN welding_date IS NOT NULL THEN nps_1 ELSE 0 END) as total_welded")
->selectRaw("SUM(nps_1) as total_scope")
->whereNotNull('project')
->where('project', '!=', '')
->groupBy('project')
->get();
$result = $weldingData->map(function ($row) {
$totalWelded = (float)$row->total_welded;
$totalScope = (float)$row->total_scope;
$percentage = $totalScope > 0 ? round(($totalWelded / $totalScope) * 100) : 0;
return [
'project' => $row->project,
'shop' => (float)$row->shop,
'field' => (float)$row->field,
'total' => $totalWelded,
'percentage' => (int)$percentage
];
});
return response()->json([
'status' => 'success',
'data' => $result
]);
}
}