mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-13 13:54:23 +00:00
Merge branch 'features/create-social-action' into 'master'
Create social work See merge request Chill-Projet/chill-bundles!90
This commit is contained in:
commit
7fb4616aa6
@ -359,9 +359,10 @@ class ApiController extends AbstractCRUDController
|
|||||||
* 6. validate the base entity (not the deserialized one). Groups are fetched from getValidationGroups, validation is perform by `validate`
|
* 6. validate the base entity (not the deserialized one). Groups are fetched from getValidationGroups, validation is perform by `validate`
|
||||||
* 7. run onAfterValidation
|
* 7. run onAfterValidation
|
||||||
* 8. if errors, return a 422 response with errors
|
* 8. if errors, return a 422 response with errors
|
||||||
* 9. flush the data
|
* 9. if $forcePersist === true, persist the entity
|
||||||
* 10. run onAfterFlush
|
* 10. flush the data
|
||||||
* 11. return a 202 response for DELETE with empty body, or HTTP 200 for post with serialized posted entity
|
* 11. run onAfterFlush
|
||||||
|
* 12. return a 202 response for DELETE with empty body, or HTTP 200 for post with serialized posted entity
|
||||||
*
|
*
|
||||||
* @param string action
|
* @param string action
|
||||||
* @param mixed id
|
* @param mixed id
|
||||||
@ -370,11 +371,12 @@ class ApiController extends AbstractCRUDController
|
|||||||
* @param string $property the name of the property. This will be used to make a `add+$property` and `remove+$property` method
|
* @param string $property the name of the property. This will be used to make a `add+$property` and `remove+$property` method
|
||||||
* @param string $postedDataType the type of the posted data (the content)
|
* @param string $postedDataType the type of the posted data (the content)
|
||||||
* @param string $postedDataContext a context to deserialize posted data (the content)
|
* @param string $postedDataContext a context to deserialize posted data (the content)
|
||||||
|
* @param bool $forcePersist force to persist the created element (only for POST request)
|
||||||
* @throw BadRequestException if unable to deserialize the posted data
|
* @throw BadRequestException if unable to deserialize the posted data
|
||||||
* @throw BadRequestException if the method is not POST or DELETE
|
* @throw BadRequestException if the method is not POST or DELETE
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected function addRemoveSomething(string $action, $id, Request $request, string $_format, string $property, string $postedDataType, $postedDataContext = []): Response
|
protected function addRemoveSomething(string $action, $id, Request $request, string $_format, string $property, string $postedDataType, array $postedDataContext = [], bool $forcePersist = false): Response
|
||||||
{
|
{
|
||||||
$entity = $this->getEntity($action, $id, $request);
|
$entity = $this->getEntity($action, $id, $request);
|
||||||
|
|
||||||
@ -429,6 +431,10 @@ class ApiController extends AbstractCRUDController
|
|||||||
return $this->json($errors, 422);
|
return $this->json($errors, 422);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($forcePersist && $request->getMethod() === Request::METHOD_POST) {
|
||||||
|
$this->getDoctrine()->getManager()->persist($postedData);
|
||||||
|
}
|
||||||
|
|
||||||
$this->getDoctrine()->getManager()->flush();
|
$this->getDoctrine()->getManager()->flush();
|
||||||
|
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ class CRUDRoutesLoader extends Loader
|
|||||||
|
|
||||||
foreach ($crudConfig['actions'] as $name => $action) {
|
foreach ($crudConfig['actions'] as $name => $action) {
|
||||||
// filter only on single actions
|
// filter only on single actions
|
||||||
$singleCollection = $action['single-collection'] ?? $name === '_entity' ? 'single' : NULL;
|
$singleCollection = $action['single_collection'] ?? $name === '_entity' ? 'single' : NULL;
|
||||||
if ('collection' === $singleCollection) {
|
if ('collection' === $singleCollection) {
|
||||||
// continue;
|
// continue;
|
||||||
}
|
}
|
||||||
@ -171,7 +171,7 @@ class CRUDRoutesLoader extends Loader
|
|||||||
// path are rewritten
|
// path are rewritten
|
||||||
// if name === 'default', we rewrite it to nothing :-)
|
// if name === 'default', we rewrite it to nothing :-)
|
||||||
$localName = \in_array($name, [ '_entity', '_index' ]) ? '' : '/'.$name;
|
$localName = \in_array($name, [ '_entity', '_index' ]) ? '' : '/'.$name;
|
||||||
if ('collection' === $action['single-collection'] || '_index' === $name) {
|
if ('collection' === $action['single_collection'] || '_index' === $name) {
|
||||||
$localPath = $action['path'] ?? $localName.'.{_format}';
|
$localPath = $action['path'] ?? $localName.'.{_format}';
|
||||||
} else {
|
} else {
|
||||||
$localPath = $action['path'] ?? '/{id}'.$localName.'.{_format}';
|
$localPath = $action['path'] ?? '/{id}'.$localName.'.{_format}';
|
||||||
|
@ -205,7 +205,7 @@ class Configuration implements ConfigurationInterface
|
|||||||
->ignoreExtraKeys(false)
|
->ignoreExtraKeys(false)
|
||||||
->info('the requirements for the route. Will be set to `[ \'id\' => \'\d+\' ]` if left empty.')
|
->info('the requirements for the route. Will be set to `[ \'id\' => \'\d+\' ]` if left empty.')
|
||||||
->end()
|
->end()
|
||||||
->enumNode('single-collection')
|
->enumNode('single_collection')
|
||||||
->values(['single', 'collection'])
|
->values(['single', 'collection'])
|
||||||
->defaultValue('single')
|
->defaultValue('single')
|
||||||
->info('indicates if the returned object is a single element or a collection. '.
|
->info('indicates if the returned object is a single element or a collection. '.
|
||||||
|
@ -11,13 +11,16 @@
|
|||||||
*
|
*
|
||||||
* Do not take time into account
|
* Do not take time into account
|
||||||
*
|
*
|
||||||
* **Experimental**
|
|
||||||
*/
|
*/
|
||||||
const dateToISO = (date) => {
|
const dateToISO = (date) => {
|
||||||
|
if (null === date) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
this.$store.state.startDate.getFullYear(),
|
date.getFullYear(),
|
||||||
(this.$store.state.startDate.getMonth() + 1).toString().padStart(2, '0'),
|
(date.getMonth() + 1).toString().padStart(2, '0'),
|
||||||
this.$store.state.startDate.getDate().toString().padStart(2, '0')
|
date.getDate().toString().padStart(2, '0')
|
||||||
].join('-');
|
].join('-');
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -36,10 +39,12 @@ const ISOToDate = (str) => {
|
|||||||
/**
|
/**
|
||||||
* Return a date object from iso string formatted as YYYY-mm-dd:HH:MM:ss+01:00
|
* Return a date object from iso string formatted as YYYY-mm-dd:HH:MM:ss+01:00
|
||||||
*
|
*
|
||||||
* **Experimental**
|
|
||||||
*/
|
*/
|
||||||
const ISOToDatetime = (str) => {
|
const ISOToDatetime = (str) => {
|
||||||
console.log(str);
|
if (null === str) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
let
|
let
|
||||||
[cal, times] = str.split('T'),
|
[cal, times] = str.split('T'),
|
||||||
[year, month, date] = cal.split('-'),
|
[year, month, date] = cal.split('-'),
|
||||||
|
@ -19,7 +19,6 @@ class CollectionNormalizer implements NormalizerInterface, NormalizerAwareInterf
|
|||||||
public function normalize($collection, string $format = null, array $context = [])
|
public function normalize($collection, string $format = null, array $context = [])
|
||||||
{
|
{
|
||||||
/** @var $collection Collection */
|
/** @var $collection Collection */
|
||||||
/** @var $collection Chill\MainBundle\Pagination\PaginatorInterface */
|
|
||||||
$paginator = $collection->getPaginator();
|
$paginator = $collection->getPaginator();
|
||||||
|
|
||||||
$data['count'] = $paginator->getTotalItems();
|
$data['count'] = $paginator->getTotalItems();
|
||||||
|
@ -6,6 +6,7 @@ use Chill\MainBundle\CRUD\Controller\ApiController;
|
|||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
|
||||||
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
|
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
|
||||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||||
@ -116,6 +117,20 @@ $workflow = $this->registry->get($accompanyingPeriod);
|
|||||||
return $this->addRemoveSomething('socialissue', $id, $request, $_format, 'socialIssue', SocialIssue::class, [ 'groups' => [ 'read' ] ]);
|
return $this->addRemoveSomething('socialissue', $id, $request, $_format, 'socialIssue', SocialIssue::class, [ 'groups' => [ 'read' ] ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function workApi($id, Request $request, string $_format): Response
|
||||||
|
{
|
||||||
|
return $this->addRemoveSomething(
|
||||||
|
'work',
|
||||||
|
$id,
|
||||||
|
$request,
|
||||||
|
$_format,
|
||||||
|
'work',
|
||||||
|
AccompanyingPeriodWork::class,
|
||||||
|
[ 'groups' => [ 'accompanying_period_work:create' ] ],
|
||||||
|
true // force persist
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function requestorApi($id, Request $request, string $_format): Response
|
public function requestorApi($id, Request $request, string $_format): Response
|
||||||
{
|
{
|
||||||
/** @var AccompanyingPeriod $accompanyingPeriod */
|
/** @var AccompanyingPeriod $accompanyingPeriod */
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\Controller;
|
||||||
|
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
use Symfony\Component\Serializer\SerializerInterface;
|
||||||
|
use Symfony\Component\Translation\TranslatorInterface;
|
||||||
|
|
||||||
|
class AccompanyingCourseWorkController extends AbstractController
|
||||||
|
{
|
||||||
|
private TranslatorInterface $trans;
|
||||||
|
private SerializerInterface $serializer;
|
||||||
|
|
||||||
|
public function __construct(TranslatorInterface $trans, SerializerInterface $serializer)
|
||||||
|
{
|
||||||
|
$this->trans = $trans;
|
||||||
|
$this->serializer = $serializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Route(
|
||||||
|
* "{_locale}/person/accompanying-period/{id}/work/new",
|
||||||
|
* methods={"GET", "POST"}
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
public function createWork(AccompanyingPeriod $period)
|
||||||
|
{
|
||||||
|
// TODO ACL
|
||||||
|
|
||||||
|
if ($period->getSocialIssues()->count() === 0) {
|
||||||
|
$this->addFlash('error', $this->trans->trans(
|
||||||
|
"accompanying_work.You must add at least ".
|
||||||
|
"one social issue on accompanying period")
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->redirectToRoute('chill_person_accompanying_course_index', [
|
||||||
|
'accompanying_period_id' => $period->getId()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$json = $this->serializer->normalize($period, 'json', [ "groups" => [ "read" ]]);
|
||||||
|
|
||||||
|
return $this->render('@ChillPerson/AccompanyingCourseWork/create.html.twig', [
|
||||||
|
'accompanyingCourse' => $period,
|
||||||
|
'json' => $json
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\Controller;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Serializer\Model\Collection;
|
||||||
|
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||||
|
use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
|
||||||
|
use Chill\MainBundle\CRUD\Controller\ApiController;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
|
|
||||||
|
class SocialWorkSocialActionApiController extends ApiController
|
||||||
|
{
|
||||||
|
private SocialIssueRepository $socialIssueRepository;
|
||||||
|
|
||||||
|
private PaginatorFactory $paginator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param SocialIssueRepository $socialIssueRepository
|
||||||
|
*/
|
||||||
|
public function __construct(SocialIssueRepository $socialIssueRepository, PaginatorFactory $paginator)
|
||||||
|
{
|
||||||
|
$this->socialIssueRepository = $socialIssueRepository;
|
||||||
|
$this->paginator = $paginator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function listBySocialIssueApi($id, Request $request)
|
||||||
|
{
|
||||||
|
$socialIssue = $this->socialIssueRepository
|
||||||
|
->find($id);
|
||||||
|
|
||||||
|
if (NULL === $socialIssue) {
|
||||||
|
throw $this->createNotFoundException("socialIssue not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
$socialActions = $socialIssue->getRecursiveSocialActions();
|
||||||
|
$pagination = $this->paginator->create(count($socialActions));
|
||||||
|
// max one page
|
||||||
|
$pagination->setItemsPerPage(count($socialActions));
|
||||||
|
|
||||||
|
$collection = new Collection($socialActions, $pagination);
|
||||||
|
|
||||||
|
|
||||||
|
return $this->json($collection, JsonResponse::HTTP_OK, [], [ "groups" => [ "read" ]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -438,6 +438,19 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
|||||||
Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
|
Request::METHOD_DELETE=> \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
'work' => [
|
||||||
|
'methods' => [
|
||||||
|
Request::METHOD_POST => true,
|
||||||
|
Request::METHOD_DELETE => false,
|
||||||
|
Request::METHOD_GET => false,
|
||||||
|
Request::METHOD_HEAD => false,
|
||||||
|
],
|
||||||
|
'controller_action' => 'workApi',
|
||||||
|
'roles' => [
|
||||||
|
Request::METHOD_POST => \Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter::SEE,
|
||||||
|
Request::METHOD_DELETE => 'ALWAYS_FAILS',
|
||||||
|
]
|
||||||
|
],
|
||||||
|
|
||||||
'confirm' => [
|
'confirm' => [
|
||||||
'methods' => [
|
'methods' => [
|
||||||
@ -573,6 +586,49 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
|||||||
],
|
],
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'class' => \Chill\PersonBundle\Entity\SocialWork\SocialAction::class,
|
||||||
|
'name' => 'social_action',
|
||||||
|
'base_path' => '/api/1.0/person/social/social-action',
|
||||||
|
'controller' => \Chill\PersonBundle\Controller\SocialWorkSocialActionApiController::class,
|
||||||
|
// TODO: acl
|
||||||
|
'base_role' => 'ROLE_USER',
|
||||||
|
'actions' => [
|
||||||
|
'_entity' => [
|
||||||
|
'methods' => [
|
||||||
|
Request::METHOD_GET => true,
|
||||||
|
Request::METHOD_HEAD => true,
|
||||||
|
],
|
||||||
|
'roles' => [
|
||||||
|
Request::METHOD_GET => 'ROLE_USER',
|
||||||
|
Request::METHOD_HEAD => 'ROLE_USER',
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'_index' => [
|
||||||
|
'methods' => [
|
||||||
|
Request::METHOD_GET => true,
|
||||||
|
Request::METHOD_HEAD => true,
|
||||||
|
],
|
||||||
|
'roles' => [
|
||||||
|
Request::METHOD_GET => 'ROLE_USER',
|
||||||
|
Request::METHOD_HEAD => 'ROLE_USER',
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'listBySocialIssue' => [
|
||||||
|
'single-collection' => 'collection',
|
||||||
|
'path' => '/by-social-issue/{id}.{_format}',
|
||||||
|
'methods' => [
|
||||||
|
Request::METHOD_GET => true,
|
||||||
|
Request::METHOD_HEAD => true,
|
||||||
|
],
|
||||||
|
'roles' => [
|
||||||
|
Request::METHOD_GET => 'ROLE_USER',
|
||||||
|
Request::METHOD_HEAD => 'ROLE_USER',
|
||||||
|
]
|
||||||
|
|
||||||
|
]
|
||||||
|
]
|
||||||
|
],
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ namespace Chill\PersonBundle\Entity;
|
|||||||
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
|
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
|
||||||
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
|
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
|
||||||
use Chill\MainBundle\Entity\Scope;
|
use Chill\MainBundle\Entity\Scope;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\Origin;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\Origin;
|
||||||
@ -39,6 +40,7 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
|||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
use Symfony\Component\Serializer\Annotation\Groups;
|
use Symfony\Component\Serializer\Annotation\Groups;
|
||||||
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
|
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccompanyingPeriod Class
|
* AccompanyingPeriod Class
|
||||||
@ -280,6 +282,15 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
*/
|
*/
|
||||||
private \DateTimeInterface $updatedAt;
|
private \DateTimeInterface $updatedAt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\OneToMany(
|
||||||
|
* targetEntity=AccompanyingPeriodWork::class,
|
||||||
|
* mappedBy="accompanyingPeriod"
|
||||||
|
* )
|
||||||
|
* @Assert\Valid(traverse=true)
|
||||||
|
*/
|
||||||
|
private Collection $works;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccompanyingPeriod constructor.
|
* AccompanyingPeriod constructor.
|
||||||
*
|
*
|
||||||
@ -292,6 +303,7 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
$this->scopes = new ArrayCollection();
|
$this->scopes = new ArrayCollection();
|
||||||
$this->socialIssues = new ArrayCollection();
|
$this->socialIssues = new ArrayCollection();
|
||||||
$this->comments = new ArrayCollection();
|
$this->comments = new ArrayCollection();
|
||||||
|
$this->works = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -896,4 +908,28 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return AccompanyingPeriodWork[]
|
||||||
|
*/
|
||||||
|
public function getWorks(): Collection
|
||||||
|
{
|
||||||
|
return $this->works;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addWork(AccompanyingPeriodWork $work): self
|
||||||
|
{
|
||||||
|
$this->works[] = $work;
|
||||||
|
$work->setAccompanyingPeriod($this);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeWork(AccompanyingPeriodWork $work): self
|
||||||
|
{
|
||||||
|
$this->work->removeElement($work);
|
||||||
|
$work->setAccompanyingPeriod(null);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,86 +7,123 @@ use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
|||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||||
|
use DateTimeInterface;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||||
|
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
|
||||||
|
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Entity
|
* @ORM\Entity
|
||||||
* @ORM\Table(name="chill_person_accompanying_period_work")
|
* @ORM\Table(name="chill_person_accompanying_period_work")
|
||||||
|
* @Serializer\DiscriminatorMap(
|
||||||
|
* typeProperty="type",
|
||||||
|
* mapping={
|
||||||
|
* "accompanying_period_work":AccompanyingPeriodWork::class
|
||||||
|
* }
|
||||||
|
* )
|
||||||
*/
|
*/
|
||||||
class AccompanyingPeriodWork
|
class AccompanyingPeriodWork implements TrackCreationInterface, TrackUpdateInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @ORM\Id
|
* @ORM\Id
|
||||||
* @ORM\GeneratedValue
|
* @ORM\GeneratedValue
|
||||||
* @ORM\Column(type="integer")
|
* @ORM\Column(type="integer")
|
||||||
|
* @Serializer\Groups({"read"})
|
||||||
*/
|
*/
|
||||||
private $id;
|
private ?int $id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="text")
|
* @ORM\Column(type="text")
|
||||||
|
* @Serializer\Groups({"read"})
|
||||||
*/
|
*/
|
||||||
private $note;
|
private string $note = "";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToOne(targetEntity=AccompanyingPeriod::class)
|
* @ORM\ManyToOne(targetEntity=AccompanyingPeriod::class)
|
||||||
|
* @Serializer\Groups({"read"})
|
||||||
*/
|
*/
|
||||||
private $accompanyingPeriod;
|
private ?AccompanyingPeriod $accompanyingPeriod = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToOne(targetEntity=SocialAction::class)
|
* @ORM\ManyToOne(targetEntity=SocialAction::class)
|
||||||
|
* @Serializer\Groups({"accompanying_period_work:create", "read"})
|
||||||
*/
|
*/
|
||||||
private $socialAction;
|
private ?SocialAction $socialAction = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="datetime")
|
* @ORM\Column(type="datetime_immutable")
|
||||||
|
* @Serializer\Groups({"read"})
|
||||||
*/
|
*/
|
||||||
private $createdAt;
|
private ?\DateTimeImmutable $createdAt = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToOne(targetEntity=User::class)
|
* @ORM\ManyToOne(targetEntity=User::class)
|
||||||
* @ORM\JoinColumn(nullable=false)
|
* @ORM\JoinColumn(nullable=false)
|
||||||
|
* @Serializer\Groups({"read"})
|
||||||
*/
|
*/
|
||||||
private $createdBy;
|
private ?User $createdBy = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="datetime")
|
* @ORM\Column(type="datetime_immutable")
|
||||||
|
* @Serializer\Groups({"read"})
|
||||||
*/
|
*/
|
||||||
private $startDate;
|
private ?\DateTimeImmutable $updatedAt = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="datetime")
|
* @ORM\ManyToOne(targetEntity=User::class)
|
||||||
|
* @ORM\JoinColumn(nullable=false)
|
||||||
|
* @Serializer\Groups({"read"})
|
||||||
*/
|
*/
|
||||||
private $endDate;
|
private ?User $updatedBy = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="date_immutable")
|
||||||
|
* @Serializer\Groups({"accompanying_period_work:create"})
|
||||||
|
* @Serializer\Groups({"read"})
|
||||||
|
*/
|
||||||
|
private \DateTimeImmutable $startDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="date_immutable", nullable=true, options={"default":null})
|
||||||
|
* @Serializer\Groups({"accompanying_period_work:create", "read"})
|
||||||
|
* @Assert\GreaterThan(propertyPath="startDate",
|
||||||
|
* message="accompanying_course_work.The endDate should be greater than the start date"
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
private ?\DateTimeImmutable $endDate = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToOne(targetEntity=ThirdParty::class)
|
* @ORM\ManyToOne(targetEntity=ThirdParty::class)
|
||||||
|
* @Serializer\Groups({"read"})
|
||||||
*
|
*
|
||||||
* In schema : traitant
|
* In schema : traitant
|
||||||
*/
|
*/
|
||||||
private $handlingThierParty;
|
private ?ThirdParty $handlingThierParty = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="boolean")
|
* @ORM\Column(type="boolean")
|
||||||
*/
|
*/
|
||||||
private $createdAutomatically;
|
private bool $createdAutomatically = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="text")
|
* @ORM\Column(type="text")
|
||||||
*/
|
*/
|
||||||
private $createdAutomaticallyReason;
|
private string $createdAutomaticallyReason = "";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\OneToMany(targetEntity=AccompanyingPeriodWorkGoal::class, mappedBy="accompanyingPeriodWork")
|
* @ORM\OneToMany(targetEntity=AccompanyingPeriodWorkGoal::class, mappedBy="accompanyingPeriodWork")
|
||||||
*/
|
*/
|
||||||
private $goals;
|
private Collection $goals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToMany(targetEntity=Result::class, inversedBy="accompanyingPeriodWorks")
|
* @ORM\ManyToMany(targetEntity=Result::class, inversedBy="accompanyingPeriodWorks")
|
||||||
* @ORM\JoinTable(name="chill_person_accompanying_period_work_result")
|
* @ORM\JoinTable(name="chill_person_accompanying_period_work_result")
|
||||||
*/
|
*/
|
||||||
private $results;
|
private Collection $results;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToMany(targetEntity=ThirdParty::class)
|
* @ORM\ManyToMany(targetEntity=ThirdParty::class)
|
||||||
@ -94,7 +131,7 @@ use Doctrine\ORM\Mapping as ORM;
|
|||||||
*
|
*
|
||||||
* In schema : intervenants
|
* In schema : intervenants
|
||||||
*/
|
*/
|
||||||
private $thirdParties;
|
private Collection $thirdParties;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@ -125,8 +162,17 @@ use Doctrine\ORM\Mapping as ORM;
|
|||||||
return $this->accompanyingPeriod;
|
return $this->accompanyingPeriod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal: you should use `$accompanyingPeriod->removeWork($work);` or
|
||||||
|
* `$accompanyingPeriod->addWork($work);`
|
||||||
|
*/
|
||||||
public function setAccompanyingPeriod(?AccompanyingPeriod $accompanyingPeriod): self
|
public function setAccompanyingPeriod(?AccompanyingPeriod $accompanyingPeriod): self
|
||||||
{
|
{
|
||||||
|
if ($this->accompanyingPeriod instanceof AccompanyingPeriod &&
|
||||||
|
$accompanyingPeriod !== $this->accompanyingPeriod) {
|
||||||
|
throw new \LogicException("A work cannot change accompanyingPeriod");
|
||||||
|
}
|
||||||
|
|
||||||
$this->accompanyingPeriod = $accompanyingPeriod;
|
$this->accompanyingPeriod = $accompanyingPeriod;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
@ -144,7 +190,7 @@ use Doctrine\ORM\Mapping as ORM;
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCreatedAt(): ?\DateTimeInterface
|
public function getCreatedAt(): ?\DateTimeImmutable
|
||||||
{
|
{
|
||||||
return $this->createdAt;
|
return $this->createdAt;
|
||||||
}
|
}
|
||||||
@ -168,6 +214,30 @@ use Doctrine\ORM\Mapping as ORM;
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setUpdatedBy(User $user): TrackUpdateInterface
|
||||||
|
{
|
||||||
|
$this->updatedBy = $user;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUpdatedAt(DateTimeInterface $datetime): TrackUpdateInterface
|
||||||
|
{
|
||||||
|
$this->updatedAt = $datetime;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUpdatedAt(): ?\DateTimeImmutable
|
||||||
|
{
|
||||||
|
return $this->updatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUpdatedBy(): ?User
|
||||||
|
{
|
||||||
|
return $this->updatedBy;
|
||||||
|
}
|
||||||
|
|
||||||
public function getStartDate(): ?\DateTimeInterface
|
public function getStartDate(): ?\DateTimeInterface
|
||||||
{
|
{
|
||||||
return $this->startDate;
|
return $this->startDate;
|
||||||
|
@ -5,10 +5,17 @@ namespace Chill\PersonBundle\Entity\SocialWork;
|
|||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Entity
|
* @ORM\Entity
|
||||||
* @ORM\Table(name="chill_person_social_action")
|
* @ORM\Table(name="chill_person_social_action")
|
||||||
|
* @Serializer\DiscriminatorMap(
|
||||||
|
* typeProperty="type",
|
||||||
|
* mapping={
|
||||||
|
* "social_work_social_action":SocialAction::class
|
||||||
|
* }
|
||||||
|
* )
|
||||||
*/
|
*/
|
||||||
class SocialAction
|
class SocialAction
|
||||||
{
|
{
|
||||||
|
@ -6,8 +6,9 @@ use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
|||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\EntityRepository;
|
use Doctrine\ORM\EntityRepository;
|
||||||
|
use Doctrine\Persistence\ObjectRepository;
|
||||||
|
|
||||||
final class SocialIssueRepository
|
final class SocialIssueRepository implements ObjectRepository
|
||||||
{
|
{
|
||||||
private EntityRepository $repository;
|
private EntityRepository $repository;
|
||||||
|
|
||||||
@ -15,4 +16,44 @@ final class SocialIssueRepository
|
|||||||
{
|
{
|
||||||
$this->repository = $entityManager->getRepository(SocialIssue::class);
|
$this->repository = $entityManager->getRepository(SocialIssue::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function find($id)
|
||||||
|
{
|
||||||
|
return $this->repository->find($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function findAll()
|
||||||
|
{
|
||||||
|
return $this->repository->findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null)
|
||||||
|
{
|
||||||
|
return $this->repository->findBy($criteria, $orderBy, $limit, $offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function findOneBy(array $criteria)
|
||||||
|
{
|
||||||
|
return $this->findOneBy($criteria);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function getClassName()
|
||||||
|
{
|
||||||
|
return SocialIssue::class;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,190 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<h2>{{ $t('pick_social_issue') }}</h2>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="awc_create_form">
|
||||||
|
|
||||||
|
<div id="picking">
|
||||||
|
<p>{{ $t('pick_social_issue_linked_with_action') }}</p>
|
||||||
|
|
||||||
|
<div v-for="si in socialIssues">
|
||||||
|
<input type="radio" v-bind:value="si.id" name="socialIssue" v-model="socialIssuePicked"> {{ si.title.fr }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="hasSocialIssuePicked">
|
||||||
|
<h2>{{ $t('pick_an_action') }}</h2>
|
||||||
|
|
||||||
|
<vue-multiselect
|
||||||
|
v-model="socialActionPicked"
|
||||||
|
label="text"
|
||||||
|
:options="socialActionsReachables"
|
||||||
|
:searchable="true"
|
||||||
|
:close-on-select="true"
|
||||||
|
:show-labels="true"
|
||||||
|
track-by="id"
|
||||||
|
></vue-multiselect>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="isLoadingSocialActions">
|
||||||
|
<p>spinner</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="hasSocialActionPicked" id="start_date">
|
||||||
|
<p><label>{{ $t('startDate') }}</label> <input type="date" v-model="startDate" /></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="hasSocialActionPicked" id="end_date">
|
||||||
|
<p><label>{{ $t('endDate') }}</label> <input type="date" v-model="endDate" /></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="confirm">
|
||||||
|
<div v-if="hasErrors">
|
||||||
|
<p>{{ $t('form_has_errors') }}</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li v-for="e in errors">
|
||||||
|
{{ e }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<ul class="record_actions">
|
||||||
|
<li class="cancel">
|
||||||
|
<a href="#" class="sc-button bt-cancel">
|
||||||
|
{{ $t('action.cancel') }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li v-if="hasSocialActionPicked">
|
||||||
|
<button class="sc-button bt-save" v-show="!isPostingWork" @click="submit">
|
||||||
|
{{ $t('action.save') }}
|
||||||
|
</button>
|
||||||
|
<button class="sc-button bt-save" v-show="isPostingWork" disabled>
|
||||||
|
{{ $t('Save') }}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
|
||||||
|
#awc_create_form {
|
||||||
|
display: grid;
|
||||||
|
grid-template-areas:
|
||||||
|
"picking picking"
|
||||||
|
"start_date end_date"
|
||||||
|
"confirm confirm"
|
||||||
|
;
|
||||||
|
grid-template-columns: 50% 50%;
|
||||||
|
column-gap: 1.5rem;
|
||||||
|
|
||||||
|
#picking {
|
||||||
|
grid-area: picking;
|
||||||
|
}
|
||||||
|
|
||||||
|
#start_date {
|
||||||
|
grid-area: start_date;
|
||||||
|
}
|
||||||
|
|
||||||
|
#end_date {
|
||||||
|
grid-area: end_date;
|
||||||
|
}
|
||||||
|
|
||||||
|
#confirm {
|
||||||
|
grid-area: confirm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapState, mapActions, mapGetters } from 'vuex';
|
||||||
|
import VueMultiselect from 'vue-multiselect';
|
||||||
|
import { dateToISO, ISOToDate } from 'ChillMainAssets/js/date.js';
|
||||||
|
|
||||||
|
const i18n = {
|
||||||
|
messages: {
|
||||||
|
fr: {
|
||||||
|
startDate: "Date de début",
|
||||||
|
endDate: "Date de fin",
|
||||||
|
form_has_errors: "Le formulaire comporte des erreurs",
|
||||||
|
pick_social_issue: "Choisir une problématique sociale",
|
||||||
|
pick_an_action: "Choisir une action d'accompagnement",
|
||||||
|
pick_social_issue_linked_with_action: "Indiquez la problématique sociale liée à l'action d'accompagnement",
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'App',
|
||||||
|
components: {
|
||||||
|
VueMultiselect,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
submit() {
|
||||||
|
this.$store.dispatch('submit');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
i18n,
|
||||||
|
computed: {
|
||||||
|
...mapState([
|
||||||
|
'socialIssues',
|
||||||
|
'socialActionsReachables',
|
||||||
|
'errors',
|
||||||
|
]),
|
||||||
|
...mapGetters([
|
||||||
|
'hasSocialIssuePicked',
|
||||||
|
'hasSocialActionPicked',
|
||||||
|
'isLoadingSocialActions',
|
||||||
|
'isPostingWork',
|
||||||
|
'hasErrors',
|
||||||
|
]),
|
||||||
|
socialIssuePicked: {
|
||||||
|
get() {
|
||||||
|
let s = this.$store.state.socialIssuePicked;
|
||||||
|
|
||||||
|
if (s === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.id;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$store.dispatch('pickSocialIssue', value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
socialActionPicked: {
|
||||||
|
get() {
|
||||||
|
return this.$store.state.socialActionPicked;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$store.commit('setSocialAction', value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
startDate: {
|
||||||
|
get() {
|
||||||
|
let d = this.$store.state.startDate;
|
||||||
|
return dateToISO(d);
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$store.commit('setStartDate', ISOToDate(value));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
endDate: {
|
||||||
|
get() {
|
||||||
|
return dateToISO(this.$store.state.endDate);
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$store.commit('setEndDate', ISOToDate(value));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
@ -0,0 +1,15 @@
|
|||||||
|
import { createApp } from 'vue';
|
||||||
|
import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n';
|
||||||
|
import { store } from './store';
|
||||||
|
import { personMessages } from 'ChillPersonAssets/vuejs/_js/i18n'
|
||||||
|
import App from './App.vue';
|
||||||
|
|
||||||
|
const i18n = _createI18n(personMessages);
|
||||||
|
|
||||||
|
const app = createApp({
|
||||||
|
template: `<app></app>`,
|
||||||
|
})
|
||||||
|
.use(store)
|
||||||
|
.use(i18n)
|
||||||
|
.component('app', App)
|
||||||
|
.mount('#accompanying_course_work_create');
|
@ -0,0 +1,155 @@
|
|||||||
|
|
||||||
|
import { createStore } from 'vuex';
|
||||||
|
import { datetimeToISO } from 'ChillMainAssets/js/date.js';
|
||||||
|
import { findSocialActionsBySocialIssue } from 'ChillPersonAssets/vuejs/_api/SocialWorkSocialAction.js';
|
||||||
|
import { create } from 'ChillPersonAssets/vuejs/_api/AccompanyingCourseWork.js';
|
||||||
|
|
||||||
|
const debug = process.env.NODE_ENV !== 'production';
|
||||||
|
|
||||||
|
const store = createStore({
|
||||||
|
strict: debug,
|
||||||
|
state: {
|
||||||
|
accompanyingCourse: window.accompanyingCourse,
|
||||||
|
socialIssues: window.accompanyingCourse.socialIssues,
|
||||||
|
socialIssuePicked: null,
|
||||||
|
socialActionsReachables: [],
|
||||||
|
socialActionPicked: null,
|
||||||
|
startDate: new Date(),
|
||||||
|
endDate: null,
|
||||||
|
isLoadingSocialActions: false,
|
||||||
|
isPostingWork: false,
|
||||||
|
errors: [],
|
||||||
|
},
|
||||||
|
getters: {
|
||||||
|
hasSocialActionPicked(state) {
|
||||||
|
console.log(state.socialActionPicked);
|
||||||
|
return null !== state.socialActionPicked;
|
||||||
|
},
|
||||||
|
hasSocialIssuePicked(state) {
|
||||||
|
console.log(state.socialIssuePicked);
|
||||||
|
return null !== state.socialIssuePicked;
|
||||||
|
},
|
||||||
|
isLoadingSocialActions(state) {
|
||||||
|
return state.isLoadingSocialActions;
|
||||||
|
},
|
||||||
|
isPostingWork(state) {
|
||||||
|
return state.isPostingWork;
|
||||||
|
},
|
||||||
|
buildPayloadCreate(state) {
|
||||||
|
let payload = {
|
||||||
|
type: 'accompanying_period_work',
|
||||||
|
social_action: {
|
||||||
|
type: 'social_work_social_action',
|
||||||
|
id: state.socialActionPicked.id
|
||||||
|
},
|
||||||
|
startDate: {
|
||||||
|
datetime: datetimeToISO(state.startDate)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (null !== state.endDate) {
|
||||||
|
payload.endDate = {
|
||||||
|
datetime: datetimeToISO(state.endDate)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return payload;
|
||||||
|
},
|
||||||
|
hasErrors(state) {
|
||||||
|
return state.errors.length > 0;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
setSocialActionsReachables(state, actions) {
|
||||||
|
console.log('set social action reachables');
|
||||||
|
console.log(actions);
|
||||||
|
|
||||||
|
state.socialActionsReachables = actions;
|
||||||
|
},
|
||||||
|
setSocialAction(state, socialAction) {
|
||||||
|
console.log('socialAction', socialAction);
|
||||||
|
state.socialActionPicked = socialAction;
|
||||||
|
},
|
||||||
|
setSocialIssue(state, socialIssueId) {
|
||||||
|
if (socialIssueId === null) {
|
||||||
|
state.socialIssuePicked = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state.socialIssuePicked = state.socialIssues
|
||||||
|
.find(e => e.id === socialIssueId);
|
||||||
|
},
|
||||||
|
setIsLoadingSocialActions(state, s) {
|
||||||
|
state.isLoadingSocialActions = s;
|
||||||
|
},
|
||||||
|
setPostingWork(state) {
|
||||||
|
state.isPostingWork = true;
|
||||||
|
},
|
||||||
|
setStartDate(state, date) {
|
||||||
|
state.startDate = date;
|
||||||
|
},
|
||||||
|
setEndDate(state, date) {
|
||||||
|
state.endDate = date;
|
||||||
|
},
|
||||||
|
addErrors(state, { errors, cancel_posting }) {
|
||||||
|
console.log('add errors', errors);
|
||||||
|
state.errors = errors;
|
||||||
|
if (cancel_posting) {
|
||||||
|
state.isPostingWork = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
pickSocialIssue({ commit }, socialIssueId) {
|
||||||
|
console.log('pick social issue');
|
||||||
|
|
||||||
|
commit('setIsLoadingSocialActions', true);
|
||||||
|
commit('setSocialIssue', null);
|
||||||
|
commit('setSocialActionsReachables', []);
|
||||||
|
|
||||||
|
findSocialActionsBySocialIssue(socialIssueId).then(
|
||||||
|
(response) => {
|
||||||
|
console.log(response);
|
||||||
|
console.log(response.results);
|
||||||
|
commit('setSocialIssue', socialIssueId);
|
||||||
|
commit('setSocialActionsReachables', response.results);
|
||||||
|
commit('setIsLoadingSocialActions', false);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
submit({ commit, getters, state }) {
|
||||||
|
console.log('submit');
|
||||||
|
let
|
||||||
|
payload = getters.buildPayloadCreate,
|
||||||
|
errors = [];
|
||||||
|
|
||||||
|
commit('setPostingWork');
|
||||||
|
|
||||||
|
create(state.accompanyingCourse.id, payload)
|
||||||
|
.then( ({status, data}) => {
|
||||||
|
console.log('created return', { status, data});
|
||||||
|
if (status === 200) {
|
||||||
|
console.log('created, nothing to do here any more. Bye-bye!');
|
||||||
|
window.location.assign(`/fr/person/accompanying-period/work/${data.id}/edit`);
|
||||||
|
} else if (status === 422) {
|
||||||
|
console.log(data);
|
||||||
|
for (let i in data.violations) {
|
||||||
|
console.log(i);
|
||||||
|
console.log(data.violations[i].title);
|
||||||
|
errors.push(data.violations[i].title);
|
||||||
|
}
|
||||||
|
console.log('errors after reseponse handling', errors);
|
||||||
|
console.log({errors, cancel_posting: true});
|
||||||
|
commit('addErrors', { errors, cancel_posting: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
export { store };
|
@ -0,0 +1,30 @@
|
|||||||
|
const create = (accompanying_period_id, payload) => {
|
||||||
|
const url = `/api/1.0/person/accompanying-course/${accompanying_period_id}/work.json`;
|
||||||
|
let status;
|
||||||
|
console.log('create', payload);
|
||||||
|
|
||||||
|
return fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(payload),
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (response.ok || response.status === 422) {
|
||||||
|
status = response.status;
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error("Error while retrieving social actions: " + response.status +
|
||||||
|
" " + response.statusText);
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
resolve({ status, data });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export { create };
|
@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
const findSocialActionsBySocialIssue = (id) => {
|
||||||
|
const url = `/api/1.0/person/social/social-action/by-social-issue/${id}.json`;
|
||||||
|
|
||||||
|
return fetch(url)
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Error while retrieving social actions " + response.status
|
||||||
|
+ " " + response.statusText);
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
throw err
|
||||||
|
})
|
||||||
|
;
|
||||||
|
};
|
||||||
|
|
||||||
|
export {
|
||||||
|
findSocialActionsBySocialIssue
|
||||||
|
};
|
@ -0,0 +1,24 @@
|
|||||||
|
{% extends '@ChillPerson/AccompanyingCourse/layout.html.twig' %}
|
||||||
|
|
||||||
|
{% block title 'accompanying_course_work.Create accompanying course work'|trans %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>{{ block('title') }}</h1>
|
||||||
|
|
||||||
|
<div id="accompanying_course_work_create"></div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block js %}
|
||||||
|
<script type="text/javascript">
|
||||||
|
window.accompanyingCourse = {{ json|json_encode|raw }};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{{ encore_entry_script_tags('accompanying_course_work_create') }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block css %}
|
||||||
|
{{ parent() }}
|
||||||
|
{{ encore_entry_link_tags('accompanying_course_work_create') }}
|
||||||
|
{% endblock %}
|
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\Serializer\Normalizer;
|
||||||
|
|
||||||
|
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||||
|
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
|
||||||
|
|
||||||
|
|
||||||
|
class SocialActionNormalizer implements NormalizerInterface, NormalizerAwareInterface
|
||||||
|
{
|
||||||
|
use NormalizerAwareTrait;
|
||||||
|
|
||||||
|
private SocialActionRender $render;
|
||||||
|
|
||||||
|
public function __construct(SocialActionRender $render)
|
||||||
|
{
|
||||||
|
$this->render = $render;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function normalize($socialAction, string $format = null, array $context = [])
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $socialAction->getId(),
|
||||||
|
'type' => 'social_work_social_action',
|
||||||
|
'text' => $this->render->renderString($socialAction, []),
|
||||||
|
'parent' => $this->normalizer->normalize($socialAction->getParent()),
|
||||||
|
'desactivationDate' => $this->normalizer->normalize($socialAction->getDesactivationDate()),
|
||||||
|
'title' => $socialAction->getTitle()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function supportsNormalization($data, string $format = null)
|
||||||
|
{
|
||||||
|
return $data instanceof SocialAction;
|
||||||
|
}
|
||||||
|
}
|
@ -798,6 +798,55 @@ paths:
|
|||||||
422:
|
422:
|
||||||
description: "object with validation errors"
|
description: "object with validation errors"
|
||||||
|
|
||||||
|
/1.0/person/accompanying-course/{id}/work.json:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- person
|
||||||
|
summary: "Add a work (AccompanyingPeriodwork) to the accompanying course"
|
||||||
|
parameters:
|
||||||
|
- name: id
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: The accompanying period's id
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: integer
|
||||||
|
minimum: 1
|
||||||
|
requestBody:
|
||||||
|
description: "A new work"
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- 'accompanying_period_work'
|
||||||
|
startDate:
|
||||||
|
$ref: '#/components/schemas/Date'
|
||||||
|
endDate:
|
||||||
|
$ref: '#/components/schemas/Date'
|
||||||
|
examples:
|
||||||
|
create a work:
|
||||||
|
value:
|
||||||
|
type: accompanying_period_work
|
||||||
|
social_action:
|
||||||
|
id: 0
|
||||||
|
type: social_work_social_action
|
||||||
|
startDate:
|
||||||
|
datetime: 2021-06-20T15:00:00+0200
|
||||||
|
responses:
|
||||||
|
401:
|
||||||
|
description: "Unauthorized"
|
||||||
|
404:
|
||||||
|
description: "Not found"
|
||||||
|
200:
|
||||||
|
description: "OK"
|
||||||
|
422:
|
||||||
|
description: "object with validation errors"
|
||||||
|
|
||||||
/1.0/person/accompanying-course/{id}/confirm.json:
|
/1.0/person/accompanying-course/{id}/confirm.json:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
|
@ -13,4 +13,5 @@ module.exports = function(encore, entries)
|
|||||||
encore.addEntry('household_members_editor', __dirname + '/Resources/public/vuejs/HouseholdMembersEditor/index.js');
|
encore.addEntry('household_members_editor', __dirname + '/Resources/public/vuejs/HouseholdMembersEditor/index.js');
|
||||||
encore.addEntry('vue_accourse', __dirname + '/Resources/public/vuejs/AccompanyingCourse/index.js');
|
encore.addEntry('vue_accourse', __dirname + '/Resources/public/vuejs/AccompanyingCourse/index.js');
|
||||||
encore.addEntry('household_edit_metadata', __dirname + '/Resources/public/modules/household_edit_metadata/index.js');
|
encore.addEntry('household_edit_metadata', __dirname + '/Resources/public/modules/household_edit_metadata/index.js');
|
||||||
|
encore.addEntry('accompanying_course_work_create', __dirname + '/Resources/public/vuejs/AccompanyingCourseWorkCreate/index.js');
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\Migrations\Person;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add updated information to accompanying period work
|
||||||
|
*/
|
||||||
|
final class Version20210620143757 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return 'add updated information to accompanying period work';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('ALTER TABLE chill_person_accompanying_period_work ADD updatedAt TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_accompanying_period_work ADD updatedBy_id INT NOT NULL');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_accompanying_period_work ALTER createdat TYPE TIMESTAMP(0) WITHOUT TIME ZONE');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_accompanying_period_work ALTER createdat DROP DEFAULT');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_accompanying_period_work ALTER startdate TYPE DATE');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_accompanying_period_work ALTER startdate DROP DEFAULT');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_accompanying_period_work ALTER enddate TYPE DATE');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_accompanying_period_work ALTER enddate DROP NOT NULL');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_accompanying_period_work ALTER enddate SET DEFAULT NULL');
|
||||||
|
$this->addSql('COMMENT ON COLUMN chill_person_accompanying_period_work.updatedAt IS \'(DC2Type:datetime_immutable)\'');
|
||||||
|
$this->addSql('COMMENT ON COLUMN chill_person_accompanying_period_work.createdAt IS \'(DC2Type:datetime_immutable)\'');
|
||||||
|
$this->addSql('COMMENT ON COLUMN chill_person_accompanying_period_work.startDate IS \'(DC2Type:datetime_immutable)\'');
|
||||||
|
$this->addSql('COMMENT ON COLUMN chill_person_accompanying_period_work.endDate IS \'(DC2Type:datetime_immutable)\'');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('ALTER TABLE chill_person_accompanying_period_work DROP updatedAt');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_accompanying_period_work DROP updatedBy_id');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_accompanying_period_work ALTER createdAt TYPE TIMESTAMP(0) WITHOUT TIME ZONE');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_accompanying_period_work ALTER createdAt DROP DEFAULT');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_accompanying_period_work ALTER startDate TYPE TIMESTAMP(0) WITHOUT TIME ZONE');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_accompanying_period_work ALTER startDate DROP DEFAULT');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_accompanying_period_work ALTER endDate TYPE TIMESTAMP(0) WITHOUT TIME ZONE');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_accompanying_period_work ALTER endDate DROP DEFAULT');
|
||||||
|
$this->addSql('COMMENT ON COLUMN chill_person_accompanying_period_work.createdat IS NULL');
|
||||||
|
$this->addSql('COMMENT ON COLUMN chill_person_accompanying_period_work.startdate IS NULL');
|
||||||
|
$this->addSql('COMMENT ON COLUMN chill_person_accompanying_period_work.enddate IS NULL');
|
||||||
|
}
|
||||||
|
}
|
@ -328,3 +328,8 @@ Members: Membres
|
|||||||
Addresses: Adresses
|
Addresses: Adresses
|
||||||
Move household: Nouveau déménagement
|
Move household: Nouveau déménagement
|
||||||
Addresses history for household: Historique des adresses
|
Addresses history for household: Historique des adresses
|
||||||
|
|
||||||
|
# accompanying course work
|
||||||
|
accompanying_course_work:
|
||||||
|
Create accompanying course work: Créer une action d'accompagnement
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user