Feat: Add ICS generator for disposition dates
This commit is contained in:
@@ -27,6 +27,7 @@
|
|||||||
"phpstan/phpdoc-parser": "^1.22",
|
"phpstan/phpdoc-parser": "^1.22",
|
||||||
"setasign/fpdf": "^1.8",
|
"setasign/fpdf": "^1.8",
|
||||||
"setasign/fpdi": "^2.5",
|
"setasign/fpdi": "^2.5",
|
||||||
|
"spatie/icalendar-generator": "^2.5",
|
||||||
"symfony/apache-pack": "^1.0",
|
"symfony/apache-pack": "^1.0",
|
||||||
"symfony/asset": "6.3.*",
|
"symfony/asset": "6.3.*",
|
||||||
"symfony/console": "6.3.*",
|
"symfony/console": "6.3.*",
|
||||||
|
|||||||
Generated
+136
-1
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "9018bf9f3712da46a5f6d428cd540cb0",
|
"content-hash": "a8cff958b7f2a068c8187b04e541adb9",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "beberlei/doctrineextensions",
|
"name": "beberlei/doctrineextensions",
|
||||||
@@ -2846,6 +2846,141 @@
|
|||||||
],
|
],
|
||||||
"time": "2023-09-28T10:46:27+00:00"
|
"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",
|
"name": "symfony/apache-pack",
|
||||||
"version": "v1.0.1",
|
"version": "v1.0.1",
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class ContractPdfController extends AbstractController
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
#[Route('/teamer/disposition/contract/{uuid}', name: 'app_teamer_disposition_contractpdf')]
|
#[Route('/teamer/disposition/contract/{uuid}', name: 'app_teamer_disposition_contractpdf')]
|
||||||
|
#[IsGranted('ROLE_TEAMER')]
|
||||||
#[IsGranted('CONTRACT', subject: 'disposition')]
|
#[IsGranted('CONTRACT', subject: 'disposition')]
|
||||||
public function index(Disposition $disposition): Response
|
public function index(Disposition $disposition): Response
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ class DetailController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/teamer/disposition/detail/{uuid}', name: 'app_teamer_disposition_detail')]
|
#[Route('/teamer/disposition/detail/{uuid}', name: 'app_teamer_disposition_detail')]
|
||||||
|
#[IsGranted('ROLE_TEAMER')]
|
||||||
#[IsGranted('VIEW', subject: 'disposition')]
|
#[IsGranted('VIEW', subject: 'disposition')]
|
||||||
public function index(Disposition $disposition, Request $request): Response
|
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')]
|
#[Route('/teamer/disposition/invoice/{uuid}', name: 'app_teamer_disposition_invoicepdf')]
|
||||||
|
#[IsGranted('ROLE_TEAMER')]
|
||||||
#[IsGranted('INVOICE', subject: 'disposition')]
|
#[IsGranted('INVOICE', subject: 'disposition')]
|
||||||
public function index(Disposition $disposition): Response
|
public function index(Disposition $disposition): Response
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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>
|
<div>
|
||||||
{{ assignment.benefits|nl2list }}
|
{{ assignment.benefits|nl2list }}
|
||||||
</div>
|
</div>
|
||||||
|
{% if assignment.fees|length %}
|
||||||
<div>
|
<div>
|
||||||
Honorar
|
Honorar
|
||||||
</div>
|
</div>
|
||||||
{% if assignment.fees|length %}
|
|
||||||
<div>
|
<div>
|
||||||
{% for fee in assignment.fees %}
|
{% for fee in assignment.fees %}
|
||||||
{{ fee.name }} {{ fee.value|format_money }}
|
{{ fee.name }} {{ fee.value|format_money }}
|
||||||
|
|||||||
@@ -27,6 +27,11 @@
|
|||||||
<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>
|
||||||
|
<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 #}
|
{# Upload contract #}
|
||||||
{% if workflow_has_marked_place(disposition, 'new') %}
|
{% if workflow_has_marked_place(disposition, 'new') %}
|
||||||
|
|||||||
Reference in New Issue
Block a user