diff --git a/config/packages/workflow.yaml b/config/packages/workflow.yaml index bacf49d..f89b573 100644 --- a/config/packages/workflow.yaml +++ b/config/packages/workflow.yaml @@ -22,12 +22,18 @@ framework: confirm_contract: from: checking_contract to: confirmed + reject_contract: + from: checking_contract + to: new upload_invoice: from: confirmed to: checking_invoice confirm_invoice: from: checking_invoice to: paid + reject_invoice: + from: checking_invoice + to: confirmed complete: from: confirmed to: completed diff --git a/src/Controller/Admin/Document/CheckController.php b/src/Controller/Admin/Document/CheckController.php new file mode 100644 index 0000000..264eb3b --- /dev/null +++ b/src/Controller/Admin/Document/CheckController.php @@ -0,0 +1,107 @@ +generateUrl('app_admin_document_check', ['uuid' => $document->getUuid()]); + $form = $this->createForm( + DocumentCheckType::class, + $formData, + [ + 'action' => $formAction, + 'ajax_submit' => true, + 'document_type' => $document->getType(), + ] + ); + + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + switch ($formData->getStatus()) { + case Upload::STATUS_CHECKED: + $this->confirmDocument($document, 'confirm_contract', Upload::STATUS_CHECKED); + break; + case Upload::STATUS_PAID: + $this->confirmDocument($document, 'confirm_invoice', Upload::STATUS_PAID); + break; + case Upload::STATUS_REJECTED: + $this->rejectDocument($document); + $this->eventDispatcher->dispatch(new DocumentRejectedEvent($formData), DocumentRejectedEvent::NAME); + } + + $returnUrl = $this->generateUrl('app_admin_document_index'); + $response->setCloseAndRedirect($returnUrl); + } else { + $response->setContent($this->renderView('admin/document/check.html.twig', [ + 'document' => $document, + 'form' => $form, + ])); + } + + return $this->json($response); + } + + private function rejectDocument(Upload $document): void + { + $transition = Upload::TYPE_CONTRACT === $document->getType() ? 'reject_contract' : 'reject_invoice'; + $this->workflow->apply($document->getDisposition(), $transition); + $document->setStatus(Upload::STATUS_REJECTED); + $this->entityManager->flush(); + + $this->addFlash('success', 'Das Dokument wurde abgelehnt'); + $this->logger->info('Reject document', [ + 'document' => $document->getOriginalFilename(), + ]); + + } + + private function confirmDocument(Upload $document, string $transition, string $status): void + { + if (true === $this->workflow->can($document->getDisposition(), $transition)) { + $document->setStatus($status); + $this->workflow->apply($document->getDisposition(), $transition); + $this->entityManager->flush(); + $this->addFlash('success', 'Das Dokument wurde bestätigt'); + $this->logger->info('Confirm document', [ + 'document' => $document->getOriginalFilename(), + ]); + } else { + $blockers = $this->workflow->buildTransitionBlockerList($document->getDisposition(), $transition); + foreach ($blockers as $blocker) { + $this->addFlash('error', $blocker->getMessage()); + } + } + } +} diff --git a/src/Controller/Admin/Document/DeleteController.php b/src/Controller/Admin/Document/DeleteController.php deleted file mode 100644 index d12b05a..0000000 --- a/src/Controller/Admin/Document/DeleteController.php +++ /dev/null @@ -1,31 +0,0 @@ -entityManager->remove($document); - $this->entityManager->flush(); - - return $this->render(''); - } -} diff --git a/src/Entity/Upload.php b/src/Entity/Upload.php index c5814b7..f531601 100644 --- a/src/Entity/Upload.php +++ b/src/Entity/Upload.php @@ -22,10 +22,9 @@ class Upload implements BlameableEntityInterface, TimestampableEntityInterface public const TYPE_DOCUMENT = 'document'; public const STATUS_NEW = 'new'; - public const CHECKING = 'checking'; public const STATUS_CHECKED = 'checked'; public const STATUS_PAID = 'paid'; - public const STATUS_ERROR = 'error'; + public const STATUS_REJECTED = 'rejected'; #[ORM\Id] #[ORM\GeneratedValue] diff --git a/src/Event/DocumentRejectedEvent.php b/src/Event/DocumentRejectedEvent.php new file mode 100644 index 0000000..b079bde --- /dev/null +++ b/src/Event/DocumentRejectedEvent.php @@ -0,0 +1,31 @@ +document = $documentCheckDto->getUpload(); + $this->comment = $documentCheckDto->getComment(); + } + + public function getDocument(): Upload + { + return $this->document; + } + + public function getComment(): ?string + { + return $this->comment; + } +} \ No newline at end of file diff --git a/src/Form/DocumentCheckType.php b/src/Form/DocumentCheckType.php new file mode 100644 index 0000000..4ab305e --- /dev/null +++ b/src/Form/DocumentCheckType.php @@ -0,0 +1,53 @@ +add('status', ChoiceType::class, [ + 'label' => 'neuer Status', + 'choices' => $options['status_choices'][$options['document_type']], + ]) + ->add('comment', TextareaType::class, [ + 'label' => 'Kommentar/Begründung', + 'required' => false, + 'attr' => [ + 'rows' => 3, + ], + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver + ->setDefaults([ + 'data_class' => DocumentCheckDto::class, + 'status_choices' => [ + Upload::TYPE_CONTRACT => [ + 'bestätigt' => Upload::STATUS_CHECKED, + 'abgelehnt' => Upload::STATUS_REJECTED, + ], + Upload::TYPE_INVOICE => [ + 'bezahlt' => Upload::STATUS_PAID, + 'abgelehnt' => Upload::STATUS_REJECTED, + ], + ], + ]) + ->setRequired(['document_type']) + ->setAllowedTypes('document_type', 'string') + ->setAllowedValues('document_type', [Upload::TYPE_INVOICE, Upload::TYPE_CONTRACT]) + ; + } +} \ No newline at end of file diff --git a/src/Menu/TeamerMenuBuilder.php b/src/Menu/TeamerMenuBuilder.php index 7282cc3..3db2ecd 100644 --- a/src/Menu/TeamerMenuBuilder.php +++ b/src/Menu/TeamerMenuBuilder.php @@ -49,6 +49,13 @@ class TeamerMenuBuilder extends AbstractMenuBuilder [ 'route' => 'app_teamer_bookmark_index', 'title' => 'Merkliste', + 'children' => [ + [ + 'route' => 'app_teamer_assignment', + 'title' => 'Einsatzdetails', + 'routeParameters' => $this->getDefaultRouteParameters('uuid'), + ] + ], ], [ 'route' => 'app_teamer_application_index', diff --git a/src/Model/DocumentCheckDto.php b/src/Model/DocumentCheckDto.php new file mode 100644 index 0000000..1db3fe7 --- /dev/null +++ b/src/Model/DocumentCheckDto.php @@ -0,0 +1,46 @@ +upload = $upload; + } + + public function getUpload(): Upload + { + return $this->upload; + } + + public function getStatus(): string + { + return $this->status; + } + + public function setStatus(string $status): static + { + $this->status = $status; + + return $this; + } + + public function getComment(): ?string + { + return $this->comment; + } + + public function setComment(?string $comment): static + { + $this->comment = $comment; + + return $this; + } +} \ No newline at end of file diff --git a/src/Twig/AppRuntime.php b/src/Twig/AppRuntime.php index 17aa4fc..c2bc698 100644 --- a/src/Twig/AppRuntime.php +++ b/src/Twig/AppRuntime.php @@ -103,7 +103,7 @@ class AppRuntime implements RuntimeExtensionInterface $class = 'upload-status-badge '; $class .= match($status) { Upload::STATUS_NEW => 'upload-status-badge--new', - Upload::STATUS_ERROR => 'upload-status-badge--error', + Upload::STATUS_REJECTED => 'upload-status-badge--error', Upload::STATUS_PAID => 'upload-status-badge--paid', Upload::STATUS_CHECKED => 'upload-status-badge--checked', default => 'upload-status-badge--default', diff --git a/templates/admin/document/check.html.twig b/templates/admin/document/check.html.twig new file mode 100644 index 0000000..e7bd9e0 --- /dev/null +++ b/templates/admin/document/check.html.twig @@ -0,0 +1,13 @@ +{{ form_start(form) }} +