'EQU_NAME', 'mcf' => 'm.MCF_NAME', ]; public function __construct(private readonly EquipmentFileService $files) {} public function index(Request $request) { $q = trim((string) $request->query('q', '')); $mcf = (int) $request->query('mcf', self::MCF_ALL); [$sort, $dir] = $this->sortParams($request); $items = Equipment::query() ->visible()->ofType(self::TYPE_METERING)->with('manufacturer') ->when($q !== '', fn ($w) => $w->where('EQU_NAME', 'like', '%'.$q.'%')) ->when($mcf !== self::MCF_ALL, fn ($w) => $w->where('EQU_MCF_ID', $mcf)) ->when($sort === 'mcf', fn ($w) => $w ->leftJoin('seg_manufacturers as m', 'm.MCF_ID', '=', 'seg_equipments.EQU_MCF_ID') ->select('seg_equipments.*')) ->when($sort !== null, fn ($w) => $w->orderBy(self::SORTABLE[$sort], $dir)) ->orderBy('EQU_NAME') ->paginate(20) ->withQueryString(); return view('catalog.metering.index', [ 'items' => $items, 'manufacturers' => $this->manufacturers(), 'q' => $q, 'mcf' => $mcf, 'mcfAll' => self::MCF_ALL, ]); } public function create() { return view('catalog.metering.create', ['manufacturers' => $this->manufacturers()]); } public function store(StoreMeteringRequest $request) { $data = $request->validated(); $item = Equipment::create([ 'EQU_NAME' => $data['name'], 'EQU_MCF_ID' => $data['manufacturer_id'], 'EQU_DESCRIPTION' => $data['description'] ?? null, 'EQU_PARAM_02' => $this->defaultCategoryId(), // kategoria SPM_FULL (jak legacy) 'EQU_TYPE_ID' => self::TYPE_METERING, 'EQU_STATUS' => '1', ]); $this->saveFiles($request, $item->EQU_ID); return redirect()->route('metering.show', $item) ->with('status', 'Dodano urządzenie „'.$item->EQU_NAME.'".'); } public function show(Equipment $metering) { abort_unless((int) $metering->EQU_TYPE_ID === self::TYPE_METERING, 404); $metering->load('manufacturer', 'files'); return view('catalog.metering.show', [ 'item' => $metering, 'document' => $metering->files->first(fn ($f) => ! $f->isImage()), 'image' => $metering->files->first(fn ($f) => $f->isImage()), 'inUse' => $this->inUse($metering->EQU_ID), ]); } public function edit(Equipment $metering) { abort_unless((int) $metering->EQU_TYPE_ID === self::TYPE_METERING, 404); $metering->load('manufacturer', 'files'); return view('catalog.metering.edit', [ 'item' => $metering, 'manufacturers' => $this->manufacturers(), 'document' => $metering->files->first(fn ($f) => ! $f->isImage()), 'image' => $metering->files->first(fn ($f) => $f->isImage()), ]); } public function update(UpdateMeteringRequest $request, Equipment $metering) { abort_unless((int) $metering->EQU_TYPE_ID === self::TYPE_METERING, 404); $data = $request->validated(); // Legacy update aktualizuje tylko nazwę/producenta/opis (kategoria zostaje). $metering->update([ 'EQU_NAME' => $data['name'], 'EQU_MCF_ID' => $data['manufacturer_id'], 'EQU_DESCRIPTION' => $data['description'] ?? null, ]); $this->saveFiles($request, $metering->EQU_ID); return redirect()->route('metering.show', $metering) ->with('status', 'Zaktualizowano urządzenie „'.$metering->EQU_NAME.'".'); } public function destroy(Equipment $metering) { abort_unless((int) $metering->EQU_TYPE_ID === self::TYPE_METERING, 404); // Legacy: blokuj, gdy urządzenie jest użyte jako zasób (seg_dev_resources, typ 14). if ($this->inUse($metering->EQU_ID)) { return redirect()->route('metering.show', $metering) ->with('error', 'Nie można usunąć - urządzenie jest użyte w stanie opomiarowania.'); } $metering->update(['EQU_STATUS' => '0']); // usuwanie logiczne return redirect()->route('metering.index') ->with('status', 'Usunięto urządzenie „'.$metering->EQU_NAME.'".'); } private function saveFiles(Request $request, int $equId): void { $user = $request->user()->USR_USERNAME; if ($request->hasFile('catalogue_file')) { $this->files->store($equId, $request->file('catalogue_file'), $user); } if ($request->hasFile('image_file')) { $this->files->store($equId, $request->file('image_file'), $user); } } /** Czy urządzenie jest użyte jako zasób opomiarowania (seg_dev_resources, typ 14). */ private function inUse(int $equId): bool { return DB::connection('softspm')->table('seg_dev_resources') ->where('DRS_DEV_TYPE', self::TYPE_METERING) ->where('DRS_DEV_ID', $equId) ->exists(); } /** DIC_ID słownikowej kategorii WELL_CATEGORY/SPM_FULL (jak hidden w site208A). */ private function defaultCategoryId(): ?int { return DB::connection('softspm')->table('sys_dictionaries') ->where('DIC_TYPE', 'WELL_CATEGORY') ->where('DIC_NAME', 'SPM_FULL') ->value('DIC_ID'); } private function manufacturers() { return Manufacturer::orderBy('MCF_NAME')->pluck('MCF_NAME', 'MCF_ID'); } }