diff --git a/composer.json b/composer.json index 87b49f8..d73e90b 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,7 @@ "phpstan/phpdoc-parser": "^1.22", "setasign/fpdf": "^1.8", "setasign/fpdi": "^2.5", + "spatie/icalendar-generator": "^2.5", "symfony/apache-pack": "^1.0", "symfony/asset": "6.3.*", "symfony/console": "6.3.*", diff --git a/composer.lock b/composer.lock index 97ecc29..3c3073e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "9018bf9f3712da46a5f6d428cd540cb0", + "content-hash": "a8cff958b7f2a068c8187b04e541adb9", "packages": [ { "name": "beberlei/doctrineextensions", @@ -2846,6 +2846,141 @@ ], "time": "2023-09-28T10:46:27+00:00" }, + { + "name": "spatie/enum", + "version": "3.13.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/enum.git", + "reference": "f1a0f464ba909491a53e60a955ce84ad7cd93a2c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/enum/zipball/f1a0f464ba909491a53e60a955ce84ad7cd93a2c", + "reference": "f1a0f464ba909491a53e60a955ce84ad7cd93a2c", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^8.0" + }, + "require-dev": { + "fakerphp/faker": "^1.9.1", + "larapack/dd": "^1.1", + "phpunit/phpunit": "^9.0", + "vimeo/psalm": "^4.3" + }, + "suggest": { + "fakerphp/faker": "To use the enum faker provider", + "phpunit/phpunit": "To use the enum assertions" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Enum\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brent Roose", + "email": "brent@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + }, + { + "name": "Tom Witkowski", + "email": "dev@gummibeer.de", + "homepage": "https://gummibeer.de", + "role": "Developer" + } + ], + "description": "PHP Enums", + "homepage": "https://github.com/spatie/enum", + "keywords": [ + "enum", + "enumerable", + "spatie" + ], + "support": { + "docs": "https://docs.spatie.be/enum", + "issues": "https://github.com/spatie/enum/issues", + "source": "https://github.com/spatie/enum" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-04-22T08:51:55+00:00" + }, + { + "name": "spatie/icalendar-generator", + "version": "2.5.6", + "source": { + "type": "git", + "url": "https://github.com/spatie/icalendar-generator.git", + "reference": "8af1ebe392d04369f647574d0053a00da4cff311" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/icalendar-generator/zipball/8af1ebe392d04369f647574d0053a00da4cff311", + "reference": "8af1ebe392d04369f647574d0053a00da4cff311", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "nesbot/carbon": "^2.63", + "php": "^7.4|^8.0", + "spatie/enum": "^3.11" + }, + "require-dev": { + "ext-json": "*", + "larapack/dd": "^1.1", + "pestphp/pest": "^1.22", + "spatie/pest-plugin-snapshots": "^1.1", + "vimeo/psalm": "^4.13" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\IcalendarGenerator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ruben Van Assche", + "email": "ruben@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Build calendars in the iCalendar format", + "homepage": "https://github.com/spatie/icalendar-generator", + "keywords": [ + "calendar", + "iCalendar", + "ical", + "ics", + "spatie" + ], + "support": { + "source": "https://github.com/spatie/icalendar-generator/tree/2.5.6" + }, + "time": "2023-03-24T10:38:32+00:00" + }, { "name": "symfony/apache-pack", "version": "v1.0.1", diff --git a/src/Controller/Teamer/Disposition/ContractPdfController.php b/src/Controller/Teamer/Disposition/ContractPdfController.php index db3c84c..9d017be 100644 --- a/src/Controller/Teamer/Disposition/ContractPdfController.php +++ b/src/Controller/Teamer/Disposition/ContractPdfController.php @@ -16,6 +16,7 @@ class ContractPdfController extends AbstractController {} #[Route('/teamer/disposition/contract/{uuid}', name: 'app_teamer_disposition_contractpdf')] + #[IsGranted('ROLE_TEAMER')] #[IsGranted('CONTRACT', subject: 'disposition')] public function index(Disposition $disposition): Response { diff --git a/src/Controller/Teamer/Disposition/DetailController.php b/src/Controller/Teamer/Disposition/DetailController.php index e79dc0f..15794f2 100644 --- a/src/Controller/Teamer/Disposition/DetailController.php +++ b/src/Controller/Teamer/Disposition/DetailController.php @@ -32,6 +32,7 @@ class DetailController extends AbstractController } #[Route('/teamer/disposition/detail/{uuid}', name: 'app_teamer_disposition_detail')] + #[IsGranted('ROLE_TEAMER')] #[IsGranted('VIEW', subject: 'disposition')] public function index(Disposition $disposition, Request $request): Response { diff --git a/src/Controller/Teamer/Disposition/IcsController.php b/src/Controller/Teamer/Disposition/IcsController.php new file mode 100644 index 0000000..96b4a00 --- /dev/null +++ b/src/Controller/Teamer/Disposition/IcsController.php @@ -0,0 +1,38 @@ +getAssignment(); + $jobProfile = $assignment->getJobProfile(); + $ics = (new IcsGenerator($disposition))->generate(); + $filename = sprintf( + 'Einteilung_%s_%s-%s.ics', + $jobProfile->getName(), + $assignment->getEffectivePeriod()->start->format('d.m.Y'), + $assignment->getEffectivePeriod()->end->format('d.m.Y') + ); + $disposition = HeaderUtils::makeDisposition(HeaderUtils::DISPOSITION_INLINE, $filename, md5($filename)); + + $response = new Response($ics); + $response->setPrivate(); + $response->headers->set('Content-type', 'text/calendar'); + $response->headers->set('Content-Disposition', $disposition); + + return $response; + } +} diff --git a/src/Controller/Teamer/Disposition/InvoicePdfController.php b/src/Controller/Teamer/Disposition/InvoicePdfController.php index 10d29c3..7f82275 100644 --- a/src/Controller/Teamer/Disposition/InvoicePdfController.php +++ b/src/Controller/Teamer/Disposition/InvoicePdfController.php @@ -16,6 +16,7 @@ class InvoicePdfController extends AbstractController {} #[Route('/teamer/disposition/invoice/{uuid}', name: 'app_teamer_disposition_invoicepdf')] + #[IsGranted('ROLE_TEAMER')] #[IsGranted('INVOICE', subject: 'disposition')] public function index(Disposition $disposition): Response { diff --git a/src/Service/Common/IcsGenerator.php b/src/Service/Common/IcsGenerator.php new file mode 100644 index 0000000..bbb06d0 --- /dev/null +++ b/src/Service/Common/IcsGenerator.php @@ -0,0 +1,38 @@ +disposition->getAssignment(); + + $calendar = Calendar::create('MyE&P Team'); + + $label = sprintf('E&P: Einteilung als %s', $assignment->getJobProfile()->getName()); + $address = sprintf("%s\n%s", $assignment->getDestination()->getProduct(), $assignment->getDestination()->getHotel()); + + $event = Event::create($label) + ->startsAt($assignment->getEffectivePeriod()->start) + ->endsAt($assignment->getEffectivePeriod()->end->modify('+1 day')) + ->address($address) + ->description($label) + ; + + if (null !== $contact = $assignment->getContact()) { + $event->organizer($contact->getEmail(), $contact); + } + + $calendar->event($event); + + return $calendar->get(); + } +} diff --git a/templates/_partials/_assignment_info.html.twig b/templates/_partials/_assignment_info.html.twig index 13d2695..76078bb 100644 --- a/templates/_partials/_assignment_info.html.twig +++ b/templates/_partials/_assignment_info.html.twig @@ -39,10 +39,10 @@
{{ assignment.benefits|nl2list }}
-
- Honorar -
{% if assignment.fees|length %} +
+ Honorar +
{% for fee in assignment.fees %} {{ fee.name }} {{ fee.value|format_money }} diff --git a/templates/teamer/disposition/detail.html.twig b/templates/teamer/disposition/detail.html.twig index 771a018..b827bbe 100644 --- a/templates/teamer/disposition/detail.html.twig +++ b/templates/teamer/disposition/detail.html.twig @@ -27,6 +27,11 @@
{{ assignment.contact }}, {{ assignment.contact.email }}

+

+ + Hier kannst du den Einsatz in deinen Kalender eintragen (ICS). + +

{# Upload contract #} {% if workflow_has_marked_place(disposition, 'new') %}