Feat: Add ICS generator for disposition dates

This commit is contained in:
Björn Fromme
2023-10-20 14:26:52 +02:00
parent 004b189be9
commit 096ef06a1e
9 changed files with 224 additions and 4 deletions
+1
View File
@@ -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.*",
Generated
+136 -1
View File
@@ -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": "[email protected]",
"homepage": "https://spatie.be",
"role": "Developer"
},
{
"name": "Tom Witkowski",
"email": "[email protected]",
"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": "[email protected]",
"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",
@@ -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
{
@@ -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
{
@@ -0,0 +1,38 @@
<?php
namespace App\Controller\Teamer\Disposition;
use App\Entity\Disposition;
use App\Service\Common\IcsGenerator;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\HeaderUtils;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
class IcsController extends AbstractController
{
#[Route('/teamer/disposition/ics/{uuid}', name: 'app_teamer_disposition_ics')]
#[IsGranted('ROLE_TEAMER')]
#[IsGranted('VIEW', subject: 'disposition')]
public function index(Disposition $disposition): Response
{
$assignment = $disposition->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;
}
}
@@ -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
{
+38
View File
@@ -0,0 +1,38 @@
<?php
namespace App\Service\Common;
use App\Entity\Disposition;
use Spatie\IcalendarGenerator\Components\Calendar;
use Spatie\IcalendarGenerator\Components\Event;
class IcsGenerator
{
public function __construct(private readonly Disposition $disposition)
{}
public function generate(): string
{
$assignment = $this->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();
}
}
@@ -39,10 +39,10 @@
<div>
{{ assignment.benefits|nl2list }}
</div>
<div>
Honorar
</div>
{% if assignment.fees|length %}
<div>
Honorar
</div>
<div>
{% for fee in assignment.fees %}
{{ fee.name }} {{ fee.value|format_money }}
@@ -27,6 +27,11 @@
<br>
{{ assignment.contact }}, <a href="mailto:{{ assignment.contact.email }}" class="underline">{{ assignment.contact.email }}</a>
</p>
<p class="pb-4">
<a href="{{ path('app_teamer_disposition_ics', { 'uuid': disposition.uuid }) }}" class="underline">
Hier kannst du den Einsatz in deinen Kalender eintragen (ICS).
</a>
</p>
{# Upload contract #}
{% if workflow_has_marked_place(disposition, 'new') %}