545 lines
22 KiB
PHP
545 lines
22 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Http\Controllers\Concerns\SortsLists;
|
|
use App\Services\PumpService;
|
|
use App\Services\SyndisService;
|
|
use App\Services\WellAssessmentService;
|
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
/**
|
|
* Eksploatacja studni (legacy grupa site401). Osobny moduł pod sekcją
|
|
* Eksploatacja - NIE myli się z modułem Studnie (wells.*, sekcja Stan).
|
|
*
|
|
* Etap 1: lista eksploatacyjna (site401.php) + szkielet karty studni
|
|
* (site401mark). Dashboard ocen pracy układu, energochłonność, wykresy
|
|
* Hp/η, parametry pracy (site401inf) i podstrony (lift/mhis/offhis/demand)
|
|
* dokładamy w kolejnych etapach - opierają się na danych SYNDIS
|
|
* (rep_his_data_everyday, rep_soap_syndis_quality_data) i próbach pomp.
|
|
*/
|
|
class WellOperationController extends Controller
|
|
{
|
|
use SortsLists;
|
|
|
|
/** Status "Wszystkie" - wartość spoza słownika (jak legacy: 100). */
|
|
private const STATUS_ALL = 100;
|
|
|
|
/** Sortowalne kolumny listy (aliasy z joinów). */
|
|
private const SORTABLE = [
|
|
'name' => 'w.WLL_NAME',
|
|
'bariera' => 'w.WLL_BARIERA',
|
|
'pump' => 'p.PUP_NAME',
|
|
'pump_no' => 'drp.DRS_SN_NUMBER',
|
|
'engine' => 'e.ENG_NAME',
|
|
'engine_no' => 'dre.DRS_SN_NUMBER',
|
|
'type' => 'w.WLL_SYS_TYPE',
|
|
];
|
|
|
|
public function __construct(
|
|
private readonly PumpService $pumps,
|
|
private readonly WellAssessmentService $assess,
|
|
) {}
|
|
|
|
public function index(Request $request)
|
|
{
|
|
$department = $request->session()->get('department');
|
|
$search = trim((string) $request->query('q', ''));
|
|
$status = (int) $request->query('status', 3); // domyślnie jak legacy
|
|
|
|
[$sort, $dir] = $this->sortParams($request);
|
|
|
|
$statusOptions = DB::connection('softspm')->table('sys_dictionaries')
|
|
->whereIn('DIC_ID', [3, 4])
|
|
->orderBy('DIC_ID')
|
|
->pluck('DIC_POL_LANG', 'DIC_ID');
|
|
|
|
$wells = $this->buildQuery($department, $search, $status)
|
|
->when($sort !== null, fn ($q) => $q->orderBy(self::SORTABLE[$sort], $dir))
|
|
->orderBy('w.WLL_NAME')
|
|
->paginate(20)
|
|
->withQueryString();
|
|
|
|
$this->attachOnOff($wells);
|
|
|
|
return view('exploitation.wells.index', [
|
|
'wells' => $wells,
|
|
'search' => $search,
|
|
'status' => $status,
|
|
'statusOptions' => $statusOptions,
|
|
'statusAll' => self::STATUS_ALL,
|
|
'department' => $department,
|
|
]);
|
|
}
|
|
|
|
/** Karta eksploatacyjna studni (migracja site401mark). */
|
|
public function show(int $drs)
|
|
{
|
|
$well = $this->wellDetails($drs);
|
|
abort_if(! $well, 404);
|
|
|
|
$onoff = $this->lastOnOff($drs);
|
|
$m = $this->lastMeasurement($drs); // ostatni pomiar SYNDIS lub null
|
|
$lpDr = $this->lpDr($drs); // [Lp, Dr] lub [null, null]
|
|
$test = $this->pumpTest($well); // punkty próby pompy (kolekcja)
|
|
|
|
// Typ studni (WLL_CAT_DIC_ID): 18=BASE, 19=OPT, 20=inne (bez oceny), inaczej FULL.
|
|
$cat = (int) ($well->cat_dic_id ?? 0);
|
|
$grey = $cat === 20; // "SPM - inne" -> brak ocen (jak legacy)
|
|
|
|
// Krzywe z próby (skala BAZY = m³/h) - do obliczeń ocen/sprawności.
|
|
$hCurve = $test->map(fn ($p) => (object) ['x' => $p->q, 'y' => $p->h])->values();
|
|
$etaCurve = $test->map(fn ($p) => (object) ['x' => $p->q, 'y' => $p->n])->values();
|
|
$hasTest = $test->count() > 1;
|
|
|
|
$qn = (float) ($well->pump_qn ?? 0); // m³/h (obliczenia)
|
|
$q = $m?->q !== null ? (float) $m->q : null; // m³/h (obliczenia)
|
|
$hps = ($hasTest && $q !== null) ? $this->pumps->valueAt($hCurve, $q) : null; // do oceny H=f(Q)
|
|
$eta = $grey ? null : $this->assess->efficiency($q, $m?->hd, $m?->p2, $m?->pe);
|
|
|
|
$assessments = $grey ? null : [
|
|
'q' => $this->assess->q($qn, $q),
|
|
'hfq' => $this->assess->hfq($hps, $m?->pp, $m?->hh),
|
|
'throttle' => $this->assess->throttling($m?->hd, $m?->p1, $m?->p2),
|
|
'loss' => $this->assess->lineLoss($m?->p1, $m?->pp, $lpDr[0], $lpDr[1]),
|
|
];
|
|
|
|
// WYŚWIETLANIE: poza katalogami jednostka przepływu = m³/min (= m³/h / 60).
|
|
$toMin = fn (?float $v) => $v === null ? null : $v / 60;
|
|
$hCurveDisp = $hCurve->map(fn ($p) => (object) ['x' => $p->x / 60, 'y' => $p->y])->values();
|
|
$etaCurveDisp = $etaCurve->map(fn ($p) => (object) ['x' => $p->x / 60, 'y' => $p->y])->values();
|
|
$opQ = $toMin($q);
|
|
// Punkt pracy = wartości ZMIERZONE (nie rzutowane na krzywą próby):
|
|
// - wysokość podnoszenia Hp = Pp - Hh (manometryczna, z pomiaru),
|
|
// - sprawność = η obliczona (resETA). Odchyłka od krzywej = diagnostyka.
|
|
$opH = ($m && $m->pp !== null && $m->hh !== null) ? ((float) $m->pp - (float) $m->hh) : null;
|
|
$opEta = $eta;
|
|
|
|
$ry = $this->assess->redYellowLimit($qn);
|
|
$yg = $this->assess->yellowGreenLimit($qn);
|
|
|
|
return view('exploitation.wells.show', [
|
|
'well' => $well,
|
|
'onoff' => $onoff,
|
|
'measurement' => $m,
|
|
'qnMin' => $toMin($qn), // Qₙ w m³/min
|
|
'grey' => $grey,
|
|
'spmImage' => $this->spmImage($cat),
|
|
'diag' => $m?->dgn,
|
|
'assessments' => $assessments,
|
|
'energy' => $eta === null ? null : [
|
|
'eta' => $eta,
|
|
'ry' => $ry,
|
|
'yg' => $yg,
|
|
'zone' => $this->assess->energyZone($eta, $ry, $yg),
|
|
],
|
|
'hPlot' => $hasTest ? $this->pumps->plot($hCurveDisp) : null,
|
|
'etaPlot' => $hasTest ? $this->pumps->plot($etaCurveDisp) : null,
|
|
'opQ' => $opQ, // punkt pracy Q w m³/min
|
|
'opH' => $opH,
|
|
'opEta' => $opEta,
|
|
]);
|
|
}
|
|
|
|
/** Parametry pracy układu (migracja site401inf) - pełny zestaw pomiarów + dane techniczne. */
|
|
public function params(int $drs)
|
|
{
|
|
$well = $this->wellDetails($drs);
|
|
abort_if(! $well, 404);
|
|
|
|
$m = $this->lastMeasurement($drs);
|
|
|
|
// Dodatkowe parametry z detali (port getLastValue).
|
|
$extra = (object) [
|
|
'pb' => $this->lastDetailValue(225, $drs),
|
|
'throttle' => $this->lastDetailValue(730, $drs),
|
|
'energy_kwh' => $this->lastDetailValue(265, $drs),
|
|
'unit_energy' => $this->lastDetailValue(721, $drs),
|
|
];
|
|
|
|
// Parametry techniczne ze słownika WELL_TECHNICAL_PARAMETERS.
|
|
$techParams = DB::connection('softspm')->table('sys_dictionaries')
|
|
->where('DIC_TYPE', 'WELL_TECHNICAL_PARAMETERS')
|
|
->orderBy('DIC_ID')
|
|
->get(['DIC_ID', 'DIC_POL_LANG'])
|
|
->map(fn ($d) => (object) [
|
|
'label' => $d->DIC_POL_LANG,
|
|
'value' => $this->lastDetailValue((int) $d->DIC_ID, $drs),
|
|
]);
|
|
|
|
[$lp, $dr] = $this->lpDr($drs);
|
|
|
|
// Ostatnie zwierciadło statyczne >0 (jak site401bpow - osobne zapytanie).
|
|
$hst = DB::connection('softspm')->table('rep_his_data_everyday')
|
|
->where('RHD_DRS_ID', $drs)->where('RHD_HST_VAL', '>', 0)
|
|
->orderByDesc('RHD_ID')->value('RHD_HST_VAL');
|
|
|
|
return view('exploitation.wells.params', [
|
|
'well' => $well,
|
|
'measurement' => $m,
|
|
'extra' => $extra,
|
|
'techParams' => $techParams,
|
|
'lp' => $lp,
|
|
'dr' => $dr,
|
|
'mParam' => $this->lastDetailValue(251, $drs),
|
|
'category' => DB::connection('softspm')->table('sys_dictionaries')->where('DIC_ID', $well->cat_dic_id)->value('DIC_POL_LANG'),
|
|
'availableDate' => DB::connection('softspm')->table('seg_dev_resources')->where('DRS_ID', $drs)->value('DRS_AVAILABLE_DATE'),
|
|
'onoff' => $this->lastOnOff($drs),
|
|
'power' => $this->powerBalance($m, $lp, $dr, $hst === null ? null : (float) $hst),
|
|
'historyParams' => DB::connection('softspm')->table('sys_dictionaries')
|
|
->whereIn('DIC_ID', [200, 205, 210, 212, 215, 220, 245, 401, 402, 260, 270, 275, 280, 255])
|
|
->orderBy('DIC_POL_LANG')->pluck('DIC_POL_LANG', 'DIC_ID'),
|
|
]);
|
|
}
|
|
|
|
/** Ręczny zapis pomiaru (migracja edycji „Modyfikuj" z site401inf). */
|
|
public function paramsStore(int $drs, Request $request)
|
|
{
|
|
$well = $this->wellDetails($drs);
|
|
abort_if(! $well, 404);
|
|
|
|
$request->validate(['date' => ['required', 'date']]);
|
|
|
|
$num = fn ($k) => $request->filled($k) ? (float) str_replace(',', '.', (string) $request->input($k)) : null;
|
|
$dt = $request->input('date').' '.($request->filled('time') ? $request->input('time').':00' : now()->format('H:i:s'));
|
|
$user = $request->user()->USR_USERNAME;
|
|
|
|
$qH = $num('q') !== null ? $num('q') * 60 : null; // wpis w m³/min -> baza m³/h
|
|
|
|
DB::connection('softspm')->transaction(function () use ($drs, $num, $qH, $dt, $user) {
|
|
DB::connection('softspm')->table('rep_his_data_everyday')->insert([
|
|
'RHD_DRS_ID' => $drs,
|
|
'RHD_DATE' => $dt,
|
|
'RHD_Q_VAL' => $qH,
|
|
'RHD_HD_VAL' => $num('hd'),
|
|
'RHD_HST_VAL' => $num('hst'),
|
|
'RHD_HST0_VAL' => $num('hst0'),
|
|
'RHD_P1_VAL' => $num('p1'),
|
|
'RHD_P2_VAL' => $num('p2'),
|
|
'RHD_VM3_VAL' => $num('vm3'),
|
|
'RHD_WTEMP_VAL' => $num('wtemp'),
|
|
'RHD_PP_VAL' => $num('pp'),
|
|
'RHD_HH_VAL' => $num('hh'),
|
|
'RHD_PE_VAL' => $num('pe'),
|
|
'RHD_I_VAL' => $num('i'),
|
|
'RHD_U_VAL' => $num('u'),
|
|
'RHD_COS_VAL' => $num('cos'),
|
|
'RHD_WORK_TIME_VAL' => $num('work_time'),
|
|
'RHD_AUDIT_CD' => now()->toDateTimeString(),
|
|
]);
|
|
|
|
$details = [
|
|
200 => $qH, 205 => $num('hd'), 210 => $num('hst'), 212 => $num('hst0'),
|
|
215 => $num('p1'), 220 => $num('p2'), 225 => $num('pb'), 230 => $num('vm3'),
|
|
245 => $num('wtemp'), 401 => $num('pp'), 402 => $num('hh'), 730 => $num('throttle'),
|
|
260 => $num('pe'), 265 => $num('energy_kwh'), 270 => $num('i'), 275 => $num('u'),
|
|
280 => $num('cos'), 290 => $num('work_time'), 721 => $num('unit_energy'),
|
|
];
|
|
foreach ($details as $detail => $value) {
|
|
if ($value === null) {
|
|
continue;
|
|
}
|
|
DB::connection('softspm')->table('seg_dev_resources_det')->insert([
|
|
'DRD_DRS_ID' => $drs,
|
|
'DRD_RESOURCES_DETAIL' => $detail,
|
|
'DRD_VALUE' => (string) $value,
|
|
'DRD_AUDIT_USR' => $user,
|
|
'DRD_AUDIT_DATE' => $dt,
|
|
]);
|
|
}
|
|
});
|
|
|
|
return redirect()->route('well-operation.params', $drs)->with('status', 'Zapisano ręczny pomiar.');
|
|
}
|
|
|
|
/**
|
|
* Bilans mocy układu (port nowszego site401bpow.php). Dane z ostatniego
|
|
* pomiaru (rep_his_data_everyday) + Lp/Dr. Skala Q = m³/h (stała 0,002752
|
|
* ≈ moc hydrauliczna [kW] = Q·H/363). Zwraca składowe mocy lub null.
|
|
*/
|
|
private function powerBalance(?object $m, ?float $lp, ?float $dr, ?float $hst): ?array
|
|
{
|
|
if (! $m || $m->q === null || $m->pe === null) {
|
|
return null;
|
|
}
|
|
|
|
$q = (float) $m->q;
|
|
$pe = (float) $m->pe;
|
|
$pp = (float) ($m->pp ?? 0);
|
|
$hh = (float) ($m->hh ?? 0);
|
|
$p1 = (float) ($m->p1 ?? 0);
|
|
$p2 = (float) ($m->p2 ?? 0);
|
|
$hstV = (float) ($hst ?? 0);
|
|
$lpV = (float) ($lp ?? 0);
|
|
$drV = (float) ($dr ?? 0);
|
|
|
|
$k = 0.002752;
|
|
$vel = $drV > 0 ? $q / (2826 * $drV * $drV) : 0.0; // prędkość w rurociągu
|
|
$hct = ($vel * $vel) / 19.62; // wysokość prędkości
|
|
|
|
$pod = $k * $q * (($pp - $hh) + $hct);
|
|
$paz = $pe - $pod;
|
|
$psl = $k * $q * ($pp - ($lpV + $p1));
|
|
$psa = $k * $q * ($p1 - $p2);
|
|
$pp2 = $k * $q * ($p2 + $hct);
|
|
$pst = $k * $q * $hstV;
|
|
$pgh = $pod - ($pst + $pp2 + $psl + $psa);
|
|
|
|
return [
|
|
'pe' => $pe,
|
|
'pod' => $pod,
|
|
'paz' => $paz,
|
|
'psl' => $psl,
|
|
'psa' => $psa,
|
|
'pp2' => $pp2,
|
|
'pst' => $pst,
|
|
'pgh' => $pgh,
|
|
'sum' => $paz + $psl + $psa + $pp2 + $pst + $pgh,
|
|
];
|
|
}
|
|
|
|
/** Pobranie aktualnych danych z SYNDIS (migracja site401mark&data=refresh + ajax_getdata4well). */
|
|
public function fetchData(int $drs, Request $request, SyndisService $syndis)
|
|
{
|
|
$well = $this->wellDetails($drs);
|
|
abort_if(! $well, 404);
|
|
|
|
try {
|
|
$saved = $syndis->refreshWell($drs, $well->well_name, $request->user()->USR_USERNAME);
|
|
|
|
return redirect()->route('well-operation.show', $drs)->with(
|
|
$saved ? 'status' : 'error',
|
|
$saved
|
|
? 'Pobrano aktualne dane z SYNDIS dla studni „'.$well->well_name.'".'
|
|
: 'Studnia wyłączona lub brak aktualnych danych w SYNDIS.'
|
|
);
|
|
} catch (\Throwable $e) {
|
|
return redirect()->route('well-operation.show', $drs)
|
|
->with('error', 'Nie udało się pobrać danych z SYNDIS: '.$e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Lista eksploatacyjna - jedno zapytanie z joinami (pompa/silnik), stan
|
|
* ON/OFF dociągany osobno dla bieżącej strony. Wierne site401.php.
|
|
*/
|
|
private function buildQuery(?string $department, string $search, int $status)
|
|
{
|
|
return DB::connection('softspm')
|
|
->table('seg_wells as w')
|
|
->leftJoin('seg_dev_resources as drw', function ($j) {
|
|
$j->on('drw.DRS_DEV_ID', '=', 'w.WLL_ID')->where('drw.DRS_DEV_TYPE', '=', 12);
|
|
})
|
|
->leftJoin('seg_well_pump_eng_rel as rel', 'rel.RWL_WLL_ID', '=', 'w.WLL_ID')
|
|
->leftJoin('seg_dev_resources as drp', function ($j) {
|
|
$j->on('drp.DRS_ID', '=', 'rel.RWL_PUP_DRS_ID')->where('drp.DRS_DEV_TYPE', '=', 10);
|
|
})
|
|
->leftJoin('seg_pumps as p', 'p.PUP_ID', '=', 'drp.DRS_DEV_ID')
|
|
->leftJoin('seg_dev_resources as dre', function ($j) {
|
|
$j->on('dre.DRS_ID', '=', 'rel.RWL_ENG_DRS_ID')->where('dre.DRS_DEV_TYPE', '=', 11);
|
|
})
|
|
->leftJoin('seg_engines as e', 'e.ENG_ID', '=', 'dre.DRS_DEV_ID')
|
|
->where('drw.DRS_DEPARTMENT', $department)
|
|
->when($search !== '', fn ($q) => $q->where('w.WLL_NAME', 'like', '%'.$search.'%'))
|
|
->when($status !== self::STATUS_ALL, fn ($q) => $q->where('drw.DRS_STATUS_DIC_ID', $status))
|
|
->select([
|
|
'drw.DRS_ID as drs_id',
|
|
'w.WLL_NAME as well_name',
|
|
'w.WLL_BARIERA as bariera',
|
|
'p.PUP_NAME as pump_name',
|
|
'drp.DRS_SN_NUMBER as pump_no',
|
|
'e.ENG_NAME as engine_name',
|
|
'dre.DRS_SN_NUMBER as engine_no',
|
|
'w.WLL_SYS_TYPE as sys_type',
|
|
]);
|
|
}
|
|
|
|
/** Stan ON/OFF (DRD_RESOURCES_DETAIL=507) tylko dla studni z bieżącej strony. */
|
|
private function attachOnOff(LengthAwarePaginator $wells): void
|
|
{
|
|
$ids = collect($wells->items())->pluck('drs_id')->filter()->values()->all();
|
|
|
|
$values = empty($ids) ? collect() : DB::connection('softspm')
|
|
->table('seg_dev_resources_det as d')
|
|
->joinSub(
|
|
DB::connection('softspm')->table('seg_dev_resources_det')
|
|
->select('DRD_DRS_ID', DB::raw('MAX(DRD_ID) as max_id'))
|
|
->where('DRD_RESOURCES_DETAIL', 507)
|
|
->whereIn('DRD_DRS_ID', $ids)
|
|
->groupBy('DRD_DRS_ID'),
|
|
'mx', 'mx.max_id', '=', 'd.DRD_ID'
|
|
)
|
|
->pluck('d.DRD_VALUE', 'd.DRD_DRS_ID');
|
|
|
|
foreach ($wells->items() as $row) {
|
|
$row->onoff = $values[$row->drs_id] ?? null;
|
|
}
|
|
}
|
|
|
|
/** Podstawowe dane studni + układu pompowego (część site401mark). */
|
|
private function wellDetails(int $drs): ?object
|
|
{
|
|
return DB::connection('softspm')
|
|
->table('seg_dev_resources as drw')
|
|
->join('seg_wells as w', 'w.WLL_ID', '=', 'drw.DRS_DEV_ID')
|
|
->leftJoin('seg_well_pump_eng_rel as rel', 'rel.RWL_WLL_ID', '=', 'w.WLL_ID')
|
|
->leftJoin('seg_dev_resources as drp', function ($j) {
|
|
$j->on('drp.DRS_ID', '=', 'rel.RWL_PUP_DRS_ID')->where('drp.DRS_DEV_TYPE', '=', 10);
|
|
})
|
|
->leftJoin('seg_pumps as p', 'p.PUP_ID', '=', 'drp.DRS_DEV_ID')
|
|
->leftJoin('seg_dev_resources as dre', function ($j) {
|
|
$j->on('dre.DRS_ID', '=', 'rel.RWL_ENG_DRS_ID')->where('dre.DRS_DEV_TYPE', '=', 11);
|
|
})
|
|
->leftJoin('seg_engines as e', 'e.ENG_ID', '=', 'dre.DRS_DEV_ID')
|
|
->where('drw.DRS_ID', $drs)
|
|
->where('drw.DRS_DEV_TYPE', 12)
|
|
->select([
|
|
'drw.DRS_ID as drs_id',
|
|
'w.WLL_ID as well_id',
|
|
'w.WLL_NAME as well_name',
|
|
'w.WLL_BARIERA as bariera',
|
|
'w.WLL_SYS_TYPE as sys_type',
|
|
'w.WLL_CAT_DIC_ID as cat_dic_id',
|
|
'p.PUP_ID as pump_id',
|
|
'p.PUP_NAME as pump_name',
|
|
'drp.DRS_SN_NUMBER as pump_no',
|
|
'p.PUP_Q_N as pump_qn',
|
|
'e.ENG_NAME as engine_name',
|
|
'dre.DRS_SN_NUMBER as engine_no',
|
|
'e.ENG_VOLTAGE as engine_voltage',
|
|
])
|
|
->first();
|
|
}
|
|
|
|
/** Ostatni pomiar SYNDIS (rep_his_data_everyday) dla studni lub null. */
|
|
private function lastMeasurement(int $drs): ?object
|
|
{
|
|
$r = DB::connection('softspm')->table('rep_his_data_everyday')
|
|
->where('RHD_DRS_ID', $drs)
|
|
->orderByDesc('RHD_ID')
|
|
->first();
|
|
|
|
if (! $r) {
|
|
return null;
|
|
}
|
|
|
|
return (object) [
|
|
'q' => $r->RHD_Q_VAL,
|
|
'hd' => $r->RHD_HD_VAL,
|
|
'hst' => $r->RHD_HST_VAL,
|
|
'hst0' => $r->RHD_HST0_VAL,
|
|
'p1' => $r->RHD_P1_VAL,
|
|
'p2' => $r->RHD_P2_VAL,
|
|
'pp' => $r->RHD_PP_VAL,
|
|
'hh' => $r->RHD_HH_VAL,
|
|
'pe' => $r->RHD_PE_VAL,
|
|
'i' => $r->RHD_I_VAL,
|
|
'u' => $r->RHD_U_VAL,
|
|
'cos' => $r->RHD_COS_VAL,
|
|
'vm3' => $r->RHD_VM3_VAL,
|
|
'wtemp' => $r->RHD_WTEMP_VAL,
|
|
'work_time' => $r->RHD_WORK_TIME_VAL,
|
|
'dgn' => $r->RHD_DGN_VAL,
|
|
'date' => $r->RHD_DATE,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Lp (głębokość zabudowy pompy, detal 240) i Dr (średnica rurociągu,
|
|
* detal 235/1000). Zastępuje funkcję składowaną MySQL getLastValue
|
|
* własnym zapytaniem (optymalizacja - bez zależności od procedur w bazie).
|
|
*/
|
|
private function lpDr(int $drs): array
|
|
{
|
|
$lp = $this->lastDetailValue(240, $drs);
|
|
$dr = $this->lastDetailValue(235, $drs);
|
|
|
|
return [
|
|
$lp !== null ? (float) $lp : null,
|
|
$dr !== null ? (float) $dr / 1000 : null,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Ostatnia wartość detalu zasobu (port funkcji składowanej getLastValue):
|
|
* DRD_VALUE z seg_dev_resources_det dla danego detalu i zasobu, po
|
|
* najpóźniejszej dacie audytu (rozstrzyganie po DRD_ID).
|
|
*/
|
|
private function lastDetailValue(int $detail, int $drs): ?string
|
|
{
|
|
return DB::connection('softspm')->table('seg_dev_resources_det')
|
|
->where('DRD_RESOURCES_DETAIL', $detail)
|
|
->where('DRD_DRS_ID', $drs)
|
|
->orderByDesc('DRD_AUDIT_DATE')
|
|
->orderByDesc('DRD_ID')
|
|
->value('DRD_VALUE');
|
|
}
|
|
|
|
/**
|
|
* Punkty próby pompy ze stacji prób (tst_tests + tst_test_details):
|
|
* q=TSD_VAL_04, h=TSD_VAL_08, p=TSD_VAL_14, n=TSD_VAL_18 (skala m³/h, bez /60).
|
|
* Dobór próby: po PUP_ID + nr fabrycznych pompy/silnika (fallback bez silnika).
|
|
*/
|
|
private function pumpTest(object $well): Collection
|
|
{
|
|
if (empty($well->pump_id)) {
|
|
return collect();
|
|
}
|
|
|
|
$base = DB::connection('softspm')->table('tst_tests')
|
|
->where('TST_PUP_ID', $well->pump_id)
|
|
->where('TST_PUP_SN_NO', $well->pump_no);
|
|
|
|
$testId = (clone $base)->where('TST_ENG_SN_NO', $well->engine_no)->max('TST_ID')
|
|
?? $base->max('TST_ID');
|
|
|
|
if (! $testId) {
|
|
return collect();
|
|
}
|
|
|
|
return DB::connection('softspm')->table('tst_test_details')
|
|
->where('TSD_TST_ID', $testId)
|
|
->orderBy('TSD_MSR_STEP')
|
|
->get()
|
|
->map(fn ($d) => (object) [
|
|
'q' => (float) $d->TSD_VAL_04,
|
|
'h' => (float) $d->TSD_VAL_08,
|
|
'p' => (float) $d->TSD_VAL_14,
|
|
'n' => (float) $d->TSD_VAL_18,
|
|
])
|
|
->filter(fn ($p) => $p->q > 0)
|
|
->values();
|
|
}
|
|
|
|
/** Plik schematu SPM wg kategorii studni (18=BASE, 19=OPT, inaczej FULL). */
|
|
private function spmImage(int $cat): string
|
|
{
|
|
return match ($cat) {
|
|
18 => 'images/spm_base.png',
|
|
19 => 'images/spm_opt.png',
|
|
default => 'images/spm_full.png',
|
|
};
|
|
}
|
|
|
|
/** Ostatni wpis ON/OFF dla studni (wartość, data, powód wyłączenia). */
|
|
private function lastOnOff(int $drs): ?object
|
|
{
|
|
$row = DB::connection('softspm')->table('seg_dev_resources_det')
|
|
->where('DRD_RESOURCES_DETAIL', 507)
|
|
->where('DRD_DRS_ID', $drs)
|
|
->orderByDesc('DRD_ID')
|
|
->first();
|
|
|
|
if ($row && ! empty($row->DRD_DESCRIPTION)) {
|
|
$row->reason = DB::connection('softspm')->table('sys_dictionaries')
|
|
->where('DIC_ID', $row->DRD_DESCRIPTION)
|
|
->value('DIC_POL_LANG');
|
|
}
|
|
|
|
return $row;
|
|
}
|
|
}
|