Feat: Implement workflow for disposition document uploads
This commit is contained in:
Generated
+21
-21
@@ -101,16 +101,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "doctrine/collections",
|
"name": "doctrine/collections",
|
||||||
"version": "2.1.3",
|
"version": "2.1.4",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/doctrine/collections.git",
|
"url": "https://github.com/doctrine/collections.git",
|
||||||
"reference": "3023e150f90a38843856147b58190aa8b46cc155"
|
"reference": "72328a11443a0de79967104ad36ba7b30bded134"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/doctrine/collections/zipball/3023e150f90a38843856147b58190aa8b46cc155",
|
"url": "https://api.github.com/repos/doctrine/collections/zipball/72328a11443a0de79967104ad36ba7b30bded134",
|
||||||
"reference": "3023e150f90a38843856147b58190aa8b46cc155",
|
"reference": "72328a11443a0de79967104ad36ba7b30bded134",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
"php": "^8.1"
|
"php": "^8.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"doctrine/coding-standard": "^10.0",
|
"doctrine/coding-standard": "^12",
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"phpstan/phpstan": "^1.8",
|
"phpstan/phpstan": "^1.8",
|
||||||
"phpstan/phpstan-phpunit": "^1.0",
|
"phpstan/phpstan-phpunit": "^1.0",
|
||||||
@@ -167,7 +167,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/doctrine/collections/issues",
|
"issues": "https://github.com/doctrine/collections/issues",
|
||||||
"source": "https://github.com/doctrine/collections/tree/2.1.3"
|
"source": "https://github.com/doctrine/collections/tree/2.1.4"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -183,7 +183,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-07-06T15:15:36+00:00"
|
"time": "2023-10-03T09:22:33+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "doctrine/common",
|
"name": "doctrine/common",
|
||||||
@@ -278,16 +278,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "doctrine/dbal",
|
"name": "doctrine/dbal",
|
||||||
"version": "3.7.0",
|
"version": "3.7.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/doctrine/dbal.git",
|
"url": "https://github.com/doctrine/dbal.git",
|
||||||
"reference": "00d03067f07482f025d41ab55e4ba0db5eca2cdf"
|
"reference": "5b7bd66c9ff58c04c5474ab85edce442f8081cb2"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/00d03067f07482f025d41ab55e4ba0db5eca2cdf",
|
"url": "https://api.github.com/repos/doctrine/dbal/zipball/5b7bd66c9ff58c04c5474ab85edce442f8081cb2",
|
||||||
"reference": "00d03067f07482f025d41ab55e4ba0db5eca2cdf",
|
"reference": "5b7bd66c9ff58c04c5474ab85edce442f8081cb2",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -371,7 +371,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/doctrine/dbal/issues",
|
"issues": "https://github.com/doctrine/dbal/issues",
|
||||||
"source": "https://github.com/doctrine/dbal/tree/3.7.0"
|
"source": "https://github.com/doctrine/dbal/tree/3.7.1"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -387,7 +387,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-09-26T20:56:55+00:00"
|
"time": "2023-10-06T05:06:20+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "doctrine/deprecations",
|
"name": "doctrine/deprecations",
|
||||||
@@ -1322,16 +1322,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "egulias/email-validator",
|
"name": "egulias/email-validator",
|
||||||
"version": "4.0.1",
|
"version": "4.0.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/egulias/EmailValidator.git",
|
"url": "https://github.com/egulias/EmailValidator.git",
|
||||||
"reference": "3a85486b709bc384dae8eb78fb2eec649bdb64ff"
|
"reference": "ebaaf5be6c0286928352e054f2d5125608e5405e"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/3a85486b709bc384dae8eb78fb2eec649bdb64ff",
|
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ebaaf5be6c0286928352e054f2d5125608e5405e",
|
||||||
"reference": "3a85486b709bc384dae8eb78fb2eec649bdb64ff",
|
"reference": "ebaaf5be6c0286928352e054f2d5125608e5405e",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -1340,8 +1340,8 @@
|
|||||||
"symfony/polyfill-intl-idn": "^1.26"
|
"symfony/polyfill-intl-idn": "^1.26"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^9.5.27",
|
"phpunit/phpunit": "^10.2",
|
||||||
"vimeo/psalm": "^4.30"
|
"vimeo/psalm": "^5.12"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation"
|
"ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation"
|
||||||
@@ -1377,7 +1377,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/egulias/EmailValidator/issues",
|
"issues": "https://github.com/egulias/EmailValidator/issues",
|
||||||
"source": "https://github.com/egulias/EmailValidator/tree/4.0.1"
|
"source": "https://github.com/egulias/EmailValidator/tree/4.0.2"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -1385,7 +1385,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-01-14T14:17:03+00:00"
|
"time": "2023-10-06T06:47:41+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "imagine/imagine",
|
"name": "imagine/imagine",
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
framework:
|
framework:
|
||||||
workflows:
|
workflows:
|
||||||
disposition:
|
disposition:
|
||||||
type: state_machine
|
type: 'state_machine'
|
||||||
marking_store:
|
marking_store:
|
||||||
type: method
|
type: 'method'
|
||||||
property: status
|
property: 'status'
|
||||||
supports:
|
supports:
|
||||||
- App\Entity\Disposition
|
- App\Entity\Disposition
|
||||||
initial_marking: new
|
initial_marking: new
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use App\Service\Upload\UploadHandler;
|
|||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\DependencyInjection\Attribute\Target;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
@@ -24,7 +25,8 @@ class DetailController extends AbstractController
|
|||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly UploadHandler $uploadHandler,
|
private readonly UploadHandler $uploadHandler,
|
||||||
private readonly EntityManagerInterface $entityManager,
|
private readonly EntityManagerInterface $entityManager,
|
||||||
private readonly WorkflowInterface $dispositionStateMachine,
|
#[Target('disposition')]
|
||||||
|
private readonly WorkflowInterface $workflow,
|
||||||
private readonly LoggerInterface $logger
|
private readonly LoggerInterface $logger
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
@@ -41,10 +43,10 @@ class DetailController extends AbstractController
|
|||||||
$uploadSession = $this->uploadHandler->getUploadSession();
|
$uploadSession = $this->uploadHandler->getUploadSession();
|
||||||
|
|
||||||
if (0 < $uploadSession->getCount()) {
|
if (0 < $uploadSession->getCount()) {
|
||||||
if (true === $this->dispositionStateMachine->can($disposition, 'upload_contract')) {
|
if (true === $this->workflow->can($disposition, 'upload_contract')) {
|
||||||
$this->uploadContract($disposition, $uploadSession);
|
$this->uploadContract($disposition, $uploadSession);
|
||||||
}
|
}
|
||||||
if (true === $this->dispositionStateMachine->can($disposition, 'upload_invoice')) {
|
if (true === $this->workflow->can($disposition, 'upload_invoice')) {
|
||||||
$this->uploadInvoice($disposition, $uploadSession);
|
$this->uploadInvoice($disposition, $uploadSession);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,7 +76,7 @@ class DetailController extends AbstractController
|
|||||||
$upload->setStatus(Upload::STATUS_NEW);
|
$upload->setStatus(Upload::STATUS_NEW);
|
||||||
|
|
||||||
$disposition->addDocument($upload);
|
$disposition->addDocument($upload);
|
||||||
$this->dispositionStateMachine->apply($disposition, 'upload_contract');
|
$this->workflow->apply($disposition, 'upload_contract');
|
||||||
|
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
|
|
||||||
@@ -101,7 +103,7 @@ class DetailController extends AbstractController
|
|||||||
$upload->setStatus(Upload::STATUS_NEW);
|
$upload->setStatus(Upload::STATUS_NEW);
|
||||||
|
|
||||||
$disposition->addDocument($upload);
|
$disposition->addDocument($upload);
|
||||||
$this->dispositionStateMachine->apply($disposition, 'upload_invoice');
|
$this->workflow->apply($disposition, 'upload_invoice');
|
||||||
|
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\EventListener;
|
||||||
|
|
||||||
|
use App\Entity\Disposition;
|
||||||
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
use Symfony\Component\Workflow\Event\GuardEvent;
|
||||||
|
|
||||||
|
class DispositionWorkflowGuardSubscriber implements EventSubscriberInterface
|
||||||
|
{
|
||||||
|
public function __construct(private readonly TranslatorInterface $translator)
|
||||||
|
{}
|
||||||
|
|
||||||
|
public static function getSubscribedEvents(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'workflow.disposition.guard.upload_contract' => ['guardUploadContract'],
|
||||||
|
'workflow.disposition.guard.upload_invoice' => ['guardUploadInvoice'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function guardUploadContract(GuardEvent $event): void
|
||||||
|
{
|
||||||
|
/** @var Disposition $disposition */
|
||||||
|
$disposition = $event->getSubject();
|
||||||
|
$assignment = $disposition->getAssignment();
|
||||||
|
$assignmentPeriod = $assignment->getTotalPeriod();
|
||||||
|
$today = new \DateTimeImmutable();
|
||||||
|
|
||||||
|
$dueDateFrom = $disposition->getCreatedAt()->modify('+ 7days');
|
||||||
|
$dueDateTo = $assignmentPeriod->end->modify('-1 day');
|
||||||
|
|
||||||
|
if ($dueDateTo < $today) {
|
||||||
|
$message = $this
|
||||||
|
->translator
|
||||||
|
->trans('message.upload_contract.too_late', [
|
||||||
|
'%date_from%' => $dueDateFrom->format('d.m.Y'),
|
||||||
|
'%date_to%' => $dueDateTo->format('d.m.Y'),
|
||||||
|
])
|
||||||
|
;
|
||||||
|
$event->setBlocked(true, $message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function guardUploadInvoice(GuardEvent $event): void
|
||||||
|
{
|
||||||
|
/** @var Disposition $disposition */
|
||||||
|
$disposition = $event->getSubject();
|
||||||
|
$assignment = $disposition->getAssignment();
|
||||||
|
$destination = $assignment->getDestination();
|
||||||
|
$today = new \DateTimeImmutable();
|
||||||
|
|
||||||
|
$earliestDate = $destination->getDateFrom();
|
||||||
|
|
||||||
|
if ($earliestDate > $today) {
|
||||||
|
$message = $this
|
||||||
|
->translator
|
||||||
|
->trans('message.upload_invoice.too_early', [
|
||||||
|
'%date%' => $earliestDate->format('d.m.Y'),
|
||||||
|
])
|
||||||
|
;
|
||||||
|
$event->setBlocked(true, $message);
|
||||||
|
}
|
||||||
|
|
||||||
|
$dueDate = $destination->getDateTo()->modify('+14 days');
|
||||||
|
|
||||||
|
if ($dueDate < $today) {
|
||||||
|
$message = $this
|
||||||
|
->translator
|
||||||
|
->trans('message.upload_invoice.too_late', [
|
||||||
|
'%date%' => $dueDate->format('d.m.Y'),
|
||||||
|
])
|
||||||
|
;
|
||||||
|
$event->setBlocked(true, $message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||||
|
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<!-- Generated by graphviz version 9.0.0 (20230911.1827)
|
||||||
|
-->
|
||||||
|
<!-- Title: workflow Pages: 1 -->
|
||||||
|
<svg width="813pt" height="188pt"
|
||||||
|
viewBox="0.00 0.00 812.67 188.14" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 184.14)">
|
||||||
|
<title>workflow</title>
|
||||||
|
<polygon fill="white" stroke="none" points="-4,4 -4,-184.14 808.67,-184.14 808.67,4 -4,4"/>
|
||||||
|
<!-- place_c2a6b03f190dfb2b4aa91f8af8d477a9bc3401dc -->
|
||||||
|
<g id="node1" class="node">
|
||||||
|
<title>place_c2a6b03f190dfb2b4aa91f8af8d477a9bc3401dc</title>
|
||||||
|
<ellipse fill="lightblue" stroke="#333333" cx="36" cy="-53" rx="36" ry="36"/>
|
||||||
|
<text text-anchor="middle" x="36" y="-49.7" font-family="Arial" font-size="9.00">new</text>
|
||||||
|
</g>
|
||||||
|
<!-- place_1c0139083383c818fd7ddf51e98b729b6b19803d -->
|
||||||
|
<g id="node2" class="node">
|
||||||
|
<title>place_1c0139083383c818fd7ddf51e98b729b6b19803d</title>
|
||||||
|
<ellipse fill="none" stroke="#333333" cx="220.69" cy="-53" rx="46.69" ry="46.69"/>
|
||||||
|
<text text-anchor="middle" x="220.69" y="-49.7" font-family="Arial" font-size="9.00">checking_contract</text>
|
||||||
|
</g>
|
||||||
|
<!-- place_c2a6b03f190dfb2b4aa91f8af8d477a9bc3401dc->place_1c0139083383c818fd7ddf51e98b729b6b19803d -->
|
||||||
|
<g id="edge1" class="edge">
|
||||||
|
<title>place_c2a6b03f190dfb2b4aa91f8af8d477a9bc3401dc->place_1c0139083383c818fd7ddf51e98b729b6b19803d</title>
|
||||||
|
<path fill="none" stroke="#333333" d="M72.22,-53C99.14,-53 136.66,-53 167.12,-53"/>
|
||||||
|
<polygon fill="#333333" stroke="#333333" points="166.99,-54.75 171.99,-53 166.99,-51.25 166.99,-54.75"/>
|
||||||
|
<text text-anchor="middle" x="123" y="-54.95" font-family="Arial" font-size="9.00">upload_contract</text>
|
||||||
|
</g>
|
||||||
|
<!-- place_d35ce8acb0d0ca09297349a4e2d4240c2819c523 -->
|
||||||
|
<g id="node3" class="node">
|
||||||
|
<title>place_d35ce8acb0d0ca09297349a4e2d4240c2819c523</title>
|
||||||
|
<ellipse fill="none" stroke="#333333" cx="406.89" cy="-53" rx="36" ry="36"/>
|
||||||
|
<text text-anchor="middle" x="406.89" y="-49.7" font-family="Arial" font-size="9.00">confirmed</text>
|
||||||
|
</g>
|
||||||
|
<!-- place_1c0139083383c818fd7ddf51e98b729b6b19803d->place_d35ce8acb0d0ca09297349a4e2d4240c2819c523 -->
|
||||||
|
<g id="edge2" class="edge">
|
||||||
|
<title>place_1c0139083383c818fd7ddf51e98b729b6b19803d->place_d35ce8acb0d0ca09297349a4e2d4240c2819c523</title>
|
||||||
|
<path fill="none" stroke="#333333" d="M267.7,-53C297.32,-53 335.51,-53 364.23,-53"/>
|
||||||
|
<polygon fill="#333333" stroke="#333333" points="364.06,-54.75 369.06,-53 364.06,-51.25 364.06,-54.75"/>
|
||||||
|
<text text-anchor="middle" x="319.14" y="-54.95" font-family="Arial" font-size="9.00">confirm_contract</text>
|
||||||
|
</g>
|
||||||
|
<!-- place_7b74ca224881f644aaf11239b7a05c62a7834047 -->
|
||||||
|
<g id="node4" class="node">
|
||||||
|
<title>place_7b74ca224881f644aaf11239b7a05c62a7834047</title>
|
||||||
|
<ellipse fill="none" stroke="#333333" cx="587.03" cy="-135" rx="45.14" ry="45.14"/>
|
||||||
|
<text text-anchor="middle" x="587.03" y="-131.7" font-family="Arial" font-size="9.00">checking_invoice</text>
|
||||||
|
</g>
|
||||||
|
<!-- place_d35ce8acb0d0ca09297349a4e2d4240c2819c523->place_7b74ca224881f644aaf11239b7a05c62a7834047 -->
|
||||||
|
<g id="edge3" class="edge">
|
||||||
|
<title>place_d35ce8acb0d0ca09297349a4e2d4240c2819c523->place_7b74ca224881f644aaf11239b7a05c62a7834047</title>
|
||||||
|
<path fill="none" stroke="#333333" d="M440.15,-67.85C467.99,-80.67 508.55,-99.34 539.83,-113.74"/>
|
||||||
|
<polygon fill="#333333" stroke="#333333" points="538.92,-115.24 544.19,-115.74 540.38,-112.06 538.92,-115.24"/>
|
||||||
|
<text text-anchor="middle" x="492.39" y="-108.95" font-family="Arial" font-size="9.00">upload_invoice</text>
|
||||||
|
</g>
|
||||||
|
<!-- place_231e564db4cdb44a6545583a8d460edc7f9f97ca -->
|
||||||
|
<g id="node6" class="node">
|
||||||
|
<title>place_231e564db4cdb44a6545583a8d460edc7f9f97ca</title>
|
||||||
|
<ellipse fill="none" stroke="#333333" cx="587.03" cy="-36" rx="36" ry="36"/>
|
||||||
|
<text text-anchor="middle" x="587.03" y="-32.7" font-family="Arial" font-size="9.00">completed</text>
|
||||||
|
</g>
|
||||||
|
<!-- place_d35ce8acb0d0ca09297349a4e2d4240c2819c523->place_231e564db4cdb44a6545583a8d460edc7f9f97ca -->
|
||||||
|
<g id="edge4" class="edge">
|
||||||
|
<title>place_d35ce8acb0d0ca09297349a4e2d4240c2819c523->place_231e564db4cdb44a6545583a8d460edc7f9f97ca</title>
|
||||||
|
<path fill="none" stroke="#333333" d="M443.08,-49.64C472.24,-46.86 513.73,-42.9 544.51,-39.96"/>
|
||||||
|
<polygon fill="#333333" stroke="#333333" points="544.59,-41.71 549.4,-39.5 544.25,-38.23 544.59,-41.71"/>
|
||||||
|
<text text-anchor="middle" x="492.39" y="-49.95" font-family="Arial" font-size="9.00">complete</text>
|
||||||
|
</g>
|
||||||
|
<!-- place_9e1f1120d2eedc498808e1d855cfdbbd5564f22b -->
|
||||||
|
<g id="node5" class="node">
|
||||||
|
<title>place_9e1f1120d2eedc498808e1d855cfdbbd5564f22b</title>
|
||||||
|
<ellipse fill="none" stroke="#333333" cx="768.67" cy="-135" rx="36" ry="36"/>
|
||||||
|
<text text-anchor="middle" x="768.67" y="-131.7" font-family="Arial" font-size="9.00">paid</text>
|
||||||
|
</g>
|
||||||
|
<!-- place_7b74ca224881f644aaf11239b7a05c62a7834047->place_9e1f1120d2eedc498808e1d855cfdbbd5564f22b -->
|
||||||
|
<g id="edge5" class="edge">
|
||||||
|
<title>place_7b74ca224881f644aaf11239b7a05c62a7834047->place_9e1f1120d2eedc498808e1d855cfdbbd5564f22b</title>
|
||||||
|
<path fill="none" stroke="#333333" d="M632.43,-135C661.02,-135 697.95,-135 725.99,-135"/>
|
||||||
|
<polygon fill="#333333" stroke="#333333" points="725.68,-136.75 730.68,-135 725.68,-133.25 725.68,-136.75"/>
|
||||||
|
<text text-anchor="middle" x="682.42" y="-136.95" font-family="Arial" font-size="9.00">confirm_invoice</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 5.3 KiB |
@@ -2,6 +2,13 @@
|
|||||||
|
|
||||||
{% block title %}Einsatzdetails{% endblock %}
|
{% block title %}Einsatzdetails{% endblock %}
|
||||||
|
|
||||||
|
{% macro infobox(message) %}
|
||||||
|
<div class="flex items-start space-x-4 bg-primary text-white p-4 rounded-md">
|
||||||
|
{{ icon('info', 'w-6 h-6 shrink-0') }}
|
||||||
|
<span>{{ message }}</span>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1 class="text-2xl font-bold pb-8">
|
<h1 class="text-2xl font-bold pb-8">
|
||||||
Einsatzdetails
|
Einsatzdetails
|
||||||
@@ -20,71 +27,107 @@
|
|||||||
<br>
|
<br>
|
||||||
{{ assignment.contact }}, <a href="mailto:{{ assignment.contact.email }}" class="underline">{{ assignment.contact.email }}</a>
|
{{ assignment.contact }}, <a href="mailto:{{ assignment.contact.email }}" class="underline">{{ assignment.contact.email }}</a>
|
||||||
</p>
|
</p>
|
||||||
{% if workflow_can(disposition, 'upload_contract') %}
|
|
||||||
<h3 class="text-xl font-bold pb-4">
|
{# Upload contract #}
|
||||||
Hier findest du deinen Honorarvertrag
|
{% if workflow_has_marked_place(disposition, 'new') %}
|
||||||
</h3>
|
{% if workflow_can(disposition, 'upload_contract') %}
|
||||||
<div class="pb-4">
|
<h3 class="text-xl font-bold pb-4">
|
||||||
<a href="{{ path('app_teamer_disposition_contractpdf', { 'uuid': disposition.uuid }) }}" target="_blank" class="inline-block">
|
Hier findest du deinen Honorarvertrag
|
||||||
<img src="{{ asset('build/images/contract_thumb.jpg') }}" alt="Honorarvertrag" class="block w-32 h-auto shadow-md">
|
</h3>
|
||||||
</a>
|
<div class="pb-4">
|
||||||
</div>
|
<a href="{{ path('app_teamer_disposition_contractpdf', { 'uuid': disposition.uuid }) }}" target="_blank" class="inline-block">
|
||||||
<p class="pb-4">
|
<img src="{{ asset('build/images/contract_thumb.jpg') }}" alt="Honorarvertrag" class="block w-32 h-auto shadow-md">
|
||||||
Bitte lade ihn unterschrieben hier wieder hoch:
|
</a>
|
||||||
</p>
|
</div>
|
||||||
{{ form_start(form) }}
|
<p class="pb-4">
|
||||||
<div class="pb-4">
|
Bitte lade ihn unterschrieben hier wieder hoch:
|
||||||
{% include '_partials/_upload_collection_form.html.twig' with {
|
</p>
|
||||||
'endpoint_upload': path('_uploader_upload_contract'),
|
{{ form_start(form) }}
|
||||||
'accepted_files': 'image/jpg,image/jpeg,application/pdf',
|
<div class="pb-4">
|
||||||
} %}
|
{% include '_partials/_upload_collection_form.html.twig' with {
|
||||||
</div>
|
'endpoint_upload': path('_uploader_upload_contract'),
|
||||||
<button type="submit" class="btn">
|
'accepted_files': 'image/jpg,image/jpeg,application/pdf',
|
||||||
Aktualisieren
|
} %}
|
||||||
</button>
|
</div>
|
||||||
{{ form_rest(form) }}
|
<button type="submit" class="btn">
|
||||||
{{ form_end(form) }}
|
Aktualisieren
|
||||||
{% elseif workflow_can(disposition, 'upload_invoice') %}
|
</button>
|
||||||
<h3 class="text-xl font-bold pb-4">
|
{{ form_rest(form) }}
|
||||||
Hier findest du deine Honorarnote
|
{{ form_end(form) }}
|
||||||
</h3>
|
{% else %}
|
||||||
<div class="pb-4">
|
{% for blocker in workflow_transition_blockers(disposition, 'upload_contract') %}
|
||||||
<a href="{{ path('app_teamer_disposition_contractpdf', { 'uuid': disposition.uuid }) }}" target="_blank" class="inline-block">
|
{{ _self.infobox(blocker.message) }}
|
||||||
<img src="{{ asset('build/images/contract_thumb.jpg') }}" alt="Honorarvertrag" class="block w-32 h-auto shadow-md">
|
{% endfor %}
|
||||||
</a>
|
{% endif %}
|
||||||
</div>
|
{% endif %}
|
||||||
<p class="pb-4">
|
|
||||||
Bitte lade sie ausgefüllt und unterschrieben hier wieder hoch:
|
{# Upload invoice #}
|
||||||
</p>
|
{% if workflow_has_marked_place(disposition, 'confirmed') %}
|
||||||
{{ form_start(form) }}
|
{% if workflow_can(disposition, 'upload_invoice') %}
|
||||||
<div class="pb-4">
|
<h3 class="text-xl font-bold pb-4">
|
||||||
{% include '_partials/_upload_collection_form.html.twig' with {
|
Hier findest du deine Honorarnote
|
||||||
'endpoint_upload': path('_uploader_upload_invoice'),
|
</h3>
|
||||||
'accepted_files': 'image/jpg,image/jpeg,application/pdf',
|
<div class="pb-4">
|
||||||
} %}
|
<a href="{{ path('app_teamer_disposition_contractpdf', { 'uuid': disposition.uuid }) }}" target="_blank" class="inline-block">
|
||||||
</div>
|
<img src="{{ asset('build/images/contract_thumb.jpg') }}" alt="Honorarvertrag" class="block w-32 h-auto shadow-md">
|
||||||
<button type="submit" class="btn">
|
</a>
|
||||||
Aktualisieren
|
</div>
|
||||||
</button>
|
<p class="pb-4">
|
||||||
{{ form_rest(form) }}
|
Bitte lade sie ausgefüllt und unterschrieben hier wieder hoch:
|
||||||
{{ form_end(form) }}
|
</p>
|
||||||
{% elseif workflow_has_marked_place(disposition, 'checking_contract') %}
|
{{ form_start(form) }}
|
||||||
|
<div class="pb-4">
|
||||||
|
{% include '_partials/_upload_collection_form.html.twig' with {
|
||||||
|
'endpoint_upload': path('_uploader_upload_invoice'),
|
||||||
|
'accepted_files': 'image/jpg,image/jpeg,application/pdf',
|
||||||
|
} %}
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn">
|
||||||
|
Aktualisieren
|
||||||
|
</button>
|
||||||
|
{{ form_rest(form) }}
|
||||||
|
{{ form_end(form) }}
|
||||||
|
{% else %}
|
||||||
|
{% for blocker in workflow_transition_blockers(disposition, 'upload_invoice') %}
|
||||||
|
{{ _self.infobox(blocker.message) }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{# Contract uploaded #}
|
||||||
|
{% if workflow_has_marked_place(disposition, 'checking_contract') %}
|
||||||
<h3 class="text-xl font-bold pb-4">
|
<h3 class="text-xl font-bold pb-4">
|
||||||
Danke für den Upload des Honorarvertrags
|
Danke für den Upload des Honorarvertrags
|
||||||
</h3>
|
</h3>
|
||||||
{% elseif workflow_has_marked_place(disposition, 'checking_invoice') %}
|
<div class="pb-4">
|
||||||
|
Wir prüfen das Dokument schnellstmöglich.
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{# Invoice uploaded #}
|
||||||
|
{% if workflow_has_marked_place(disposition, 'checking_invoice') %}
|
||||||
<h3 class="text-xl font-bold pb-4">
|
<h3 class="text-xl font-bold pb-4">
|
||||||
Danke für den Upload der Honorarnote
|
Danke für den Upload der Honorarnote
|
||||||
</h3>
|
</h3>
|
||||||
{% elseif workflow_has_marked_place(disposition, 'paid') %}
|
<div class="pb-4">
|
||||||
|
Wir prüfen das Dokument schnellstmöglich.
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{# Invoice paid #}
|
||||||
|
{% if workflow_has_marked_place(disposition, 'paid') %}
|
||||||
<h3 class="text-xl font-bold pb-4">
|
<h3 class="text-xl font-bold pb-4">
|
||||||
Dein Honorar wurde überwiesen
|
Dein Honorar wurde überwiesen
|
||||||
</h3>
|
</h3>
|
||||||
{% else %}
|
{% endif %}
|
||||||
|
|
||||||
|
{# No invoice required #}
|
||||||
|
{% if workflow_has_marked_place(disposition, 'completed') %}
|
||||||
<h3 class="text-xl font-bold pb-4">
|
<h3 class="text-xl font-bold pb-4">
|
||||||
Dein Einsatz ist abgeschlossen
|
Dein Einsatz ist abgeschlossen
|
||||||
</h3>
|
</h3>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div class="pt-4">
|
<div class="pt-4">
|
||||||
<a href="{{ returnUrl }}" class="underline">
|
<a href="{{ returnUrl }}" class="underline">
|
||||||
zurück
|
zurück
|
||||||
|
|||||||
@@ -22,12 +22,20 @@ label:
|
|||||||
payed: bezahlt
|
payed: bezahlt
|
||||||
error: Fehler
|
error: Fehler
|
||||||
|
|
||||||
|
message:
|
||||||
|
upload_contract:
|
||||||
|
too_late: 'Die Frist für den Upload des Honorarvertrages ist abgelaufen (%date_from% - %date_to%). Bitte wende dich an deinen Ansprechpartner'
|
||||||
|
upload_invoice:
|
||||||
|
too_early: 'Du kannst deine Honorarnote mit Beginn deines Einsatzes ab dem %date% einreichen.'
|
||||||
|
too_late: 'Du hättest deine Honorarnote bis zum %date% einreichen müssen. Bitte wende dich an deinen Ansprechpartner.'
|
||||||
|
|
||||||
uploader:
|
uploader:
|
||||||
drop_files: Dateien hier ablegen oder
|
drop_files: Dateien hier ablegen oder
|
||||||
click_here: hier klicken
|
click_here: hier klicken
|
||||||
file_too_big: Die maximale Dateigröße beträgt %maxFilesize%MB
|
file_too_big: Die maximale Dateigröße beträgt %maxFilesize%MB
|
||||||
invalid_file_type: Der Dateityp ist nicht erlaubt
|
invalid_file_type: Der Dateityp ist nicht erlaubt
|
||||||
max_files_exceeded: Die maximale Anzahl von Dateien is %maxFilesExceeded%
|
max_files_exceeded: Die maximale Anzahl von Dateien is %maxFilesExceeded%
|
||||||
|
|
||||||
paginator:
|
paginator:
|
||||||
previous: vorherige
|
previous: vorherige
|
||||||
next: nächste
|
next: nächste
|
||||||
|
|||||||
Reference in New Issue
Block a user