mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
some data in msgraph synchro and answer on calendar invite
This commit is contained in:
parent
59a64e9a62
commit
7c0bdc5abe
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\CalendarBundle\Controller;
|
||||
|
||||
use Chill\CalendarBundle\Entity\Calendar;
|
||||
use Chill\CalendarBundle\Entity\Invite;
|
||||
use Chill\CalendarBundle\Security\Voter\InviteVoter;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
use function in_array;
|
||||
|
||||
class InviteApiController
|
||||
{
|
||||
private EntityManagerInterface $entityManager;
|
||||
|
||||
private Security $security;
|
||||
|
||||
public function __construct(Security $security, EntityManagerInterface $entityManager)
|
||||
{
|
||||
$this->security = $security;
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Give an answer to a calendar invite.
|
||||
*
|
||||
* @Route("/api/1.0/calendar/calendar/{id}/answer/{answer}.json", methods={"post"})
|
||||
*/
|
||||
public function answer(Calendar $calendar, string $answer): Response
|
||||
{
|
||||
$user = $this->security->getUser();
|
||||
|
||||
if (!$user instanceof User) {
|
||||
throw new AccessDeniedHttpException('not a regular user');
|
||||
}
|
||||
|
||||
if (null === $invite = $calendar->getInviteForUser($user)) {
|
||||
throw new AccessDeniedHttpException('not invited to this calendar');
|
||||
}
|
||||
|
||||
if (!$this->security->isGranted(InviteVoter::ANSWER, $invite)) {
|
||||
throw new AccessDeniedHttpException('not allowed to answer on this invitation');
|
||||
}
|
||||
|
||||
if (!in_array($answer, Invite::STATUSES, true) || Invite::PENDING === $answer) {
|
||||
throw new BadRequestHttpException('answer not valid');
|
||||
}
|
||||
|
||||
$invite->setStatus($answer);
|
||||
$this->entityManager->flush();
|
||||
|
||||
return new JsonResponse(null, Response::HTTP_ACCEPTED, [], false);
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ use DateInterval;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use LogicException;
|
||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
@ -212,7 +213,7 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface
|
||||
|
||||
public function addUser(User $user): self
|
||||
{
|
||||
if (!$this->getUsers()->contains($user)) {
|
||||
if (!$this->getUsers()->contains($user) && $this->getMainUser() !== $user) {
|
||||
$this->addInvite((new Invite())->setUser($user));
|
||||
}
|
||||
|
||||
@ -263,6 +264,21 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getInviteForUser(User $user): ?Invite
|
||||
{
|
||||
$criteria = Criteria::create();
|
||||
$criteria->where(Criteria::expr()->eq('user', $user));
|
||||
|
||||
$matchings = $this->invites
|
||||
->matching($criteria);
|
||||
|
||||
if (1 === $matchings->count()) {
|
||||
return $matchings->first();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection|Invite[]
|
||||
*/
|
||||
@ -365,6 +381,18 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface
|
||||
return null !== $this->calendarRange;
|
||||
}
|
||||
|
||||
/**
|
||||
* return true if the user is invited.
|
||||
*/
|
||||
public function isInvited(User $user): bool
|
||||
{
|
||||
if ($this->getMainUser() === $user) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->getUsers()->contains($user);
|
||||
}
|
||||
|
||||
public static function loadValidatorMetadata(ClassMetadata $metadata): void
|
||||
{
|
||||
$metadata->addPropertyConstraint('startDate', new NotBlank());
|
||||
@ -485,6 +513,7 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface
|
||||
}
|
||||
|
||||
$this->mainUser = $mainUser;
|
||||
$this->removeUser($mainUser);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -36,6 +36,16 @@ class Invite implements TrackUpdateInterface, TrackCreationInterface
|
||||
|
||||
public const PENDING = 'pending';
|
||||
|
||||
/**
|
||||
* all statuses in one const.
|
||||
*/
|
||||
public const STATUSES = [
|
||||
self::ACCEPTED,
|
||||
self::DECLINED,
|
||||
self::PENDING,
|
||||
self::TENTATIVELY_ACCEPTED,
|
||||
];
|
||||
|
||||
public const TENTATIVELY_ACCEPTED = 'tentative';
|
||||
|
||||
/**
|
||||
|
@ -21,7 +21,6 @@ use DateTimeImmutable;
|
||||
use DateTimeZone;
|
||||
use Symfony\Component\Templating\EngineInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use Twig\Environment;
|
||||
|
||||
/**
|
||||
* Convert Chill Calendar event to Remote MS Graph event, and MS Graph
|
||||
@ -35,14 +34,14 @@ class RemoteEventConverter
|
||||
|
||||
private DateTimeZone $defaultDateTimeZone;
|
||||
|
||||
private EngineInterface $engine;
|
||||
|
||||
private PersonRenderInterface $personRender;
|
||||
|
||||
private DateTimeZone $remoteDateTimeZone;
|
||||
|
||||
private TranslatorInterface $translator;
|
||||
|
||||
private EngineInterface $engine;
|
||||
|
||||
public function __construct(EngineInterface $engine, PersonRenderInterface $personRender, TranslatorInterface $translator)
|
||||
{
|
||||
$this->engine = $engine;
|
||||
@ -112,7 +111,7 @@ class RemoteEventConverter
|
||||
'@ChillCalendar/MSGraph/calendar_event_body.html.twig',
|
||||
['calendar' => $calendar]
|
||||
),
|
||||
]
|
||||
],
|
||||
],
|
||||
$this->calendarToEventAttendeesOnly($calendar)
|
||||
);
|
||||
@ -129,17 +128,6 @@ class RemoteEventConverter
|
||||
];
|
||||
}
|
||||
|
||||
private function buildInviteToAttendee(Invite $invite): array
|
||||
{
|
||||
return [
|
||||
'emailAddress' => [
|
||||
'address' => $invite->getUser()->getEmail(),
|
||||
'name' => $invite->getUser()->getLabel(),
|
||||
],
|
||||
'type' => 'Required',
|
||||
];
|
||||
}
|
||||
|
||||
public function convertAvailabilityToRemoteEvent(array $event): RemoteEvent
|
||||
{
|
||||
$startDate =
|
||||
@ -193,4 +181,15 @@ class RemoteEventConverter
|
||||
{
|
||||
return new DateTimeZone('UTC');
|
||||
}
|
||||
|
||||
private function buildInviteToAttendee(Invite $invite): array
|
||||
{
|
||||
return [
|
||||
'emailAddress' => [
|
||||
'address' => $invite->getUser()->getEmail(),
|
||||
'name' => $invite->getUser()->getLabel(),
|
||||
],
|
||||
'type' => 'Required',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use function count;
|
||||
|
||||
class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
|
||||
{
|
||||
@ -41,10 +42,10 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
|
||||
|
||||
private RemoteEventConverter $remoteEventConverter;
|
||||
|
||||
private TranslatorInterface $translator;
|
||||
|
||||
private OnBehalfOfUserTokenStorage $tokenStorage;
|
||||
|
||||
private TranslatorInterface $translator;
|
||||
|
||||
private UrlGeneratorInterface $urlGenerator;
|
||||
|
||||
private OnBehalfOfUserHttpClient $userHttpClient;
|
||||
@ -171,7 +172,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
|
||||
$calendar->getRemoteId(),
|
||||
$this->translator->trans('remote_ms_graph.cancel_event_because_main_user_is_%label%', ['%label%' => $calendar->getMainUser()]),
|
||||
$previousMainUser,
|
||||
'calendar_'.$calendar->getRemoteId()
|
||||
'calendar_' . $calendar->getRemoteId()
|
||||
);
|
||||
$this->createCalendarOnRemote($calendar);
|
||||
} else {
|
||||
@ -189,10 +190,9 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
|
||||
->addRemoteAttributes([
|
||||
'lastModifiedDateTime' => null,
|
||||
'changeKey' => null,
|
||||
'previousId' => $calendar->getCalendarRange()->getRemoteId()
|
||||
'previousId' => $calendar->getCalendarRange()->getRemoteId(),
|
||||
])
|
||||
->setRemoteId('')
|
||||
;
|
||||
->setRemoteId('');
|
||||
}
|
||||
|
||||
if (null !== $previousCalendarRange) {
|
||||
@ -209,31 +209,30 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
|
||||
}
|
||||
}
|
||||
|
||||
private function patchCalendarOnRemote(Calendar $calendar, array $newInvites): void
|
||||
private function cancelOnRemote(string $remoteId, string $comment, User $user, string $identifier): void
|
||||
{
|
||||
$eventDatas = [];
|
||||
$eventDatas[] = $this->remoteEventConverter->calendarToEvent($calendar);
|
||||
$userId = $this->mapCalendarToUser->getUserId($user);
|
||||
|
||||
if (0 < count($newInvites)) {
|
||||
$eventDatas[] = $this->remoteEventConverter->calendarToEventAttendeesOnly($calendar);
|
||||
if (null === $userId) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($eventDatas as $eventData) {
|
||||
[
|
||||
'id' => $id,
|
||||
'lastModifiedDateTime' => $lastModified,
|
||||
'changeKey' => $changeKey
|
||||
] = $this->patchOnRemote(
|
||||
$calendar->getRemoteId(),
|
||||
$eventData,
|
||||
$calendar->getMainUser(),
|
||||
'calendar_'.$calendar->getId()
|
||||
try {
|
||||
$this->machineHttpClient->request(
|
||||
'POST',
|
||||
"users/{$userId}/calendar/events/{$remoteId}/cancel",
|
||||
[
|
||||
'json' => ['Comment' => $comment],
|
||||
]
|
||||
);
|
||||
|
||||
$calendar->addRemoteAttributes([
|
||||
'lastModifiedDateTime' => $lastModified,
|
||||
'changeKey' => $changeKey,
|
||||
} catch (ClientExceptionInterface $e) {
|
||||
$this->logger->warning('could not update calendar range to remote', [
|
||||
'exception' => $e->getTraceAsString(),
|
||||
'content' => $e->getResponse()->getContent(),
|
||||
'calendarRangeId' => $identifier,
|
||||
]);
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
@ -330,7 +329,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
|
||||
$calendarRange->setRemoteId($id)
|
||||
->addRemoteAttributes([
|
||||
'lastModifiedDateTime' => $lastModified,
|
||||
'changeKey' => $changeKey
|
||||
'changeKey' => $changeKey,
|
||||
]);
|
||||
}
|
||||
|
||||
@ -404,33 +403,32 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
|
||||
);
|
||||
}
|
||||
|
||||
private function cancelOnRemote(string $remoteId, string $comment, User $user, string $identifier): void
|
||||
private function patchCalendarOnRemote(Calendar $calendar, array $newInvites): void
|
||||
{
|
||||
$userId = $this->mapCalendarToUser->getUserId($user);
|
||||
$eventDatas = [];
|
||||
$eventDatas[] = $this->remoteEventConverter->calendarToEvent($calendar);
|
||||
|
||||
if (null === $userId) {
|
||||
return;
|
||||
if (0 < count($newInvites)) {
|
||||
$eventDatas[] = $this->remoteEventConverter->calendarToEventAttendeesOnly($calendar);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->machineHttpClient->request(
|
||||
'POST',
|
||||
"users/{$userId}/calendar/events/{$remoteId}/cancel",
|
||||
[
|
||||
'json' => ['Comment' => $comment]
|
||||
]
|
||||
foreach ($eventDatas as $eventData) {
|
||||
[
|
||||
'id' => $id,
|
||||
'lastModifiedDateTime' => $lastModified,
|
||||
'changeKey' => $changeKey
|
||||
] = $this->patchOnRemote(
|
||||
$calendar->getRemoteId(),
|
||||
$eventData,
|
||||
$calendar->getMainUser(),
|
||||
'calendar_' . $calendar->getId()
|
||||
);
|
||||
} catch (ClientExceptionInterface $e) {
|
||||
$this->logger->warning('could not update calendar range to remote', [
|
||||
'exception' => $e->getTraceAsString(),
|
||||
'content' => $e->getResponse()->getContent(),
|
||||
'calendarRangeId' => $identifier,
|
||||
|
||||
$calendar->addRemoteAttributes([
|
||||
'lastModifiedDateTime' => $lastModified,
|
||||
'changeKey' => $changeKey,
|
||||
]);
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\CalendarBundle\Security\Voter;
|
||||
|
||||
use Chill\CalendarBundle\Entity\Invite;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
|
||||
|
||||
class InviteVoter extends Voter
|
||||
{
|
||||
public const ANSWER = 'CHILL_CALENDAR_INVITE_ANSWER';
|
||||
|
||||
protected function supports($attribute, $subject): bool
|
||||
{
|
||||
return $subject instanceof Invite && self::ANSWER === $attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $attribute
|
||||
* @param Invite $subject
|
||||
*/
|
||||
protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
|
||||
{
|
||||
return $token->getUser() === $subject->getUser();
|
||||
}
|
||||
}
|
@ -1,204 +1,240 @@
|
||||
---
|
||||
openapi: "3.0.0"
|
||||
info:
|
||||
version: "1.0.0"
|
||||
title: "Chill api"
|
||||
description: "Api documentation for chill. Currently, work in progress"
|
||||
servers:
|
||||
- url: "/api"
|
||||
description: "Your current dev server"
|
||||
#openapi: "3.0.0"
|
||||
#info:
|
||||
# version: "1.0.0"
|
||||
# title: "Chill api"
|
||||
# description: "Api documentation for chill. Currently, work in progress"
|
||||
#servers:
|
||||
# - url: "/api"
|
||||
# description: "Your current dev server"
|
||||
|
||||
components:
|
||||
schemas:
|
||||
Date:
|
||||
type: object
|
||||
properties:
|
||||
datetime:
|
||||
type: string
|
||||
format: date-time
|
||||
User:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- user
|
||||
username:
|
||||
type: string
|
||||
text:
|
||||
type: string
|
||||
schemas:
|
||||
Date:
|
||||
type: object
|
||||
properties:
|
||||
datetime:
|
||||
type: string
|
||||
format: date-time
|
||||
User:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- user
|
||||
username:
|
||||
type: string
|
||||
text:
|
||||
type: string
|
||||
|
||||
paths:
|
||||
/1.0/calendar/calendar.json:
|
||||
get:
|
||||
tags:
|
||||
- calendar
|
||||
summary: Return a list of all calendar items
|
||||
responses:
|
||||
200:
|
||||
description: "ok"
|
||||
/1.0/calendar/calendar/{id}/answer/{answer}.json:
|
||||
post:
|
||||
tags:
|
||||
- calendar
|
||||
summary: Answer to a calendar's invite
|
||||
parameters:
|
||||
-
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
description: the calendar id
|
||||
schema:
|
||||
type: integer
|
||||
format: integer
|
||||
minimum: 0
|
||||
-
|
||||
in: path
|
||||
name: answer
|
||||
required: true
|
||||
description: the answer
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- accepted
|
||||
- declined
|
||||
- tentative
|
||||
responses:
|
||||
400:
|
||||
description: bad answer
|
||||
403:
|
||||
description: not invited
|
||||
404:
|
||||
description: not found
|
||||
202:
|
||||
description: accepted
|
||||
|
||||
/1.0/calendar/calendar/{id}.json:
|
||||
get:
|
||||
tags:
|
||||
- calendar
|
||||
summary: Return an calendar item by id
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
description: The calendar id
|
||||
schema:
|
||||
type: integer
|
||||
format: integer
|
||||
minimum: 1
|
||||
responses:
|
||||
200:
|
||||
description: "ok"
|
||||
404:
|
||||
description: "not found"
|
||||
401:
|
||||
description: "Unauthorized"
|
||||
/1.0/calendar/calendar.json:
|
||||
get:
|
||||
tags:
|
||||
- calendar
|
||||
summary: Return a list of all calendar items
|
||||
responses:
|
||||
200:
|
||||
description: "ok"
|
||||
|
||||
/1.0/calendar/calendar-range.json:
|
||||
get:
|
||||
tags:
|
||||
- calendar
|
||||
summary: Return a list of all calendar range items
|
||||
responses:
|
||||
200:
|
||||
description: "ok"
|
||||
post:
|
||||
tags:
|
||||
- calendar
|
||||
summary: create a new calendar range
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
user:
|
||||
$ref: '#/components/schemas/User'
|
||||
startDate:
|
||||
$ref: '#/components/schemas/Date'
|
||||
endDate:
|
||||
$ref: '#/components/schemas/Date'
|
||||
responses:
|
||||
401:
|
||||
description: "Unauthorized"
|
||||
404:
|
||||
description: "Not found"
|
||||
200:
|
||||
description: "OK"
|
||||
422:
|
||||
description: "Unprocessable entity (validation errors)"
|
||||
400:
|
||||
description: "transition cannot be applyed"
|
||||
/1.0/calendar/calendar/{id}.json:
|
||||
get:
|
||||
tags:
|
||||
- calendar
|
||||
summary: Return an calendar item by id
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
description: The calendar id
|
||||
schema:
|
||||
type: integer
|
||||
format: integer
|
||||
minimum: 1
|
||||
responses:
|
||||
200:
|
||||
description: "ok"
|
||||
404:
|
||||
description: "not found"
|
||||
401:
|
||||
description: "Unauthorized"
|
||||
|
||||
/1.0/calendar/calendar-range/{id}.json:
|
||||
get:
|
||||
tags:
|
||||
- calendar
|
||||
summary: Return an calendar-range item by id
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
description: The calendar-range id
|
||||
schema:
|
||||
type: integer
|
||||
format: integer
|
||||
minimum: 1
|
||||
responses:
|
||||
200:
|
||||
description: "ok"
|
||||
404:
|
||||
description: "not found"
|
||||
401:
|
||||
description: "Unauthorized"
|
||||
patch:
|
||||
tags:
|
||||
- calendar
|
||||
summary: update a calendar range
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
user:
|
||||
$ref: '#/components/schemas/User'
|
||||
startDate:
|
||||
$ref: '#/components/schemas/Date'
|
||||
endDate:
|
||||
$ref: '#/components/schemas/Date'
|
||||
responses:
|
||||
401:
|
||||
description: "Unauthorized"
|
||||
404:
|
||||
description: "Not found"
|
||||
200:
|
||||
description: "OK"
|
||||
422:
|
||||
description: "Unprocessable entity (validation errors)"
|
||||
400:
|
||||
description: "transition cannot be applyed"
|
||||
delete:
|
||||
tags:
|
||||
- calendar
|
||||
summary: "Remove a calendar range"
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
description: The calendar range id
|
||||
schema:
|
||||
type: integer
|
||||
format: integer
|
||||
minimum: 1
|
||||
responses:
|
||||
401:
|
||||
description: "Unauthorized"
|
||||
404:
|
||||
description: "Not found"
|
||||
200:
|
||||
description: "OK"
|
||||
422:
|
||||
description: "object with validation errors"
|
||||
/1.0/calendar/calendar-range.json:
|
||||
get:
|
||||
tags:
|
||||
- calendar
|
||||
summary: Return a list of all calendar range items
|
||||
responses:
|
||||
200:
|
||||
description: "ok"
|
||||
post:
|
||||
tags:
|
||||
- calendar
|
||||
summary: create a new calendar range
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
user:
|
||||
$ref: '#/components/schemas/User'
|
||||
startDate:
|
||||
$ref: '#/components/schemas/Date'
|
||||
endDate:
|
||||
$ref: '#/components/schemas/Date'
|
||||
responses:
|
||||
401:
|
||||
description: "Unauthorized"
|
||||
404:
|
||||
description: "Not found"
|
||||
200:
|
||||
description: "OK"
|
||||
422:
|
||||
description: "Unprocessable entity (validation errors)"
|
||||
400:
|
||||
description: "transition cannot be applyed"
|
||||
|
||||
/1.0/calendar/calendar-range-available/{userId}.json:
|
||||
get:
|
||||
tags:
|
||||
- calendar
|
||||
summary: Return a list of available calendar range items. Available means calendar-range not being taken by a calendar entity
|
||||
parameters:
|
||||
- name: userId
|
||||
in: path
|
||||
required: true
|
||||
description: The user id
|
||||
schema:
|
||||
type: integer
|
||||
format: integer
|
||||
minimum: 1
|
||||
- name: dateFrom
|
||||
in: query
|
||||
required: true
|
||||
description: The date from, formatted as ISO8601 string
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
- name: dateTo
|
||||
in: query
|
||||
required: true
|
||||
description: The date to, formatted as ISO8601 string
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
responses:
|
||||
200:
|
||||
description: "ok"
|
||||
/1.0/calendar/calendar-range/{id}.json:
|
||||
get:
|
||||
tags:
|
||||
- calendar
|
||||
summary: Return an calendar-range item by id
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
description: The calendar-range id
|
||||
schema:
|
||||
type: integer
|
||||
format: integer
|
||||
minimum: 1
|
||||
responses:
|
||||
200:
|
||||
description: "ok"
|
||||
404:
|
||||
description: "not found"
|
||||
401:
|
||||
description: "Unauthorized"
|
||||
patch:
|
||||
tags:
|
||||
- calendar
|
||||
summary: update a calendar range
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
user:
|
||||
$ref: '#/components/schemas/User'
|
||||
startDate:
|
||||
$ref: '#/components/schemas/Date'
|
||||
endDate:
|
||||
$ref: '#/components/schemas/Date'
|
||||
responses:
|
||||
401:
|
||||
description: "Unauthorized"
|
||||
404:
|
||||
description: "Not found"
|
||||
200:
|
||||
description: "OK"
|
||||
422:
|
||||
description: "Unprocessable entity (validation errors)"
|
||||
400:
|
||||
description: "transition cannot be applyed"
|
||||
delete:
|
||||
tags:
|
||||
- calendar
|
||||
summary: "Remove a calendar range"
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
description: The calendar range id
|
||||
schema:
|
||||
type: integer
|
||||
format: integer
|
||||
minimum: 1
|
||||
responses:
|
||||
401:
|
||||
description: "Unauthorized"
|
||||
404:
|
||||
description: "Not found"
|
||||
200:
|
||||
description: "OK"
|
||||
422:
|
||||
description: "object with validation errors"
|
||||
|
||||
/1.0/calendar/calendar-range-available/{userId}.json:
|
||||
get:
|
||||
tags:
|
||||
- calendar
|
||||
summary: Return a list of available calendar range items. Available means calendar-range not being taken by a calendar entity
|
||||
parameters:
|
||||
- name: userId
|
||||
in: path
|
||||
required: true
|
||||
description: The user id
|
||||
schema:
|
||||
type: integer
|
||||
format: integer
|
||||
minimum: 1
|
||||
- name: dateFrom
|
||||
in: query
|
||||
required: true
|
||||
description: The date from, formatted as ISO8601 string
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
- name: dateTo
|
||||
in: query
|
||||
required: true
|
||||
description: The date to, formatted as ISO8601 string
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
responses:
|
||||
200:
|
||||
description: "ok"
|
||||
|
Loading…
x
Reference in New Issue
Block a user