Files
2026-09-03 12:21:17 +02:00

277 lines
11 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Services;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
/**
* Logika domenowa studni (migracja site301A/site301E/site301inf).
*
* Zapisy są wielotabelowe i w legacy szły BEZ transakcji (ryzyko danych
* częściowych). Tu każdy zapis jest opakowany w DB::transaction() na
* połączeniu `softspm`.
*
* Lokalizacja słowników: kolumna języka wybierana wg locale (pl→POL/en→ENG/
* de→GER), domyślnie POL.
*/
class WellService
{
/** DRS_DEV_TYPE dla studni. */
private const DEV_TYPE_WELL = 12;
/** Domyślny status zasobu nowej studni (legacy: DRS_STATUS_DIC_ID=3). */
private const DEFAULT_STATUS_DIC_ID = 3;
private function db()
{
return DB::connection('softspm');
}
/** Kolumna języka w sys_dictionaries wg aktualnego locale. */
private function langColumn(): string
{
return match (app()->getLocale()) {
'en' => 'DIC_ENG_LANG',
'de' => 'DIC_GER_LANG',
default => 'DIC_POL_LANG',
};
}
// ===================== LOOKUPY (do formularzy) =====================
/** Ujęcia wody (bariera): SWI_ID => SWI_NAME. */
public function waterIntakes()
{
return $this->db()->table('seg_water_intakes')
->orderBy('SWI_NAME')
->pluck('SWI_NAME', 'SWI_ID');
}
/** Słownik po ID: DIC_ID => opis (dla WELL_CATEGORY, WELL_STATUS_LEVEL_01). */
public function dictionaryById(string $type)
{
$lang = $this->langColumn();
return $this->db()->table('sys_dictionaries')
->where('DIC_TYPE', $type)
->orderBy($lang)
->pluck($lang, 'DIC_ID');
}
/** Słownik po opisie: lista wartości tekstowych (dla WELL_SYSTEM_TYPE,
* WELL_STATUS_LEVEL_03 - legacy zapisuje sam opis, nie DIC_ID). */
public function dictionaryDescriptions(string $type)
{
$lang = $this->langColumn();
return $this->db()->table('sys_dictionaries')
->where('DIC_TYPE', $type)
->orderBy($lang)
->pluck($lang);
}
/** Dane studni do formularza edycji (wg zapytania z site301inf). */
public function findForEdit(int $drsId): ?object
{
$well = $this->db()->table('seg_wells as w')
->join('seg_dev_resources as drw', function ($j) {
$j->on('drw.DRS_DEV_ID', '=', 'w.WLL_ID')->where('drw.DRS_DEV_TYPE', '=', self::DEV_TYPE_WELL);
})
->leftJoin('seg_object_hole_cards as ohc', 'ohc.OHC_DRS_ID', '=', 'drw.DRS_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', $drsId)
->select([
'drw.DRS_ID as drs_id',
'w.WLL_ID as well_id',
'w.WLL_NAME as name',
'w.WLL_SWI_ID as water_intake_id',
'w.WLL_CAT_DIC_ID as category_id',
'w.WLL_PP_SCOPE as pp_scope',
'w.WLL_HH_SCOPE as hh_scope',
'w.WLL_SYS_TYPE as sys_type',
'w.WLL_STAT_DESC as status_desc',
'drw.DRS_RESOURCES_DIC_ID as status_id',
'drw.DRS_AVAILABLE_DATE as available_date',
'ohc.OHC_DL_GEOGR as latitude',
'ohc.OHC_SZER_GEOGR as longitude',
'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',
])
->first();
if (! $well) {
return null;
}
// Ostatnia zabudowa (do edycji daty zabudowy WLE_DATE_FROM).
$exchange = $this->db()->table('seg_wells_exchanged')
->where('WLE_WLL_ID', $well->well_id)
->orderByDesc('WLE_NR_EXCHANGE')
->first();
$well->wle_id = $exchange->WLE_ID ?? null;
$well->wle_date_from = $exchange->WLE_DATE_FROM ?? null;
return $well;
}
/** Czy istnieje studnia o danej nazwie (kontrola unikalności). */
public function nameExists(string $name): bool
{
return $this->db()->table('seg_wells')->where('WLL_NAME', $name)->exists();
}
// ===================== ZAPIS =====================
/**
* Dodanie studni - transakcyjny odpowiednik site301inf (linie 27-66).
* Zapisuje do: seg_wells, seg_dev_resources, seg_dev_resources_det (×3),
* seg_object_hole_cards, seg_object_hole_cards_his, seg_dev_resources_his.
*
* @return int DRS_ID utworzonego zasobu studni.
*/
public function create(array $data, string $department, string $user): int
{
return $this->db()->transaction(function () use ($data, $department, $user) {
$now = Carbon::now();
$intakeName = (string) $this->db()->table('seg_water_intakes')
->where('SWI_ID', $data['water_intake_id'])
->value('SWI_NAME');
$wellId = $this->db()->table('seg_wells')->insertGetId([
'WLL_NAME' => $data['name'],
'WLL_SWI_ID' => $data['water_intake_id'],
'WLL_BARIERA' => $intakeName,
'WLL_CAT_DIC_ID' => $data['category_id'],
'WLL_LATITUDE' => $this->decimal($data['latitude']),
'WLL_LONGITUDE' => $this->decimal($data['longitude']),
], 'WLL_ID');
$drsId = $this->db()->table('seg_dev_resources')->insertGetId([
'DRS_DEV_ID' => $wellId,
'DRS_DEV_TYPE' => self::DEV_TYPE_WELL,
'DRS_AVAILABLE_DATE' => $now->toDateString(),
'DRS_BUY_DATE' => $now->toDateString(),
'DRS_STATUS_DIC_ID' => self::DEFAULT_STATUS_DIC_ID,
'DRS_RESOURCES_DIC_ID' => $data['status_id'],
'DRS_DEPARTMENT' => $department,
'DRS_AUDIT_USR' => $user,
'DRS_AUDIT_DATE' => $now->toDateTimeString(),
], 'DRS_ID');
// Parametry techniczne: średnica (DST), głębokość (LS), zasilanie (LZ).
$this->insertDetail($drsId, 'DST', $this->decimal($data['diameter']), $now, $user);
$this->insertDetail($drsId, 'LS', $this->decimal($data['depth']), $now, $user);
$this->insertDetail($drsId, 'LZ', $this->decimal($data['supply']), $now, $user);
// Karta otworu.
$this->db()->table('seg_object_hole_cards')->insert([
'OHC_DRS_ID' => $drsId,
'OHC_UJ' => $intakeName,
'OHC_NAME' => $data['name'],
'OHC_DATA_ODDANIA' => $data['available_date'] ?? null,
'OHC_GLEB_ODWIER' => $data['depth'],
'OHC_GLEB_OSTAT' => $data['depth'],
'OHC_DL_GEOGR' => $this->decimal($data['latitude']),
'OHC_SZER_GEOGR' => $this->decimal($data['longitude']),
'OHC_PLC' => $department,
]);
$this->db()->table('seg_object_hole_cards_his')->insert([
'OHH_DRS_ID' => $drsId,
'OHH_UJ' => $intakeName,
'OHH_NAME' => $data['name'],
'OHH_ZASYP' => $data['supply'],
'OHH_PLC' => $department,
]);
// Kopia historyczna zasobu (kolumny _his identyczne z seg_dev_resources).
$this->db()->statement(
'INSERT INTO seg_dev_resources_his SELECT * FROM seg_dev_resources WHERE DRS_ID = ?',
[$drsId]
);
return $drsId;
});
}
/**
* Aktualizacja studni - transakcyjny odpowiednik site301inf (linie 138-155).
*/
public function update(int $drsId, array $data, string $user): void
{
$this->db()->transaction(function () use ($drsId, $data) {
$intakeName = (string) $this->db()->table('seg_water_intakes')
->where('SWI_ID', $data['water_intake_id'])
->value('SWI_NAME');
$this->db()->table('seg_wells')->where('WLL_ID', $data['well_id'])->update([
'WLL_NAME' => $data['name'],
'WLL_SWI_ID' => $data['water_intake_id'],
'WLL_BARIERA' => $intakeName,
'WLL_CAT_DIC_ID' => $data['category_id'],
'WLL_PP_SCOPE' => $data['pp_scope'],
'WLL_HH_SCOPE' => $data['hh_scope'],
'WLL_SYS_TYPE' => $data['sys_type'],
'WLL_STAT_DESC' => $data['status_desc'],
]);
$this->db()->table('seg_dev_resources')->where('DRS_ID', $drsId)->update([
'DRS_AVAILABLE_DATE' => $data['available_date'] ?: null,
'DRS_RESOURCES_DIC_ID' => $data['status_id'],
]);
$this->db()->table('seg_object_hole_cards')->where('OHC_DRS_ID', $drsId)->update([
'OHC_NAME' => $data['name'],
'OHC_UJ' => $intakeName,
'OHC_DL_GEOGR' => $data['latitude'],
'OHC_SZER_GEOGR' => $data['longitude'],
]);
// Data zabudowy ostatniego agregatu (tylko gdy istnieje wpis wymiany).
if (! empty($data['wle_id'])) {
$dateFrom = trim(($data['available_date'] ?? '').' '.($data['build_time'] ?? ''));
$this->db()->table('seg_wells_exchanged')->where('WLE_ID', $data['wle_id'])->update([
'WLE_DATE_FROM' => $dateFrom ?: null,
]);
}
});
}
// ===================== POMOCNICZE =====================
/** Wstawia parametr techniczny do seg_dev_resources_det (DIC po nazwie). */
private function insertDetail(int $drsId, string $dicName, string $value, Carbon $now, string $user): void
{
$detailId = $this->db()->table('sys_dictionaries')
->where('DIC_TYPE', 'WELL_TECHNICAL_PARAMETERS')
->where('DIC_NAME', $dicName)
->value('DIC_ID');
$this->db()->table('seg_dev_resources_det')->insert([
'DRD_DRS_ID' => $drsId,
'DRD_RESOURCES_DETAIL' => $detailId,
'DRD_VALUE' => $value,
'DRD_AUDIT_DATE' => $now->toDateTimeString(),
'DRD_AUDIT_USR' => $user,
]);
}
/** Normalizacja liczby (przecinek → kropka), jak getFloatValue w legacy. */
private function decimal(?string $value): string
{
return str_replace(',', '.', trim((string) $value));
}
}