where('supplier_id', $supplierId) ->when($exceptFileId, fn ($query) => $query->whereKeyNot($exceptFileId)) ->whereIn('status', [ PricelistFileStatusEnum::execution_failed->value, PricelistFileStatusEnum::inprogress->value, ]) ->latest('id') ->get() // Az `inprogress` önmagában nem blokkol: az előfeldolgozás és a validálás // egyetlen terméket sem ír, ezért közben nyugodtan feltölthető másik fájl. // Csak az számít, ahol a végrehajtás már elindult - ezt a workflow_steps // JSON tartalma dönti el, amit SQL-ben nem szűrnénk tisztán, a beszállítónkénti // jelöltek száma viszont elenyésző. ->first(fn (PricelistFile $file) => $file->status === PricelistFileStatusEnum::execution_failed || $file->hasExecutionStarted()); } public function isBlocked(?int $supplierId, ?int $exceptFileId = null): bool { return $this->blockingFileFor($supplierId, $exceptFileId) !== null; } /** * Felhasználónak szóló magyarázat: melyik fájl blokkol és miért. */ public function blockingMessage(PricelistFile $blockingFile): string { $state = $blockingFile->status === PricelistFileStatusEnum::execution_failed ? 'végrehajtása hibára futott' : 'végrehajtása jelenleg fut'; return sprintf( 'A beszállítóhoz tartozó "%s" árlista (#%d) %s. Amíg ez nincs lezárva (folytatás vagy visszavonás), nem indítható újabb árlista-feldolgozás, mert a termékadatok félig frissített állapotban lehetnek.', $blockingFile->filename, $blockingFile->id, $state, ); } }