Issue336 internal create action fixes

This commit is contained in:
LenaertsJ 2021-12-14 18:48:31 +00:00 committed by Julien Fastré
parent 45bcb27b79
commit 264bd76461
14 changed files with 154 additions and 146 deletions

View File

@ -110,6 +110,34 @@ class AccompanyingCourseController extends Controller
]); ]);
} }
/**
* Comments page of Accompanying Course section.
*
* @Route("/{_locale}/parcours/{accompanying_period_id}/comments", name="chill_person_accompanying_period_comment_list")
* @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"})
*/
public function commentAction(AccompanyingPeriod $accompanyingCourse, Request $request): Response
{
$comment = new AccompanyingPeriod\Comment();
$form = $this->createForm(AccompanyingCourseCommentType::class, $comment, []);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($comment);
$em->flush();
return $this->redirectToRoute($route);
}
return $this->render('@ChillPerson/AccompanyingCourse/comment_list.html.twig', [
'accompanyingCourse' => $accompanyingCourse,
'form' => $form->createView(),
]);
}
/** /**
* Edit page of Accompanying Course section. * Edit page of Accompanying Course section.
* *
@ -217,35 +245,4 @@ class AccompanyingCourseController extends Controller
'accompanying_period_id' => $period->getId(), 'accompanying_period_id' => $period->getId(),
]); ]);
} }
/**
* Comments page of Accompanying Course section.
*
* @Route("/{_locale}/parcours/{accompanying_period_id}/comments", name="chill_person_accompanying_period_comment_list")
* @ParamConverter("accompanyingCourse", options={"id": "accompanying_period_id"})
*/
public function commentAction(AccompanyingPeriod $accompanyingCourse, Request $request): Response
{
$comment = new AccompanyingPeriod\Comment();
$form = $this->createForm(AccompanyingCourseCommentType::class, $comment, []);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($comment);
$em->flush();
return $this->redirectToRoute($route);
}
return $this->render('@ChillPerson/AccompanyingCourse/comment_list.html.twig', [
'accompanyingCourse' => $accompanyingCourse,
'form' => $form->createView()
]);
}
} }

View File

@ -95,7 +95,7 @@ class LoadAccompanyingPeriodWork extends \Doctrine\Bundle\FixturesBundle\Fixture
// 1 of 10, force an evaluation // 1 of 10, force an evaluation
if (0 === $i % 10) { if (0 === $i % 10) {
$evaluation = $this->getRandomEvaluation(); $evaluation = $this->getRandomEvaluation();
$action = $evaluation->getSocialAction(); $action = $evaluation->getSocialActions()->first();
$issue = $action->getIssue(); $issue = $action->getIssue();
$period->addSocialIssue($issue); $period->addSocialIssue($issue);

View File

@ -180,14 +180,6 @@ class AccompanyingPeriod implements
*/ */
private ?int $id = null; private ?int $id = null;
/**
* @ORM\ManyToOne(
* targetEntity=Comment::class
* )
* @Groups({"read"})
*/
private ?Comment $pinnedComment = null;
/** /**
* @var string * @var string
* @ORM\Column(type="string", nullable=true) * @ORM\Column(type="string", nullable=true)
@ -229,6 +221,14 @@ class AccompanyingPeriod implements
*/ */
private ?Person $personLocation = null; private ?Person $personLocation = null;
/**
* @ORM\ManyToOne(
* targetEntity=Comment::class
* )
* @Groups({"read"})
*/
private ?Comment $pinnedComment = null;
/** /**
* @ORM\Column(type="text") * @ORM\Column(type="text")
* @Groups({"read", "write"}) * @Groups({"read", "write"})
@ -603,14 +603,6 @@ class AccompanyingPeriod implements
return $this->id; return $this->id;
} }
/**
* @Groups({"read"})
*/
public function getPinnedComment(): ?Comment
{
return $this->pinnedComment;
}
public function getIntensity(): ?string public function getIntensity(): ?string
{ {
return $this->intensity; return $this->intensity;
@ -738,6 +730,14 @@ class AccompanyingPeriod implements
); );
} }
/**
* @Groups({"read"})
*/
public function getPinnedComment(): ?Comment
{
return $this->pinnedComment;
}
/** /**
* @return Collection|SocialAction[] All the descendant social actions of all * @return Collection|SocialAction[] All the descendant social actions of all
* the descendants of the entity * the descendants of the entity
@ -1027,24 +1027,6 @@ class AccompanyingPeriod implements
return $this; return $this;
} }
/**
* @Groups({"write"})
*/
public function setPinnedComment(?Comment $comment = null): self
{
if (null !== $this->pinnedComment) {
$this->removeComment($this->pinnedComment);
}
if ($comment instanceof Comment) {
$this->addComment($comment);
}
$this->pinnedComment = $comment;
return $this;
}
public function setIntensity(string $intensity): self public function setIntensity(string $intensity): self
{ {
$this->intensity = $intensity; $this->intensity = $intensity;
@ -1083,6 +1065,24 @@ class AccompanyingPeriod implements
return $this; return $this;
} }
/**
* @Groups({"write"})
*/
public function setPinnedComment(?Comment $comment = null): self
{
if (null !== $this->pinnedComment) {
$this->removeComment($this->pinnedComment);
}
if ($comment instanceof Comment) {
$this->addComment($comment);
}
$this->pinnedComment = $comment;
return $this;
}
public function setRemark(?string $remark = null): self public function setRemark(?string $remark = null): self
{ {
$this->remark = (string) $remark; $this->remark = (string) $remark;

View File

@ -112,6 +112,11 @@ class Comment implements TrackCreationInterface, TrackUpdateInterface
return $this->updatedBy; return $this->updatedBy;
} }
public function isPinned(): bool
{
return $this->getAccompanyingPeriod()->getPinnedComment() === $this;
}
public function setAccompanyingPeriod(?AccompanyingPeriod $accompanyingPeriod): self public function setAccompanyingPeriod(?AccompanyingPeriod $accompanyingPeriod): self
{ {
$this->accompanyingPeriod = $accompanyingPeriod; $this->accompanyingPeriod = $accompanyingPeriod;
@ -158,9 +163,4 @@ class Comment implements TrackCreationInterface, TrackUpdateInterface
return $this; return $this;
} }
public function isPinned(): bool
{
return $this->getAccompanyingPeriod()->getPinnedComment() === $this;
}
} }

View File

@ -244,7 +244,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
* @Assert\Date( * @Assert\Date(
* groups={"general", "creation"} * groups={"general", "creation"}
* ) * )
* @Assert\GreaterThan(propertyPath="birthDate") * @Assert\GreaterThanOrEqual(propertyPath="birthdate")
* @Assert\LessThanOrEqual("today") * @Assert\LessThanOrEqual("today")
*/ */
private ?DateTimeImmutable $deathdate = null; private ?DateTimeImmutable $deathdate = null;

View File

@ -91,6 +91,11 @@ class Evaluation
return $this->notificationDelay; return $this->notificationDelay;
} }
public function getSocialActions(): Collection
{
return $this->socialActions;
}
public function getTitle(): array public function getTitle(): array
{ {
return $this->title; return $this->title;

View File

@ -1,4 +1,5 @@
<?php <?php
/** /**
* Chill is a software for social workers * Chill is a software for social workers
* *
@ -19,8 +20,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
class AccompanyingCourseCommentType extends AbstractType class AccompanyingCourseCommentType extends AbstractType
{ {
/** /**
* @param FormBuilderInterface $builder
* @param array $options
* @return void * @return void
*/ */
public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options)
@ -29,7 +28,6 @@ class AccompanyingCourseCommentType extends AbstractType
} }
/** /**
* @param OptionsResolver $resolver
* @return void * @return void
*/ */
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver)

View File

@ -80,7 +80,7 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface
'accompanying_period_id' => $period->getId(), 'accompanying_period_id' => $period->getId(),
], ]) ], ])
->setExtras(['order' => 50]); ->setExtras(['order' => 50]);
*/ */
$workflow = $this->registry->get($period, 'accompanying_period_lifecycle'); $workflow = $this->registry->get($period, 'accompanying_period_lifecycle');

View File

@ -8,10 +8,10 @@
<div id="picking"> <div id="picking">
<p>{{ $t('pick_social_issue_linked_with_action') }}</p> <p>{{ $t('pick_social_issue_linked_with_action') }}</p>
<div v-for="si in socialIssues"> <div v-for="si in socialIssues">
<input type="radio" checked v-bind:value="si.id" name="socialIssue" v-model="socialIssuePicked"><span class="badge bg-chill-l-gray text-dark">{{ si.text }}</span> <input type="radio" v-bind:value="si.id" name="socialIssue" v-model="socialIssuePicked"><span class="badge bg-chill-l-gray text-dark">{{ si.text }}</span>
</div> </div>
<div class="my-3"> <div class="my-3">
<div class="col-8"> <div class="col-11">
<vue-multiselect <vue-multiselect
name="otherIssues" name="otherIssues"
label="text" label="text"
@ -35,7 +35,7 @@
</div> </div>
<div v-if="hasSocialIssuePicked"> <div v-if="hasSocialIssuePicked">
<h2>{{ $t('pick_an_action') }}</h2> <h2>{{ $t('pick_an_action') }}</h2>
<div class="col-8"> <div class="col-11">
<vue-multiselect <vue-multiselect
v-model="socialActionPicked" v-model="socialActionPicked"
label="text" label="text"
@ -77,7 +77,7 @@
<p>{{ $t('form_has_errors') }}</p> <p>{{ $t('form_has_errors') }}</p>
<ul> <ul>
<li v-for="e in errors"> <li v-for="e in errors" :key="e.id">
{{ e }} {{ e }}
</li> </li>
</ul> </ul>
@ -120,6 +120,7 @@ const i18n = {
endDate: "Date de fin", endDate: "Date de fin",
form_has_errors: "Le formulaire comporte des erreurs", form_has_errors: "Le formulaire comporte des erreurs",
pick_social_issue: "Choisir une problématique sociale", pick_social_issue: "Choisir une problématique sociale",
pick_other_social_issue: "Veuillez choisir un autre problématique",
pick_an_action: "Choisir une action d'accompagnement", 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", pick_social_issue_linked_with_action: "Indiquez la problématique sociale liée à l'action d'accompagnement",
persons_involved: "Usagers concernés", persons_involved: "Usagers concernés",
@ -178,12 +179,10 @@ export default {
personsPicked: { personsPicked: {
get() { get() {
let s = this.$store.state.personsPicked.map(p => p.id); let s = this.$store.state.personsPicked.map(p => p.id);
// console.log('persons picked', s);
return s; return s;
}, },
set(v) { set(v) {
// console.log('persons picked', v);
this.$store.commit('setPersonsPickedIds', v); this.$store.commit('setPersonsPickedIds', v);
} }
}, },
@ -226,6 +225,11 @@ export default {
this.$store.commit('setEndDate', ISOToDate(value)); this.$store.commit('setEndDate', ISOToDate(value));
} }
}, },
setSocialIssue: {
set() {
this.$store.dispatch('setSocialIssue', socialIssues[socialIssues.length - 1])
}
}
} }
} }

View File

@ -31,7 +31,6 @@ const store = createStore({
return null !== state.socialActionPicked; return null !== state.socialActionPicked;
}, },
hasSocialIssuePicked(state) { hasSocialIssuePicked(state) {
console.log(state.socialIssuePicked);
return null !== state.socialIssuePicked; return null !== state.socialIssuePicked;
}, },
isLoadingSocialActions(state) { isLoadingSocialActions(state) {
@ -74,36 +73,27 @@ const store = createStore({
}, },
mutations: { mutations: {
setSocialActionsReachables(state, actions) { setSocialActionsReachables(state, actions) {
// console.log('set social action reachables');
// console.log(actions);
state.socialActionsReachables = actions; state.socialActionsReachables = actions;
}, },
setSocialAction(state, socialAction) { setSocialAction(state, socialAction) {
// console.log('socialAction', socialAction);
state.socialActionPicked = socialAction; state.socialActionPicked = socialAction;
}, },
setSocialIssue(state, socialIssueId) { setSocialIssue(state, socialIssueId) {
// console.log('set social issue', socialIssueId);
if (socialIssueId === null) { if (socialIssueId === null) {
state.socialIssuePicked = null; state.socialIssuePicked = null;
} else { } else {
let mapped = state.socialIssues let mapped = state.socialIssues
.find(e => e.id === socialIssueId); .find(e => e.id === socialIssueId);
state.socialIssuePicked = mapped; state.socialIssuePicked = mapped;
// console.log('social issue setted', state.socialIssuePicked);
} }
}, },
addIssueInList(state, issue) { addIssueInList(state, issue) {
//console.log('add issue list', issue.id);
state.socialIssues.push(issue); state.socialIssues.push(issue);
}, },
updateIssuesOther(state, payload) { updateIssuesOther(state, payload) {
//console.log('update issues other');
state.socialIssuesOther = payload; state.socialIssuesOther = payload;
}, },
removeIssueInOther(state, issue) { removeIssueInOther(state, issue) {
//console.log('remove issue other', issue.id);
state.socialIssuesOther = state.socialIssuesOther.filter( state.socialIssuesOther = state.socialIssuesOther.filter(
(i) => i.id !== issue.id (i) => i.id !== issue.id
); );
@ -124,12 +114,12 @@ const store = createStore({
state.endDate = date; state.endDate = date;
}, },
setPersonsPickedIds(state, ids) { setPersonsPickedIds(state, ids) {
console.log('persons ids', ids);
state.personsPicked = state.personsReachables state.personsPicked = state.personsReachables
.filter(p => ids.includes(p.id)) .filter(p => ids.includes(p.id))
}, },
addErrors(state, { errors, cancel_posting }) { addErrors(state, { errors, cancel_posting }) {
console.log('add errors', errors);
state.errors = errors; state.errors = errors;
if (cancel_posting) { if (cancel_posting) {
state.isPostingWork = false; state.isPostingWork = false;
@ -138,8 +128,6 @@ const store = createStore({
}, },
actions: { actions: {
pickSocialIssue({ commit }, socialIssueId) { pickSocialIssue({ commit }, socialIssueId) {
console.log('pick social issue');
commit('setIsLoadingSocialActions', true); commit('setIsLoadingSocialActions', true);
commit('setSocialAction', null); commit('setSocialAction', null);
commit('setSocialActionsReachables', []); commit('setSocialActionsReachables', []);

View File

@ -60,32 +60,6 @@ final class AccompanyingPeriodTest extends \PHPUnit\Framework\TestCase
$this->assertFalse($period->isClosingAfterOpening()); $this->assertFalse($period->isClosingAfterOpening());
} }
public function testPinnedComment()
{
$period = new AccompanyingPeriod(new DateTime());
$comment = new Comment();
$replacingComment = new Comment();
$period->setPinnedComment(null);
$this->assertNull($period->getPinnedComment());
$period->setPinnedComment($comment);
$this->assertSame($period->getPinnedComment(), $comment);
$this->assertSame($period, $comment->getAccompanyingPeriod());
$this->assertEquals(0, count($period->getComments()), 'The initial comment should not appears in the list of comments');
$period->setPinnedComment($replacingComment);
$this->assertSame($period->getPinnedComment(), $replacingComment);
$this->assertSame($period, $replacingComment->getAccompanyingPeriod());
$this->assertEquals(0, count($period->getComments()), 'The initial comment should not appears in the list of comments');
$this->assertNull($comment->getAccompanyingPeriod());
$period->setPinnedComment(null);
$this->assertNull($period->getPinnedComment());
$this->assertNull($replacingComment->getAccompanyingPeriod());
$this->assertEquals(0, count($period->getComments()), 'The initial comment should not appears in the list of comments');
}
public function testIsClosed() public function testIsClosed()
{ {
$period = new AccompanyingPeriod(new DateTime()); $period = new AccompanyingPeriod(new DateTime());
@ -145,6 +119,32 @@ final class AccompanyingPeriodTest extends \PHPUnit\Framework\TestCase
$this->assertEquals(1, $period->getParticipationsContainsPerson($person4)->count()); $this->assertEquals(1, $period->getParticipationsContainsPerson($person4)->count());
} }
public function testPinnedComment()
{
$period = new AccompanyingPeriod(new DateTime());
$comment = new Comment();
$replacingComment = new Comment();
$period->setPinnedComment(null);
$this->assertNull($period->getPinnedComment());
$period->setPinnedComment($comment);
$this->assertSame($period->getPinnedComment(), $comment);
$this->assertSame($period, $comment->getAccompanyingPeriod());
$this->assertEquals(0, count($period->getComments()), 'The initial comment should not appears in the list of comments');
$period->setPinnedComment($replacingComment);
$this->assertSame($period->getPinnedComment(), $replacingComment);
$this->assertSame($period, $replacingComment->getAccompanyingPeriod());
$this->assertEquals(0, count($period->getComments()), 'The initial comment should not appears in the list of comments');
$this->assertNull($comment->getAccompanyingPeriod());
$period->setPinnedComment(null);
$this->assertNull($period->getPinnedComment());
$this->assertNull($replacingComment->getAccompanyingPeriod());
$this->assertEquals(0, count($period->getComments()), 'The initial comment should not appears in the list of comments');
}
public function testRequestor() public function testRequestor()
{ {
$period = new AccompanyingPeriod(new DateTime()); $period = new AccompanyingPeriod(new DateTime());

View File

@ -1,5 +1,12 @@
<?php <?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); declare(strict_types=1);
namespace Chill\Migrations\Person; namespace Chill\Migrations\Person;
@ -9,10 +16,18 @@ use Doctrine\Migrations\AbstractMigration;
/** /**
* Auto-generated Migration: Please modify to your needs! * Auto-generated Migration: Please modify to your needs!
* @author Mathieu Jaumotte mathieu.jaumotte@champs-libres.coop
*/ */
final class Version20211213150253 extends AbstractMigration final class Version20211213150253 extends AbstractMigration
{ {
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_person_accompanying_period DROP CONSTRAINT FK_E260A868B0804E90');
$this->addSql('DROP INDEX IDX_E260A868B0804E90');
$this->addSql('ALTER TABLE chill_person_accompanying_period RENAME COLUMN pinnedcomment_id TO initialcomment_id');
$this->addSql('ALTER TABLE chill_person_accompanying_period ADD CONSTRAINT fk_e260a8683111d50b FOREIGN KEY (initialcomment_id) REFERENCES chill_person_accompanying_period_comment (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('CREATE INDEX idx_e260a8683111d50b ON chill_person_accompanying_period (initialcomment_id)');
}
public function getDescription(): string public function getDescription(): string
{ {
return 'rename initialComment attribute to pinnedComment'; return 'rename initialComment attribute to pinnedComment';
@ -26,13 +41,4 @@ final class Version20211213150253 extends AbstractMigration
$this->addSql('ALTER TABLE chill_person_accompanying_period ADD CONSTRAINT FK_E260A868B0804E90 FOREIGN KEY (pinnedcomment_id) REFERENCES chill_person_accompanying_period_comment (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); $this->addSql('ALTER TABLE chill_person_accompanying_period ADD CONSTRAINT FK_E260A868B0804E90 FOREIGN KEY (pinnedcomment_id) REFERENCES chill_person_accompanying_period_comment (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('CREATE INDEX IDX_E260A868B0804E90 ON chill_person_accompanying_period (pinnedcomment_id)'); $this->addSql('CREATE INDEX IDX_E260A868B0804E90 ON chill_person_accompanying_period (pinnedcomment_id)');
} }
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_person_accompanying_period DROP CONSTRAINT FK_E260A868B0804E90');
$this->addSql('DROP INDEX IDX_E260A868B0804E90');
$this->addSql('ALTER TABLE chill_person_accompanying_period RENAME COLUMN pinnedcomment_id TO initialcomment_id');
$this->addSql('ALTER TABLE chill_person_accompanying_period ADD CONSTRAINT fk_e260a8683111d50b FOREIGN KEY (initialcomment_id) REFERENCES chill_person_accompanying_period_comment (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('CREATE INDEX idx_e260a8683111d50b ON chill_person_accompanying_period (initialcomment_id)');
}
} }

View File

@ -219,7 +219,6 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
private ?string $telephone = null; private ?string $telephone = null;
/** /**
* @var array|null
* @ORM\Column(name="types", type="json", nullable=true) * @ORM\Column(name="types", type="json", nullable=true)
*/ */
private ?array $thirdPartyTypes = []; private ?array $thirdPartyTypes = [];

View File

@ -1,13 +1,25 @@
<?php <?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\ThirdPartyBundle\Test\Serializer\Normalizer; namespace Chill\ThirdPartyBundle\Test\Serializer\Normalizer;
use Chill\ThirdPartyBundle\Entity\ThirdParty; use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
class ThirdPartyJsonDenormalizerTest extends KernelTestCase /**
* @internal
* @coversNothing
*/
final class ThirdPartyJsonDenormalizerTest extends KernelTestCase
{ {
private DenormalizerInterface $normalizer; private DenormalizerInterface $normalizer;
@ -20,18 +32,18 @@ class ThirdPartyJsonDenormalizerTest extends KernelTestCase
public function testDenormalizeContact() public function testDenormalizeContact()
{ {
$str = <<<JSON $str = <<<'JSON'
{ {
"type": "thirdparty", "type": "thirdparty",
"name": "badaboum", "name": "badaboum",
"email": "badaboum@email.com", "email": "badaboum@email.com",
"telephone": "+32486540660", "telephone": "+32486540660",
"kind": "contact" "kind": "contact"
} }
JSON; JSON;
$actual = $this->normalizer->denormalize(json_decode($str, true), ThirdParty::class, 'json', [ $actual = $this->normalizer->denormalize(json_decode($str, true), ThirdParty::class, 'json', [
'groups' => ['write'] 'groups' => ['write'],
]); ]);
$this->assertInstanceOf(ThirdParty::class, $actual); $this->assertInstanceOf(ThirdParty::class, $actual);
@ -39,5 +51,4 @@ class ThirdPartyJsonDenormalizerTest extends KernelTestCase
$this->assertEquals('badaboum@email.com', $actual->getEmail()); $this->assertEquals('badaboum@email.com', $actual->getEmail());
$this->assertEquals(ThirdParty::KIND_CONTACT, $actual->getKind()); $this->assertEquals(ThirdParty::KIND_CONTACT, $actual->getKind());
} }
} }