addArgument('doctor-uuid', InputArgument::REQUIRED, 'Doctor uuid') ->addArgument('clinic-uuid', InputArgument::REQUIRED, 'Target clinic uuid') ->addOption('force', null, InputOption::VALUE_NONE, 'Move even when some sessions use an address outside the clinic'); } protected function execute(InputInterface $input, OutputInterface $output): int { $io = new SymfonyStyle($input, $output); $doctor = $this->doctorRepo->findByUuid((string) $input->getArgument('doctor-uuid')); $clinic = $this->clinicRepo->findByUuid((string) $input->getArgument('clinic-uuid')); if ($doctor === null || $clinic === null) { $io->error('Doctor or clinic not found.'); return Command::FAILURE; } if (!$clinic->hasDoctor($doctor)) { $io->error('This doctor is not a member of that clinic.'); return Command::FAILURE; } $schedule = $this->scheduleRepo->findByDoctorAndClinic($doctor, null); if ($schedule === null) { $io->warning('This doctor has no personal schedule to move.'); return Command::SUCCESS; } if ($this->scheduleRepo->findByDoctorAndClinic($doctor, $clinic) !== null) { $io->error('A schedule already exists for this doctor in that clinic; merge it manually.'); return Command::FAILURE; } $foreign = $this->sessionsOutsideClinic($schedule->getDaySchedule(), $doctor, $clinic->getId()); if ($foreign !== [] && !$input->getOption('force')) { $io->error(sprintf( 'Sessions use address ids outside the clinic: %s. Re-run with --force to move anyway.', implode(', ', $foreign) )); return Command::FAILURE; } $schedule->setClinic($clinic); $this->em->flush(); $io->success(sprintf('Schedule %s moved to clinic "%s".', $schedule->getUuid(), $clinic->getName())); return Command::SUCCESS; } /** @return int[] address ids referenced by the schedule that the clinic does not own */ private function sessionsOutsideClinic(array $daySchedule, \App\Doctor\Entity\Doctor $doctor, int $clinicId): array { $owned = []; foreach ($this->addressRepo->findForContext($doctor, $clinicId) as $address) { $owned[(int) $address->getId()] = true; } $foreign = []; foreach ($daySchedule as $day) { foreach (($day['sessions'] ?? []) as $session) { $id = (int) ($session['location_id'] ?? 0); if ($id > 0 && !isset($owned[$id])) { $foreign[$id] = true; } } } return array_keys($foreign); } }