277 lines
11 KiB
PHP
277 lines
11 KiB
PHP
<?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));
|
||
}
|
||
}
|