Merge remote-tracking branch 'origin/master' into issue471_activity_socialissue-action

This commit is contained in:
2022-04-26 20:29:07 +02:00
116 changed files with 2720 additions and 815 deletions

View File

@@ -13,10 +13,10 @@ namespace Chill\PersonBundle\AccompanyingPeriod\Events;
use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Entity\Notification;
use Chill\MainBundle\Notification\NotificationPersisterInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Event\Person\PersonAddressMoveEvent;
use DateTimeImmutable;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Templating\EngineInterface;
@@ -26,7 +26,7 @@ class PersonAddressMoveEventSubscriber implements EventSubscriberInterface
{
private EngineInterface $engine;
private EntityManagerInterface $entityManager;
private NotificationPersisterInterface $notificationPersister;
private Security $security;
@@ -34,12 +34,12 @@ class PersonAddressMoveEventSubscriber implements EventSubscriberInterface
public function __construct(
EngineInterface $engine,
EntityManagerInterface $entityManager,
NotificationPersisterInterface $notificationPersister,
Security $security,
TranslatorInterface $translator
) {
$this->engine = $engine;
$this->entityManager = $entityManager;
$this->notificationPersister = $notificationPersister;
$this->security = $security;
$this->translator = $translator;
}
@@ -87,7 +87,7 @@ class PersonAddressMoveEventSubscriber implements EventSubscriberInterface
'period' => $period,
]));
$this->entityManager->persist($notification);
$this->notificationPersister->persist($notification);
}
}
}

View File

@@ -13,8 +13,8 @@ namespace Chill\PersonBundle\AccompanyingPeriod\Events;
use Chill\MainBundle\Entity\Notification;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Notification\NotificationPersisterInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\Event\LifecycleEventArgs;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Security;
@@ -24,20 +24,20 @@ use Symfony\Contracts\Translation\TranslatorInterface;
class UserRefEventSubscriber implements EventSubscriberInterface
{
private EntityManagerInterface $em;
private EngineInterface $engine;
private NotificationPersisterInterface $notificationPersister;
private Security $security;
private TranslatorInterface $translator;
public function __construct(Security $security, TranslatorInterface $translator, EngineInterface $engine, EntityManagerInterface $em)
public function __construct(Security $security, TranslatorInterface $translator, EngineInterface $engine, NotificationPersisterInterface $notificationPersister)
{
$this->security = $security;
$this->translator = $translator;
$this->engine = $engine;
$this->em = $em;
$this->notificationPersister = $notificationPersister;
}
public static function getSubscribedEvents()
@@ -58,16 +58,13 @@ class UserRefEventSubscriber implements EventSubscriberInterface
public function postUpdate(AccompanyingPeriod $period, LifecycleEventArgs $args): void
{
if ($period->hasPreviousUser()
if ($period->isChangedUser()
&& $period->getUser() !== $this->security->getUser()
&& null !== $period->getUser()
&& $period->getStep() !== AccompanyingPeriod::STEP_DRAFT
) {
$this->generateNotificationToUser($period);
}
// we are just out of a flush operation. Launch a new one
$this->em->flush();
}
private function generateNotificationToUser(AccompanyingPeriod $period)
@@ -89,7 +86,7 @@ class UserRefEventSubscriber implements EventSubscriberInterface
))
->addAddressee($period->getUser());
$this->em->persist($notification);
$this->notificationPersister->persist($notification);
}
private function onPeriodConfirmed(AccompanyingPeriod $period)

View File

@@ -102,7 +102,6 @@ class HouseholdApiController extends ApiController
$event
->setPreviousAddress($household->getPreviousAddressOf($address))
->setNextAddress($address);
dump($event);
$this->eventDispatcher->dispatch($event);
}

View File

@@ -12,13 +12,16 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Form\Type\AddressDateType;
use Chill\PersonBundle\Entity\Household\Household;
use Chill\PersonBundle\Form\HouseholdType;
use Chill\PersonBundle\Repository\Household\PositionRepository;
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
use Chill\PersonBundle\Security\Authorization\HouseholdVoter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
@@ -186,6 +189,62 @@ class HouseholdController extends AbstractController
);
}
/**
* @Route(
* "/{household_id}/address/edit_valid_from",
* name="chill_person_household_address_valid_from_edit",
* methods={"GET", "HEAD", "POST"}
* )
* @ParamConverter("household", options={"id": "household_id"})
*/
public function addressValidFromEdit(Request $request, Household $household)
{
$this->denyAccessUnlessGranted(HouseholdVoter::EDIT, $household);
if (!$request->query->has('address_id')) {
throw new BadRequestException('parameter address_id is missing');
}
$address_id = $request->query->getInt('address_id');
// loop over adresses of the household, to be sure that the household is associated
// to the edited address
$address = null;
foreach ($household->getAddresses() as $householdAddress) {
if ($householdAddress->getId() === $address_id) {
$address = $householdAddress;
}
}
if (null === $address) {
throw new BadRequestException('The edited address does not belongs to the household');
}
$form = $this->createForm(AddressDateType::class, $address, []);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$household->makeAddressConsistent();
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('chill_person_household_addresses', [
'household_id' => $household->getId(),
]);
}
return $this->render(
'@ChillPerson/Household/address_valid_from_edit.html.twig',
[
'household' => $household,
'address' => $address,
'form' => $form->createView(),
]
);
}
/**
* @Route(
* "/{household_id}/members/metadata/edit",

View File

@@ -361,6 +361,8 @@ class AccompanyingPeriod implements
*/
private Collection $userHistories;
private bool $userIsChanged = false;
/**
* Temporary field, which is filled when the user is changed.
*
@@ -978,6 +980,11 @@ class AccompanyingPeriod implements
return null !== $this->userPrevious;
}
public function isChangedUser(): bool
{
return $this->userIsChanged && $this->user !== $this->userPrevious;
}
/**
* Returns true if the closing date is after the opening date.
*/
@@ -1103,6 +1110,14 @@ class AccompanyingPeriod implements
$this->setStep(AccompanyingPeriod::STEP_CONFIRMED);
}
public function resetPreviousUser(): self
{
$this->userPrevious = null;
$this->userIsChanged = false;
return $this;
}
/**
* @Groups({"write"})
*/
@@ -1329,6 +1344,7 @@ class AccompanyingPeriod implements
{
if ($this->user !== $user) {
$this->userPrevious = $this->user;
$this->userIsChanged = true;
foreach ($this->userHistories as $history) {
if (null === $history->getEndDate()) {

View File

@@ -57,6 +57,7 @@ class AccompanyingPeriodWork implements AccompanyingPeriodLinkedWithSocialIssues
* orphanRemoval=true
* )
* @Serializer\Groups({"read", "docgen:read"})
* @ORM\OrderBy({"startDate": "DESC", "id": "DESC"})
*
* @internal /!\ the serialization for write evaluations is handled in `AccompanyingPeriodWorkDenormalizer`
*/

View File

@@ -77,6 +77,7 @@ class AccompanyingPeriodWorkEvaluation implements TrackCreationInterface, TrackU
* cascade={"remove", "persist"},
* orphanRemoval=true
* )
* @ORM\OrderBy({"createdAt": "DESC", "id": "DESC"})
* @Serializer\Groups({"read"})
*/
private Collection $documents;

View File

@@ -19,6 +19,7 @@ use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity
@@ -40,6 +41,8 @@ class Comment implements TrackCreationInterface, TrackUpdateInterface
/**
* @ORM\Column(type="text")
* @Groups({"read", "write"})
* @Assert\NotBlank
* @Assert\NotNull
*/
private $content;

View File

@@ -151,6 +151,9 @@ class Household
return $this->addresses;
}
/**
* @return array|Address[]
*/
public function getAddressesOrdered(): array
{
$addresses = $this->getAddresses()->toArray();

View File

@@ -136,8 +136,11 @@ final class PersonACLAwareRepository implements PersonACLAwareRepositoryInterfac
$andWhereSearchClause = [];
$andWhereSearchClauseArgs = [];
if ('' !== $default) {
if ('' !== trim($default)) {
foreach (explode(' ', $default) as $str) {
if ('' === trim($str)) {
continue;
}
$pertinence[] =
'STRICT_WORD_SIMILARITY(LOWER(UNACCENT(?)), person.fullnamecanonical) + ' .
"(person.fullnamecanonical LIKE '%' || LOWER(UNACCENT(?)) || '%')::int + " .

View File

@@ -30,6 +30,7 @@ div.list-with-period {
// override wrap-list
div.wrap-list.periods-list {
padding-right: 1rem;
div.wl-row {
flex-wrap: nowrap;
div.wl-col {
@@ -63,6 +64,7 @@ div.list-with-period {
}
div.periods-list {
padding-right: 1rem;
div.title {
text-align: right;
div.date {}

View File

@@ -5,9 +5,8 @@
</h2>
<div>
<div class="mb-3 row">
<label class="col-form-label col-sm-4">{{ $t('startdate.date') }}</label>
<div class="col-sm-8">
<input class="form-control" type="date" v-model="startDate" @change="updateStartDate" />
<div class="col-sm-12 date-update">
<input class="form-control" type="date" id="startDate" v-model="startDateInput">
</div>
</div>
</div>
@@ -17,30 +16,54 @@
<script>
import { datetimeToISO, dateToISO, ISOToDate, ISOToDatetime} from 'ChillMainAssets/chill/js/date.js';
import { mapState, mapGetters } from 'vuex';
import { dateToISO, ISOToDatetime} from 'ChillMainAssets/chill/js/date.js';
import { mapState } from 'vuex';
export default {
name: 'startDate',
methods: {
updateStartDate(event) {
const date = event.target.value;
// console.log(date)
this.$store.dispatch('updateStartDate', date)
.catch(({name, violations}) => {
if (name === 'ValidationException' || name === 'AccessException') {
violations.forEach((violation) => this.$toast.open({message: violation}));
} else {
this.$toast.open({message: 'An error occurred'})
}
});
},
data() {
return {
lastRecordedDate: null
}
},
computed: {
...mapState({
startDate: state => dateToISO(ISOToDatetime(state.accompanyingCourse.openingDate.datetime))
})
}),
startDateInput: {
get() {
return this.startDate;
},
set(value) {
this.lastRecordedDate = value;
setTimeout(() => {
console.log('timeout finished')
if (this.lastRecordedDate === value) {
console.log('last recorded', this.lastRecordedDate, 'value', value)
this.$store.dispatch('updateStartDate', value)
.catch(({name, violations}) => {
if (name === 'ValidationException' || name === 'AccessException') {
violations.forEach((violation) => this.$toast.open({message: violation}));
} else {
this.$toast.open({message: 'An error occurred'})
}
})
}
}, 3000)
}
}
}
}
</script>
</script>
<style lang="scss" scoped>
.date-update {
display: flex;
justify-content: space-between;
&-btn {
margin-left: 1rem;
}
}
</style>

View File

@@ -59,8 +59,8 @@ const appMessages = {
ok: "Oui, l'usager quitte le parcours",
show_household_number: "Voir le ménage (n° {id})",
show_household: "Voir le ménage",
person_without_household_warning: "Certaines usagers n'appartiennent actuellement à aucun ménage. Renseignez leur appartenance dès que possible.",
update_household: "Renseigner l'appartenance",
person_without_household_warning: "Certaines usagers n'appartiennent actuellement à aucun ménage. Veuillez les associer à un ménage dès que possible.",
update_household: "Associer à un ménage",
participation_not_valid: "Sélectionnez ou créez au minimum 1 usager",
},
requestor: {
@@ -153,7 +153,7 @@ const appMessages = {
},
startdate: {
change: "Date d'ouverture",
date: "Date d'ouverture",
// update: "La nouvelle date d'ouverture a été enregistrée"
},
// catch errors
'Error while updating AccompanyingPeriod Course.': "Erreur du serveur lors de la mise à jour du parcours d'accompagnement.",

View File

@@ -322,7 +322,6 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou
}
},
updateStartDate(state, date) {
console.log('new state date', date)
state.accompanyingCourse.openingDate = date;
}
},
@@ -814,11 +813,9 @@ let initPromise = (root) => Promise.all([getScopesPromise(root), accompanyingCou
})
},
updateStartDate({commit}, payload) {
console.log('payload', payload)
const date = ISOToDate(payload);
const url = `/api/1.0/person/accompanying-course/${id}.json`;
const body = { type: "accompanying_period", openingDate: { datetime: datetimeToISO(date) }};
console.log('body', body)
const date = payload === null || payload === '' ? null : { datetime: datetimeToISO(ISOToDate(payload)) }
const body = { type: "accompanying_period", openingDate: date};
return makeFetch('PATCH', url, body)
.then((response) => {
commit('updateStartDate', response.openingDate);

View File

@@ -227,19 +227,18 @@ export default {
},
startDate: {
get() {
let d = this.$store.state.startDate;
return dateToISO(d);
return this.$store.state.startDate;
},
set(value) {
this.$store.commit('setStartDate', ISOToDate(value));
this.$store.commit('setStartDate', value);
}
},
endDate: {
get() {
return dateToISO(this.$store.state.endDate);
return this.$store.state.endDate;
},
set(value) {
this.$store.commit('setEndDate', ISOToDate(value));
this.$store.commit('setEndDate', value);
}
},
setSocialIssue: {

View File

@@ -1,6 +1,6 @@
import { createStore } from 'vuex';
import { datetimeToISO } from 'ChillMainAssets/chill/js/date.js';
import { datetimeToISO, dateToISO, ISOToDate, ISOToDatetime } from 'ChillMainAssets/chill/js/date.js';
import { findSocialActionsBySocialIssue } from 'ChillPersonAssets/vuejs/_api/SocialWorkSocialAction.js';
// import { create } from 'ChillPersonAssets/vuejs/_api/AccompanyingCourseWork.js';
import { makeFetch } from 'ChillMainAssets/lib/api/apiMethods';
@@ -20,7 +20,7 @@ const store = createStore({
.map(p => p.person),
personsReachables: window.accompanyingCourse.participations.filter(p => p.endDate == null)
.map(p => p.person),
startDate: new Date(),
startDate: dateToISO(new Date()),
endDate: null,
isLoadingSocialActions: false,
isPostingWork: false,
@@ -47,7 +47,7 @@ const store = createStore({
id: state.socialActionPicked.id
},
startDate: {
datetime: datetimeToISO(state.startDate)
datetime: datetimeToISO(ISOToDate(state.startDate))
},
persons: []
};
@@ -61,7 +61,7 @@ const store = createStore({
if (null !== state.endDate) {
payload.endDate = {
datetime: datetimeToISO(state.endDate)
datetime: datetimeToISO(ISOToDate(state.endDate))
};
}
@@ -111,6 +111,7 @@ const store = createStore({
state.startDate = date;
},
setEndDate(state, date) {
console.log(date)
state.endDate = date;
},
setPersonsPickedIds(state, ids) {

View File

@@ -439,18 +439,18 @@ export default {
]),
startDate: {
get() {
return dateToISO(this.$store.state.startDate);
return this.$store.state.startDate;
},
set(v) {
this.$store.commit('setStartDate', ISOToDate(v));
this.$store.commit('setStartDate', v);
}
},
endDate: {
get() {
return dateToISO(this.$store.state.endDate);
return this.$store.state.endDate;
},
set(v) {
this.$store.commit('setEndDate', ISOToDate(v));
this.$store.commit('setEndDate', v);
}
},
note: {
@@ -521,12 +521,12 @@ export default {
this.$store.commit('removeReferrer', u);
},
goToGenerateWorkflow({link}) {
console.log('save before leave to generate workflow')
const callback = (data) => {
window.location.assign(link);
};
// console.log('save before leave to generate workflow')
const callback = (data) => {
window.location.assign(link);
};
return this.$store.dispatch('submit', callback)
return this.$store.dispatch('submit', callback)
.catch(e => { console.log(e); throw e; });
},
submit() {

View File

@@ -67,14 +67,17 @@
<div class="flex-table">
<div class="item-bloc" v-for="(d, i) in evaluation.documents" :key="d.id">
<div class="item-row">
<div class="input-group input-group-lg mb-3">
<input
class="form-control document-title"
type="text"
:value="d.title"
:id="d.id"
:data-key="i"
@input="onInputDocumentTitle"/>
<div class="input-group input-group-lg mb-3 row">
<label class="col-sm-3 col-form-label">Titre du document:</label>
<div class="col-sm-9">
<input
class="form-control document-title"
type="text"
:value="d.title"
:id="d.id"
:data-key="i"
@input="onInputDocumentTitle"/>
</div>
</div>
</div>
<div class="item-row">
@@ -295,38 +298,39 @@ export default {
}
},
computed: {
...mapState([
'isPosting'
]),
...mapState([
'isPosting'
]),
getTemplatesAvailables() {
return this.$store.getters.getTemplatesAvailablesForEvaluation(this.evaluation.evaluation);
return this.$store.getters.getTemplatesAvailablesForEvaluation(this.evaluation.evaluation);
},
canGenerate() {
return !this.$store.state.isPosting && this.template !== null;
return !this.$store.state.isPosting && this.template !== null;
},
startDate: {
get() {
return dateToISO(this.evaluation.startDate);
},
set(v) {
this.$store.commit('setEvaluationStartDate', { key: this.evaluation.key, date: ISOToDate(v) });
}
get() {
console.log('evaluation', this.evaluation);
return this.evaluation.startDate;
},
set(v) {
this.$store.commit('setEvaluationStartDate', { key: this.evaluation.key, date: v });
}
},
endDate: {
get() {
return dateToISO(this.evaluation.endDate);
},
set(v) {
this.$store.commit('setEvaluationEndDate', { key: this.evaluation.key, date: ISOToDate(v) });
}
get() {
return this.evaluation.endDate;
},
set(v) {
this.$store.commit('setEvaluationEndDate', { key: this.evaluation.key, date: v });
}
},
maxDate: {
get() {
return dateToISO(this.evaluation.maxDate);
},
set(v) {
this.$store.commit('setEvaluationMaxDate', { key: this.evaluation.key, date: ISOToDate(v) });
}
get() {
return this.evaluation.maxDate;
},
set(v) {
this.$store.commit('setEvaluationMaxDate', { key: this.evaluation.key, date: v });
}
},
warningInterval: {
get() { return this.evaluation.warningInterval; },
@@ -341,7 +345,7 @@ export default {
ISOToDatetime,
canEditDocument(document) {
return 'storedObject' in document ?
this.mime.includes(document.storedObject.type) && document.storedObject.keyInfos.length === 0 : false;
this.mime.includes(document.storedObject.type) : false;
},
listAllStatus() {
console.log('load all status');
@@ -357,16 +361,16 @@ export default {
},
buildEditLink(storedObject) {
return `/wopi/edit/${storedObject.uuid}?returnPath=` + encodeURIComponent(
window.location.pathname + window.location.search + window.location.hash);
window.location.pathname + window.location.search + window.location.hash);
},
submitBeforeGenerate({template}) {
const callback = (data) => {
let evaluationId = data.accompanyingPeriodWorkEvaluations.find(e => e.key === this.evaluation.key).id;
const callback = (data) => {
let evaluationId = data.accompanyingPeriodWorkEvaluations.find(e => e.key === this.evaluation.key).id;
window.location.assign(buildLink(template, evaluationId, 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluation'));
};
window.location.assign(buildLink(template, evaluationId, 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluation'));
};
return this.$store.dispatch('submit', callback).catch(e => { console.log(e); throw e; });
return this.$store.dispatch('submit', callback).catch(e => { console.log(e); throw e; });
},
onInputDocumentTitle(event) {
const id = Number(event.target.id);
@@ -392,20 +396,20 @@ export default {
},
removeDocument(document) {
if (window.confirm("Êtes-vous sûr·e de vouloir supprimer le document qui a pour titre \"" + document.title +"\" ?")) {
this.$store.commit('removeDocument', {key: this.evaluation.key, document: document});
this.$store.commit('removeDocument', {key: this.evaluation.key, document: document});
}
},
goToGenerateWorkflowEvaluationDocument({event, link, workflowName, payload}) {
const callback = (data) => {
let evaluation = data.accompanyingPeriodWorkEvaluations.find(e => e.key === this.evaluation.key);
let updatedDocument = evaluation.documents.find(d => d.key === payload.doc.key);
window.location.assign(buildLinkCreate(workflowName,
'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument', updatedDocument.id));
};
const callback = (data) => {
let evaluation = data.accompanyingPeriodWorkEvaluations.find(e => e.key === this.evaluation.key);
let updatedDocument = evaluation.documents.find(d => d.key === payload.doc.key);
window.location.assign(buildLinkCreate(workflowName,
'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument', updatedDocument.id));
};
return this.$store.dispatch('submit', callback)
.catch(e => { console.log(e); throw e; });
},
return this.$store.dispatch('submit', callback)
.catch(e => { console.log(e); throw e; });
},
},
}
</script>

View File

@@ -1,5 +1,5 @@
import { createStore } from 'vuex';
import { datetimeToISO, ISOToDatetime, intervalDaysToISO, intervalISOToDays } from 'ChillMainAssets/chill/js/date.js';
import { dateToISO, ISOToDate, datetimeToISO, ISOToDatetime, intervalDaysToISO, intervalISOToDays } from 'ChillMainAssets/chill/js/date.js';
import { findSocialActionsBySocialIssue } from 'ChillPersonAssets/vuejs/_api/SocialWorkSocialAction.js';
import { create } from 'ChillPersonAssets/vuejs/_api/AccompanyingCourseWork.js';
import { fetchResults, makeFetch } from 'ChillMainAssets/lib/api/apiMethods.js';
@@ -13,9 +13,9 @@ const store = createStore({
state: {
work: window.accompanyingCourseWork,
startDate: window.accompanyingCourseWork.startDate !== null ?
ISOToDatetime(window.accompanyingCourseWork.startDate.datetime) : null,
dateToISO(new Date(window.accompanyingCourseWork.startDate.datetime)) : null,
endDate: window.accompanyingCourseWork.endDate !== null ?
ISOToDatetime(window.accompanyingCourseWork.endDate.datetime) : null,
dateToISO(new Date(window.accompanyingCourseWork.endDate.datetime)) : null,
note: window.accompanyingCourseWork.note,
goalsPicked: window.accompanyingCourseWork.goals,
goalsForAction: [],
@@ -72,11 +72,11 @@ const store = createStore({
return {
type: 'accompanying_period_work',
id: state.work.id,
startDate: state.startDate === null ? null : {
datetime: datetimeToISO(state.startDate)
startDate: state.startDate === null || state.startDate === '' ? null : {
datetime: datetimeToISO(ISOToDate(state.startDate))
},
endDate: state.endDate === null ? null : {
datetime: datetimeToISO(state.endDate)
endDate: state.endDate === null || state.endDate === '' ? null : {
datetime: datetimeToISO(ISOToDate(state.endDate))
},
note: state.note,
persons: state.personsPicked.map(p => ({id: p.id, type: p.type})),
@@ -110,9 +110,9 @@ const store = createStore({
id: e.evaluation.id,
type: e.evaluation.type
},
startDate: e.startDate !== null ? { datetime: datetimeToISO(e.startDate) } : null,
endDate: e.endDate !== null ? { datetime: datetimeToISO(e.endDate) } : null,
maxDate: e.maxDate !== null ? { datetime: datetimeToISO(e.maxDate) } : null,
startDate: e.startDate === null || e.startDate === '' ? null : { datetime: datetimeToISO(ISOToDate(e.startDate)) },
endDate: e.endDate === null || e.endDate === '' ? null : { datetime: datetimeToISO(ISOToDate(e.endDate)) },
maxDate: e.maxDate === null || e.maxDate === '' ? null : { datetime: datetimeToISO(ISOToDate(e.maxDate)) },
warningInterval: intervalDaysToISO(e.warningInterval),
comment: e.comment,
documents: e.documents
@@ -132,9 +132,9 @@ const store = createStore({
var k = Object.assign(e, {
key: index,
editEvaluation: false,
startDate: e.startDate !== null ? ISOToDatetime(e.startDate.datetime) : null,
endDate: e.endDate !== null ? ISOToDatetime(e.endDate.datetime) : null,
maxDate: e.maxDate !== null ? ISOToDatetime(e.maxDate.datetime) : null,
startDate: e.startDate !== null ? dateToISO(new Date(e.startDate.datetime)) : null,
endDate: e.endDate !== null ? dateToISO(new Date(e.endDate.datetime)) : null,
maxDate: e.maxDate !== null ? dateToISO(new Date(e.maxDate.datetime)) : null,
warningInterval: e.warningInterval !== null ? intervalISOToDays(e.warningInterval) : null,
documents: e.documents.map((d, docIndex) => {
return Object.assign(d, {
@@ -244,7 +244,7 @@ const store = createStore({
type: "accompanying_period_work_evaluation",
key: state.evaluationsPicked.length + 1,
evaluation: evaluation,
startDate: new Date(),
startDate: dateToISO(new Date()),
endDate: null,
maxDate: null,
warningInterval: null,
@@ -264,6 +264,7 @@ const store = createStore({
.startDate = date;
},
setEvaluationEndDate(state, {key, date}) {
console.log('commit date', date)
state.evaluationsPicked.find(e => e.key === key)
.endDate = date;
},

View File

@@ -53,7 +53,7 @@ export default {
return null;
},
set(value) {
this.$store.commit('setHouseholdCompositionType', value);
this.$store.dispatch('setHouseholdCompositionType', value);
},
},
numberOfChildren: {
@@ -66,18 +66,19 @@ export default {
},
startDate: {
get() {
return [
this.$store.state.startDate.getFullYear(),
(this.$store.state.startDate.getMonth() + 1).toString().padStart(2, '0'),
this.$store.state.startDate.getDate().toString().padStart(2, '0')
].join('-');
return this.$store.state.startDate;
// return [
// this.$store.state.startDate.getFullYear(),
// (this.$store.state.startDate.getMonth() + 1).toString().padStart(2, '0'),
// this.$store.state.startDate.getDate().toString().padStart(2, '0')
// ].join('-');
},
set(value) {
let
[year, month, day] = value.split('-'),
dValue = new Date(year, month-1, day);
// let
// [year, month, day] = value.split('-'),
// dValue = new Date(year, month-1, day);
this.$store.dispatch('setStartDate', dValue);
this.$store.dispatch('setStartDate', value);
}
}
}

View File

@@ -2,7 +2,7 @@ import { createStore } from 'vuex';
import { householdMove, fetchHouseholdSuggestionByAccompanyingPeriod, fetchAddressSuggestionByPerson} from './../api.js';
import { fetchResults } from 'ChillMainAssets/lib/api/apiMethods.js'
import { fetchHouseholdByAddressReference } from 'ChillPersonAssets/lib/household.js';
import { datetimeToISO } from 'ChillMainAssets/chill/js/date.js';
import { datetimeToISO, dateToISO, ISOToDate } from 'ChillMainAssets/chill/js/date.js';
const debug = process.env.NODE_ENV !== 'production';
@@ -30,7 +30,7 @@ const store = createStore({
}
return 0;
}),
startDate: new Date(),
startDate: dateToISO(new Date()),
/**
* Indicates if the destination is:
*
@@ -278,7 +278,7 @@ const store = createStore({
type: conc.person.type
},
start_date: {
datetime: datetimeToISO(state.startDate)
datetime: state.startDate === null || state.startDate === '' ? null : datetimeToISO(ISOToDate(state.startDate))
}
};
@@ -302,7 +302,7 @@ const store = createStore({
},
number_of_children: state.numberOfChildren,
start_date: {
datetime: datetimeToISO(state.startDate),
datetime: datetimeToISO(ISOToDate(state.startDate)),
},
};
}
@@ -430,7 +430,7 @@ const store = createStore({
state.householdCompositionTypes = types;
},
setHouseholdCompositionType(state, id) {
state.householdCompositionType = state.householdCompositionTypes.find(t => t.id = id);
state.householdCompositionType = state.householdCompositionTypes.find(t => t.id === id);
},
setNumberOfChildren(state, number) {
state.numberOfChildren = Number.parseInt(number);
@@ -495,6 +495,12 @@ const store = createStore({
setComment({ commit }, payload) {
commit('setComment', payload);
},
setHouseholdCompositionTypes({ commit }, payload) {
commit('setHouseholdCompositionTypes', payload);
},
setHouseholdCompositionType({ commit }, payload) {
commit('setHouseholdCompositionType', payload);
},
fetchHouseholdSuggestionForConcerned({ commit, state }, person) {
fetchHouseholdSuggestionByAccompanyingPeriod(person.id)
.then(households => {
@@ -597,7 +603,7 @@ if (concerned.length > 0) {
}
fetchResults(`/api/1.0/person/houehold/composition/type.json`).then(types => {
store.commit('setHouseholdCompositionTypes', types);
store.dispatch('setHouseholdCompositionTypes', types);
})
export { store };

View File

@@ -40,6 +40,7 @@
{% endif %}
{{ form_start(form) }}
{{ form_errors(form) }}
{{ form_errors(form.content) }}
{{ form_widget(form.content) }}
<ul class="record_actions">
<li>

View File

@@ -25,22 +25,6 @@
<div class="item-row separator">
<div class="wrap-list">
{% if w.createdBy %}
<div class="wl-row">
<div class="wl-col title">
<h3>{{ 'Referrers'|trans }}</h3>
</div>
<div class="wl-col list">
<p class="wl-item">
{% for u in w.referrers %}
{{ u|chill_entity_render_box }}
{% if not loop.last %}, {% endif %}
{% endfor %}
</p>
</div>
</div>
{% endif %}
{%- if w.persons -%}
<div class="wl-row">
<div class="wl-col title">
@@ -78,6 +62,22 @@
</div>
{% endif %}
{%- if w.referrers -%}
<div class="wl-row">
<div class="wl-col title">
<h3>{{ 'Referrers'|trans }}</h3>
</div>
<div class="wl-col list">
{% for u in w.referrers %}
<span class="wl-item">
{{ u|chill_entity_render_box }}
{% if not loop.last %}, {% endif %}
</span>
{% endfor %}
</div>
</div>
{% endif %}
{%- if w.socialAction.issue -%}
<div class="wl-row">
<div class="wl-col title">

View File

@@ -28,6 +28,15 @@
<span class="badge-thirdparty">{{ w.handlingThierParty|chill_entity_render_box }}</span>
</li>
{% endif %}
{% if w.referrers %}
<li>
<span class="item-key">{{ 'Referrers'|trans ~ ' : ' }}</span>
{% for u in w.referrers %}
<span class="badge-user">{{ u|chill_entity_render_box }}</span>
{% if not loop.last %}, {% endif %}
{% endfor %}
</li>
{% endif %}
<li class="associated-persons">
<span class="item-key">{{ 'Participants'|trans ~ ' : ' }}</span>
{% for p in w.persons %}

View File

@@ -20,7 +20,7 @@
{% elseif period.step == 'CONFIRMED' %}
<span class="badge bg-primary">{{- 'Confirmed'|trans|upper -}}</span>
{% else %}
<span class="badge bg-primary">{{- 'Closed'|trans|upper -}}</span>
<span class="badge bg-danger">{{- 'Closed'|trans|upper -}}</span>
{% endif %}
</div>
</div>
@@ -116,14 +116,40 @@
</div>
</div>
{% endif %}
<div class="item-row separator">
{% set notif_counter = chill_count_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', period.id) %}
{% if notif_counter.total > 0 %}
<div class="item-col item-meta">
{{ chill_counter_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', period.id) }}
{% if show_pinned_comment|default(false) and period.pinnedComment is not empty%}
<div class="item-row separator comment">
<div style="width: 100%">
<h4 class="item-key visually-hidden">{{ 'Pinned comment'|trans }}</h4>
<blockquote class="chill-user-quote">
{{ period.pinnedComment.content|u.truncate(750, '…', false)|chill_markdown_to_html }}
{% if period.pinnedComment.content|length > 750 %}
<a href="{{ chill_path_add_return_path('chill_person_accompanying_period_comment_list', {'accompanying_period_id': period.id}) }}">{{ 'Read more'|trans }}</a>
{% endif %}
<div class="metadata">
{{ 'Last updated by'| trans }}
<span class="user">
{{ period.pinnedComment.updatedBy|chill_entity_render_box }}
</span>
{{ 'on'|trans ~ ' ' }}
<span class="date">
{{ period.pinnedComment.updatedAt|format_datetime("medium", "short") }}
</span>
</div>
</blockquote>
</div>
{% endif %}
{% if itemMeta is defined %}
</div>
{% endif %}
<div class="item-row separator">
{% if itemMeta is not defined %}
{% set notif_counter = chill_count_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', period.id) %}
{% if notif_counter.total > 0 %}
<div class="item-col item-meta">
{{ chill_counter_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', period.id) }}
</div>
{% endif %}
{% else %}
{{ itemMeta }}
{% endif %}
<div class="item-col">

View File

@@ -17,6 +17,8 @@
<div class="col-md-10">
<h1>{{ 'My accompanying periods'|trans }}</h1>
<p>{{ 'Number of periods'|trans }}: <span class="badge rounded-pill bg-primary">{{ pagination.totalItems }}</span></p>
<div class="flex-table accompanyingcourse-list">
{% for period in accompanyingPeriods %}
{% include '@ChillPerson/AccompanyingPeriod/_list_item.html.twig' with {'period': period, 'recordAction': _self.recordAction(period)} %}

View File

@@ -10,12 +10,6 @@
{% include 'ChillPersonBundle:AccompanyingPeriod:_list.html.twig' %}
{% if accompanying_periods_old|length > 0 %}
<style>
button[aria-expanded="true"] > span.folded,
button[aria-expanded="false"] > span.unfolded { display: none; }
button[aria-expanded="false"] > span.folded,
button[aria-expanded="true"] > span.unfolded { display: inline; }
</style>
<div class="accordion" id="nonCurrent">
<div class="accordion-item">
<h2 class="accordion-header" id="heading_{{ household.id }}">

View File

@@ -0,0 +1,32 @@
{% extends '@ChillPerson/Household/layout.html.twig' %}
{% block title 'Edit household address valid from'|trans %}
{% block content %}
<h1>{{ block('title') }}</h1>
<div>
{{ address|chill_entity_render_box}}
</div>
{{ form_start(form) }}
{{ form_errors(form) }}
<div>
{{ form_row(form.validFrom) }}
</div>
<ul class="record_actions sticky-form-buttons">
<li class="cancel">
<a href="{{ path('chill_person_household_addresses', { 'household_id': household.id } ) }}" class="btn btn-cancel">
{{ 'Cancel'|trans }}
</a>
</li>
<li>
<button class="btn btn-update" type="submit">{{ 'Save'|trans }}</button>
</li>
</ul>
{{ form_end(form) }}
{% endblock %}

View File

@@ -62,13 +62,17 @@
'extended_infos': true,
'has_no_address': true
}) }}
<ul class="record_actions">
<li>
<a href="{{ path('chill_person_household_address_edit', { 'household_id': household.id, 'address_id' : address.id } ) }}"
class="btn btn-edit"></a>
</li>
</ul>
{% if is_granted('CHILL_PERSON_HOUSEHOLD_EDIT', household) %}
<ul class="record_actions">
<li>
<a href="{{ path('chill_person_household_address_valid_from_edit', { 'household_id': household.id, 'address_id' : address.id } ) }}"
class="btn btn-edit">{{ "edit address valid from"|trans }}
</a>
<a href="{{ path('chill_person_household_address_edit', { 'household_id': household.id, 'address_id' : address.id } ) }}"
class="btn btn-edit"></a>
</li>
</ul>
{% endif %}
</div>
<div class="date">

View File

@@ -191,12 +191,6 @@
{% endif %}
{% if old_members|length > 0 %}
<style>
button[aria-expanded="true"] > span.folded,
button[aria-expanded="false"] > span.unfolded { display: none; }
button[aria-expanded="false"] > span.folded,
button[aria-expanded="true"] > span.unfolded { display: inline; }
</style>
<div class="accordion" id="nonCurrent">
<div class="accordion-item">
<h2 class="accordion-header" id="heading_{{ p == '_none' ? '_none' : p.id }}">

View File

@@ -1,14 +1,14 @@
{{ 'period_notification.You are designated to a new period'|trans }}
{{ 'period_notification.You are designated to a new period'|trans|raw }}
{{ 'period_notification.See it online'|trans }}:
{{ 'period_notification.See it online'|trans|raw }}:
{{ absolute_url(path('chill_person_accompanying_course_index', {'accompanying_period_id': accompanyingCourse.id}, false)) }}
{{ 'period_notification.Persons are'|trans }}:
{{ 'period_notification.Persons are'|trans|raw }}:
{% for p in accompanyingCourse.getCurrentParticipations %}
* {{ p.person|chill_entity_render_string }}
{% endfor %}
{{ 'period_notification.Social issues are'|trans }}: {% for s in accompanyingCourse.socialIssues %}{{ s|chill_entity_render_string }}{% if not loop.last %}, {% endif %}{% endfor %}.
{{ 'period_notification.Social issues are'|trans|raw }}: {% for s in accompanyingCourse.socialIssues %}{{ s|chill_entity_render_string }}{% if not loop.last %}, {% endif %}{% endfor %}.

View File

@@ -10,6 +10,157 @@
</li>
{% endmacro %}
{% macro accompanying_period(acp, person) %}
{% set app = person.findParticipationForPeriod(acp) %}
<div class="item-row separator">
<div class="wrap-list periods-list">
<div class="wl-row">
<div class="wl-col title">
<h3 class="courseid mb-2">
<i class="fa fa-random fa-fw"></i>
{{ 'Course number'|trans }} {{ acp.id }}
</h3>
</div>
<div class="wl-col list">
<div class="d-flex flex-column justify-content-center">
{% if app != null %}
<div class="date">
{{ 'Since %date%'|trans({'%date%': app.startDate|format_date('medium') }) }}
</div>
{% endif %}
{% set notif_counter = chill_count_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', acp.id) %}
{% if notif_counter.total > 0 %}
{{ chill_counter_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', acp.id) }}
{% endif %}
</div>
<div class="ms-auto">
{% if acp.requestoranonymous == false and acp.requestorPerson is same as(person) %}
<span class="as-requestor badge bg-info" title="{{ 'Requestor'|trans|e('html_attr') }}">
{{ 'Requestor'|trans({'gender': person.gender}) }}
</span>
{% endif %}
{% if acp.emergency %}
<span class="badge rounded-pill bg-danger">{{- 'Emergency'|trans|upper -}}</span>
{% endif %}
{% if acp.confidential %}
<span class="badge rounded-pill bg-confidential">{{- 'Confidential'|trans|upper -}}</span>
{% endif %}
{% if acp.step == 'DRAFT' %}
<span class="badge bg-secondary" style="font-size: 85%;" title="{{ 'course.draft'|trans }}">{{ 'course.draft'|trans }}</span>
{% endif %}
{% if acp.step == 'CLOSED' %}
<span class="badge bg-danger" style="font-size: 85%;" title="{{ 'course.closed'|trans }}">{{ 'course.closed'|trans }}</span>
{% endif %}
</div>
</div>
</div>
{% if acp.user is not null %}
<div class="wl-row">
<div class="wl-col title">
<h3 class="referrer">{{ 'Referrer'|trans }}</h3>
</div>
<div class="wl-col list">
<div class="user">
{{ acp.user|chill_entity_render_box }}
</div>
</div>
</div>
{% endif %}
{% if acp.socialIssues|length > 0 %}
<div class="wl-row">
<div class="wl-col title">
<h3>{{ 'Social issues'|trans }}</h3>
</div>
<div class="wl-col list">
{% for issue in acp.socialIssues %}
{{ issue|chill_entity_render_box }}
{% endfor %}
</div>
</div>
{% endif %}
{% if acp.currentParticipations|length > 1 %}
<div class="wl-row">
<div class="wl-col title">
<h3 class="participants">
{{ 'Participants'|trans }}
</h3>
</div>
<div class="wl-col list">
{% set participating = false %}
{% for part in acp.currentParticipations %}
{% if part.person.id != person.id %}
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
targetEntity: { name: 'person', id: part.person.id },
action: 'show',
displayBadge: true,
buttonText: part.person|chill_entity_render_string,
isDead: part.person.deathdate is not null
} %}
{% else %}
{% set participating = true %}
{% endif %}
{% endfor %}
{% if participating %}
{{ 'person.and_himself'|trans({'gender': person.gender}) }}
{% endif %}
</div>
</div>
{% endif %}
{% if acp.requestoranonymous == false %}
{% if (acp.requestorPerson is not null and acp.requestorPerson.id != person.id) or acp.requestorThirdParty is not null %}
<div class="wl-row">
<div class="wl-col title">
<h3>
{% if acp.requestorPerson is not null %}
{{ 'Requestor'|trans({'gender': acp.requestorPerson.gender}) }}
{% else %}
{{ 'Requestor'|trans({'gender': 'other'})}}
{% endif %}
</h3>
</div>
<div class="wl-col list">
{% if acp.requestorThirdParty is not null %}
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
targetEntity: { name: 'thirdparty', id: acp.requestorThirdParty.id },
action: 'show',
displayBadge: true,
buttonText: acp.requestorThirdParty|chill_entity_render_string
} %}
{% else %}
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
targetEntity: { name: 'person', id: acp.requestorPerson.id },
action: 'show',
displayBadge: true,
buttonText: acp.requestorPerson|chill_entity_render_string,
isDead: acp.requestorPerson.deathdate is not null
} %}
{% endif %}
</div>
</div>
{% endif %}
{% endif %}
<ul class="record_actions record_actions_column">
<li>
<a href="{{ path('chill_person_accompanying_course_index', { 'accompanying_period_id': acp.id }) }}"
class="btn btn-sm btn-outline-primary" title="{{ 'See accompanying period'|trans }}">
<i class="fa fa-random fa-fw"></i>
</a>
</li>
</ul>
</div>
</div>
{% endmacro %}
<div class="list-with-period">
<h2>{{ title|default('Person search results')|trans }}</h2>
@@ -66,167 +217,53 @@
{#- 'acps' is for AcCompanyingPeriodS #}
{%- set acps = [] %}
{%- set acpsClosed = [] %}
{%- for acp in person.accompanyingPeriodInvolved %}
{%- if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_SEE', acp) %}
{%- set acps = acps|merge([acp]) %}
{% if acp.step == 'CLOSED' %}
{%- set acpsClosed = acpsClosed|merge([acp]) %}
{% else %}
{%- set acps = acps|merge([acp]) %}
{% endif %}
{%- endif %}
{%- endfor %}
{# add as requestor #}
{% if acps|length > 0 %}
{% for acp in acps %}
{% set app = person.findParticipationForPeriod(acp) %}
<div class="item-row separator">
<div class="wrap-list periods-list">
<div class="wl-row">
<div class="wl-col title">
<h3 class="courseid mb-2">
<i class="fa fa-random fa-fw"></i>
{{ 'Course number'|trans }} {{ acp.id }}
</h3>
</div>
<div class="wl-col list">
<div class="d-flex flex-column justify-content-center">
{% if app != null %}
<div class="date">
{{ 'Since %date%'|trans({'%date%': app.startDate|format_date('medium') }) }}
</div>
{% endif %}
{% set notif_counter = chill_count_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', acp.id) %}
{% if notif_counter.total > 0 %}
{{ chill_counter_notifications('Chill\\PersonBundle\\Entity\\AccompanyingPeriod', acp.id) }}
{% endif %}
</div>
<div class="ms-auto">
{% if acp.requestoranonymous == false and acp.requestorPerson == person %}
<span class="as-requestor badge bg-info" title="{{ 'Requestor'|trans|e('html_attr') }}">
{{ 'Requestor'|trans({'gender': person.gender}) }}
</span>
{% endif %}
{% if acp.emergency %}
<span class="badge rounded-pill bg-danger">{{- 'Emergency'|trans|upper -}}</span>
{% endif %}
{% if acp.confidential %}
<span class="badge rounded-pill bg-confidential">{{- 'Confidential'|trans|upper -}}</span>
{% endif %}
{% if acp.step == 'DRAFT' %}
<span class="badge bg-secondary" style="font-size: 85%;" title="{{ 'course.draft'|trans }}">{{ 'course.draft'|trans }}</span>
{% endif %}
{% if acp.step == 'CLOSED' %}
<span class="badge bg-secondary" style="font-size: 85%;" title="{{ 'course.closed'|trans }}">{{ 'course.closed'|trans }}</span>
{% endif %}
</div>
</div>
</div>
{% if acp.user is not null %}
<div class="wl-row">
<div class="wl-col title">
<h3 class="referrer">{{ 'Referrer'|trans }}</h3>
</div>
<div class="wl-col list">
<div class="user">
{{ acp.user|chill_entity_render_box }}
</div>
</div>
</div>
{% endif %}
{% if acp.socialIssues|length > 0 %}
<div class="wl-row">
<div class="wl-col title">
<h3>{{ 'Social issues'|trans }}</h3>
</div>
<div class="wl-col list">
{% for issue in acp.socialIssues %}
{{ issue|chill_entity_render_box }}
{% endfor %}
</div>
</div>
{% endif %}
{% if acp.currentParticipations|length > 1 %}
<div class="wl-row">
<div class="wl-col title">
<h3 class="participants">
{{ 'Participants'|trans }}
</h3>
</div>
<div class="wl-col list">
{% set participating = false %}
{% for part in acp.currentParticipations %}
{% if part.person.id != person.id %}
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
targetEntity: { name: 'person', id: part.person.id },
action: 'show',
displayBadge: true,
buttonText: part.person|chill_entity_render_string,
isDead: part.person.deathdate is not null
} %}
{% else %}
{% set participating = true %}
{% endif %}
{% endfor %}
{% if participating %}
{{ 'person.and_himself'|trans({'gender': person.gender}) }}
{% endif %}
</div>
</div>
{% endif %}
{% if acp.requestoranonymous == false %}
{% if (acp.requestorPerson is not null and acp.requestorPerson.id != person.id) or acp.requestorThirdParty is not null %}
<div class="wl-row">
<div class="wl-col title">
<h3>
{% if acp.requestorPerson is not null %}
{{ 'Requestor'|trans({'gender': acp.requestorPerson.gender}) }}
{% else %}
{{ 'Requestor'|trans({'gender': 'other'})}}
{% endif %}
</h3>
</div>
<div class="wl-col list">
{% if acp.requestorThirdParty is not null %}
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
targetEntity: { name: 'thirdparty', id: acp.requestorThirdParty.id },
action: 'show',
displayBadge: true,
buttonText: acp.requestorThirdParty|chill_entity_render_string
} %}
{% else %}
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
targetEntity: { name: 'person', id: acp.requestorPerson.id },
action: 'show',
displayBadge: true,
buttonText: acp.requestorPerson|chill_entity_render_string,
isDead: acp.requestorPerson.deathdate is not null
} %}
{% endif %}
</div>
</div>
{% endif %}
{% endif %}
<ul class="record_actions record_actions_column">
<li>
<a href="{{ path('chill_person_accompanying_course_index', { 'accompanying_period_id': acp.id }) }}"
class="btn btn-sm btn-outline-primary" title="{{ 'See accompanying period'|trans }}">
<i class="fa fa-random fa-fw"></i>
</a>
</li>
</ul>
</div>
</div>
{{ _self.accompanying_period(acp, person) }}
{% endfor %}
{% endif %}
{% if acpsClosed|length > 0 %}
<div class="accordion" id="member_{{ person.id }}">
<div class="accordion-item">
<h2 class="accordion-header" id="heading_{{ person.id }}">
<button
class="accordion-button collapsed"
type="button"
data-bs-toggle="collapse"
data-bs-target="#collapse_{{ person.id }}"
aria-expanded="false"
aria-controls="collapse_{{ person.id }}">
<span class="folded">{{ 'periods.show closed periods'|trans({ 'nb_items': acpsClosed|length }) }}</span>
<span class="unfolded text-secondary">{{ 'periods.hide closed periods'|trans({ 'nb_items': acpsClosed|length }) }}</span>
</button>
</h2>
<div id="collapse_{{ person.id }}"
class="accordion-collapse collapse"
aria-labelledby="heading_{{ person.id }}"
data-bs-parent="#nonCurrent">
{% for acp in acpsClosed %}
{{ _self.accompanying_period(acp, person) }}
{% endfor %}
</div>
</div>
</div>
{% endif %}
</div>
{% endfor %}
</div>

View File

@@ -1,133 +1,139 @@
{%- import "@ChillDocStore/Macro/macro.html.twig" as m -%}
<div class="flex-table accompanying_course_work-list">
<div class="item-bloc evaluation-item bg-chill-llight-gray">
<div class="item-row mb-2">
<h1>{{ doc.title }}</h1>
</div>
<div class="item-row mb-2">
<h2 class="badge-title">
<span class="title_label"></span>
<span class="title_action">
{{ evaluation.accompanyingPeriodWork.socialAction|chill_entity_render_string }}
<ul class="small_in_title columns mt-1">
<li>
<span class="item-key">{{ 'accompanying_course_work.start_date'|trans ~ ' : ' }}</span>
<b>{{ evaluation.accompanyingPeriodWork.startDate|format_date('short') }}</b>
</li>
{% if evaluation.accompanyingPeriodWork.endDate %}
{% if doc is null %}
<div class="alert alert-warning">
{{ 'workflow.doc for evaluation deleted'|trans }}
</div>
{% else %}
<div class="flex-table accompanying_course_work-list">
<div class="item-bloc evaluation-item bg-chill-llight-gray">
<div class="item-row mb-2">
<h1>{{ doc.title }}</h1>
</div>
<div class="item-row mb-2">
<h2 class="badge-title">
<span class="title_label"></span>
<span class="title_action">
{{ evaluation.accompanyingPeriodWork.socialAction|chill_entity_render_string }}
<ul class="small_in_title columns mt-1">
<li>
<span class="item-key">{{ 'accompanying_course_work.end_date'|trans ~ ' : ' }}</span>
<b>{{ evaluation.accompanyingPeriodWork.endDate|format_date('short') }}</b>
<span class="item-key">{{ 'accompanying_course_work.start_date'|trans ~ ' : ' }}</span>
<b>{{ evaluation.accompanyingPeriodWork.startDate|format_date('short') }}</b>
</li>
{% endif %}
</ul>
</span>
</h2>
</div>
<div class="item-row mb-2">
<div class="item-col" style="width: 17%;">
<h4 class="title_label">
{{ 'Participants'|trans }}
</h4>
</div>
<div class="item-col list">
{% for p in evaluation.accompanyingPeriodWork.persons %}
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
targetEntity: { name: 'person', id: p.id },
action: 'show',
displayBadge: true,
buttonText: p|chill_entity_render_string,
isDead: p.deathdate is not null
} %}
{% endfor %}
</div>
</div>
<div class="item-row column">
<table class="obj-res-eval my-3" style="font-size: 110% !important;">
<thead>
<tr>
<th class="eval">
<h4 class="title_label">
{{ 'Évaluation'|trans }}
</h4>
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="eval">
<ul class="eval_title">
<li class="my-2">
{{ evaluation.evaluation.title|localize_translatable_string }}
<ul class="columns pt-2">
<li>
<span class="item-key">{{ 'accompanying_course_work.start_date'|trans ~ ' : ' }}</span>
<b>{{ evaluation.startDate|format_date('short') }}</b>
</li>
{% if evaluation.endDate %}
<li>
<span class="item-key">{{ 'accompanying_course_work.end_date'|trans ~ ' : ' }}</span>
<b>{{ evaluation.endDate|format_date('short') }}</b>
</li>
{% endif %}
{% if evaluation.maxDate %}
<li>
<span class="item-key">{{ 'accompanying_course_work.max_date'|trans ~ ' : ' }}</span>
<b>{{ evaluation.maxDate|format_date('short') }}</b>
</li>
{% endif %}
{% if evaluation.warningInterval and evaluation.warningInterval.d > 0 %}
<li>
{% set days = (evaluation.warningInterval.d + evaluation.warningInterval.m * 30) %}
<span class="item-key">{{ 'accompanying_course_work.warning_interval'|trans ~ ' : ' }}</span>
{{ 'accompanying_course_work.%days% days before max_date'|trans({'%days%': days }) }}
</li>
{% endif %}
<li>
{% if evaluation.createdBy is not null %}
<span class="item-key">créé par</span>
<b>{{ evaluation.createdBy.username }}</b>
{% endif %}
{% if evaluation.createdAt is not null %}
<span class="item-key">{{ 'le'|trans }}</span>
<b>{{ evaluation.createdAt|format_date('short') }}</b>
{% endif %}
</li>
</ul>
{% if evaluation.comment %}
<blockquote class="chill-user-quote" style="margin-left: 0;">
{{ evaluation.comment }}
</blockquote>
{% endif %}
{% if evaluation.accompanyingPeriodWork.endDate %}
<li>
<span class="item-key">{{ 'accompanying_course_work.end_date'|trans ~ ' : ' }}</span>
<b>{{ evaluation.accompanyingPeriodWork.endDate|format_date('short') }}</b>
</li>
</ul>
</td>
</tr>
</tbody>
</table>
</div>
<div class="item-row">
{% import '@ChillPerson/Macro/updatedBy.html.twig' as macro %}
{{ macro.updatedBy(evaluation) }}
{% endif %}
</ul>
</span>
</h2>
</div>
<div class="item-row mb-2">
<div class="item-col" style="width: 17%;">
<h4 class="title_label">
{{ 'Participants'|trans }}
</h4>
</div>
<div class="item-col list">
{% for p in evaluation.accompanyingPeriodWork.persons %}
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
targetEntity: { name: 'person', id: p.id },
action: 'show',
displayBadge: true,
buttonText: p|chill_entity_render_string,
isDead: p.deathdate is not null
} %}
{% endfor %}
</div>
</div>
<div class="item-row column">
<table class="obj-res-eval my-3" style="font-size: 110% !important;">
<thead>
<tr>
<th class="eval">
<h4 class="title_label">
{{ 'Évaluation'|trans }}
</h4>
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="eval">
<ul class="eval_title">
<li class="my-2">
{{ evaluation.evaluation.title|localize_translatable_string }}
<ul class="columns pt-2">
<li>
<span class="item-key">{{ 'accompanying_course_work.start_date'|trans ~ ' : ' }}</span>
<b>{{ evaluation.startDate|format_date('short') }}</b>
</li>
{% if evaluation.endDate %}
<li>
<span class="item-key">{{ 'accompanying_course_work.end_date'|trans ~ ' : ' }}</span>
<b>{{ evaluation.endDate|format_date('short') }}</b>
</li>
{% endif %}
{% if evaluation.maxDate %}
<li>
<span class="item-key">{{ 'accompanying_course_work.max_date'|trans ~ ' : ' }}</span>
<b>{{ evaluation.maxDate|format_date('short') }}</b>
</li>
{% endif %}
{% if evaluation.warningInterval and evaluation.warningInterval.d > 0 %}
<li>
{% set days = (evaluation.warningInterval.d + evaluation.warningInterval.m * 30) %}
<span class="item-key">{{ 'accompanying_course_work.warning_interval'|trans ~ ' : ' }}</span>
{{ 'accompanying_course_work.%days% days before max_date'|trans({'%days%': days }) }}
</li>
{% endif %}
<li>
{% if evaluation.createdBy is not null %}
<span class="item-key">créé par</span>
<b>{{ evaluation.createdBy.username }}</b>
{% endif %}
{% if evaluation.createdAt is not null %}
<span class="item-key">{{ 'le'|trans }}</span>
<b>{{ evaluation.createdAt|format_date('short') }}</b>
{% endif %}
</li>
</ul>
{% if evaluation.comment %}
<blockquote class="chill-user-quote" style="margin-left: 0;">
{{ evaluation.comment }}
</blockquote>
{% endif %}
</li>
</ul>
</td>
</tr>
</tbody>
</table>
</div>
<div class="item-row">
{% import '@ChillPerson/Macro/updatedBy.html.twig' as macro %}
{{ macro.updatedBy(evaluation) }}
</div>
</div>
</div>
</div>
{% if display_action is defined and display_action == true %}
{% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', evaluation.accompanyingPeriodWork) %}
<ul class="record_actions">
<li>{{ m.download_button(doc.storedObject, doc.title) }}</li>
{% if chill_document_is_editable(doc.storedObject) %}
{% if display_action is defined and display_action == true %}
{% if is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', evaluation.accompanyingPeriodWork) %}
<ul class="record_actions">
<li>{{ m.download_button(doc.storedObject, doc.title) }}</li>
{% if chill_document_is_editable(doc.storedObject) %}
<li>
{{ doc.storedObject|chill_document_edit_button }}
</li>
{% endif %}
<li>
{{ doc.storedObject|chill_document_edit_button }}
<a class="btn btn-show" href="{{ path('chill_person_accompanying_period_work_edit', {'id': evaluation.accompanyingPeriodWork.id}) }}">
{{ 'Show'|trans }}
</a>
</li>
</ul>
{% endif %}
<li>
<a class="btn btn-show" href="{{ path('chill_person_accompanying_period_work_edit', {'id': evaluation.accompanyingPeriodWork.id}) }}">
{{ 'Show'|trans }}
</a>
</li>
</ul>
{% endif %}
{% endif %}

View File

@@ -23,6 +23,7 @@ use Chill\PersonBundle\Repository\Relationships\RelationshipRepository;
use Chill\PersonBundle\Templating\Entity\PersonRenderInterface;
use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection;
use libphonenumber\PhoneNumber;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
@@ -71,6 +72,7 @@ class PersonDocGenNormalizer implements
$dateContext = $context;
$dateContext['docgen:expects'] = DateTimeInterface::class;
$addressContext = array_merge($context, ['docgen:expects' => Address::class]);
$phonenumberContext = array_merge($context, ['docgen:expects' => PhoneNumber::class]);
$personResourceContext = array_merge($context, [
'docgen:expects' => Person\PersonResource::class,
// we simplify the list of attributes for the embedded persons
@@ -113,9 +115,9 @@ class PersonDocGenNormalizer implements
'maritalStatus' => null !== ($ms = $person->getMaritalStatus()) ? $this->translatableStringHelper->localize($ms->getName()) : '',
'maritalStatusDate' => $this->normalizer->normalize($person->getMaritalStatusDate(), $format, $dateContext),
'email' => $person->getEmail(),
'firstPhoneNumber' => $this->normalizer->normalize($person->getPhonenumber() ?? $person->getMobilenumber(), $format, $context),
'fixPhoneNumber' => $this->normalizer->normalize($person->getPhonenumber(), $format, $context),
'mobilePhoneNumber' => $this->normalizer->normalize($person->getMobilenumber(), $format, $context),
'firstPhoneNumber' => $this->normalizer->normalize($person->getPhonenumber() ?? $person->getMobilenumber(), $format, $phonenumberContext),
'fixPhoneNumber' => $this->normalizer->normalize($person->getPhonenumber(), $format, $phonenumberContext),
'mobilePhoneNumber' => $this->normalizer->normalize($person->getMobilenumber(), $format, $phonenumberContext),
'nationality' => null !== ($c = $person->getNationality()) ? $this->translatableStringHelper->localize($c->getName()) : '',
'placeOfBirth' => $person->getPlaceOfBirth(),
'memo' => $person->getMemo(),

View File

@@ -40,6 +40,7 @@ class SocialActionNormalizer implements NormalizerAwareInterface, NormalizerInte
'desactivationDate' => $this->normalizer->normalize($socialAction->getDesactivationDate(), $format, $context),
'title' => $socialAction->getTitle(),
'issue' => $this->normalizer->normalize($socialAction->getIssue(), $format, $context),
'ordering' => $socialAction->getOrdering(),
];
case 'docgen':

View File

@@ -152,8 +152,25 @@ class AccompanyingPeriodContext implements
$options = $template->getOptions();
$persons = $entity->getCurrentParticipations()->map(static function (AccompanyingPeriodParticipation $p) {
return $p->getPerson();
})
->toArray();
});
foreach ($entity->getCurrentParticipations() as $p) {
foreach ($p->getPerson()->getResources() as $r) {
if (null !== $r->getPerson() && !$persons->contains($r->getPerson())) {
$persons->add($r->getPerson());
}
}
}
if (null !== $entity->getRequestorPerson() && !$persons->contains($entity->getRequestorPerson())) {
$persons->add($entity->getRequestorPerson());
}
foreach ($entity->getResources() as $r) {
if (null !== $r->getPerson() && !$persons->contains($r->getPerson())) {
$persons->add($r->getPerson());
}
}
foreach (['mainPerson', 'person1', 'person2'] as $key) {
if ($options[$key] ?? false) {

View File

@@ -14,6 +14,8 @@ namespace AccompanyingPeriod\Events;
use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Entity\Notification;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Notification\NotificationPersister;
use Chill\MainBundle\Notification\NotificationPersisterInterface;
use Chill\PersonBundle\AccompanyingPeriod\Events\PersonAddressMoveEventSubscriber;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Household\Household;
@@ -22,7 +24,6 @@ use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Event\Person\PersonAddressMoveEvent;
use DateTime;
use DateTimeImmutable;
use Doctrine\ORM\EntityManagerInterface;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use ReflectionClass;
@@ -73,9 +74,9 @@ final class PersonMoveEventSubscriberTest extends KernelTestCase
->setPreviousMembership($previousMembership)
->setNextMembership($nextMembership);
$em = $this->prophesize(EntityManagerInterface::class);
$em->persist(Argument::type(Notification::class))->shouldNotBeCalled();
$eventSubscriber = $this->buildSubscriber(null, $em->reveal(), null, null);
$notificationPersister = $this->prophesize(NotificationPersisterInterface::class);
$notificationPersister->persist(Argument::type(Notification::class))->shouldNotBeCalled();
$eventSubscriber = $this->buildSubscriber(null, $notificationPersister->reveal(), null, null);
$eventSubscriber->resetPeriodLocation($event);
}
@@ -115,9 +116,9 @@ final class PersonMoveEventSubscriberTest extends KernelTestCase
->setPreviousMembership($previousMembership)
->setNextMembership($nextMembership);
$em = $this->prophesize(EntityManagerInterface::class);
$em->persist(Argument::type(Notification::class))->shouldBeCalledTimes(1);
$eventSubscriber = $this->buildSubscriber(null, $em->reveal(), null, null);
$notificationPersister = $this->prophesize(NotificationPersisterInterface::class);
$notificationPersister->persist(Argument::type(Notification::class))->shouldBeCalledTimes(1);
$eventSubscriber = $this->buildSubscriber(null, $notificationPersister->reveal(), null, null);
$eventSubscriber->resetPeriodLocation($event);
@@ -160,9 +161,9 @@ final class PersonMoveEventSubscriberTest extends KernelTestCase
->setPreviousMembership($previousMembership)
->setNextMembership($nextMembership);
$em = $this->prophesize(EntityManagerInterface::class);
$em->persist(Argument::type(Notification::class))->shouldBeCalled(1);
$eventSubscriber = $this->buildSubscriber(null, $em->reveal(), null, null);
$notificationPersister = $this->prophesize(NotificationPersisterInterface::class);
$notificationPersister->persist(Argument::type(Notification::class))->shouldBeCalled(1);
$eventSubscriber = $this->buildSubscriber(null, $notificationPersister->reveal(), null, null);
$eventSubscriber->resetPeriodLocation($event);
@@ -195,9 +196,9 @@ final class PersonMoveEventSubscriberTest extends KernelTestCase
$event
->setPreviousMembership($previousMembership);
$em = $this->prophesize(EntityManagerInterface::class);
$em->persist(Argument::type(Notification::class))->shouldBeCalledTimes(1);
$eventSubscriber = $this->buildSubscriber(null, $em->reveal(), null, null);
$notificationPersister = $this->prophesize(NotificationPersisterInterface::class);
$notificationPersister->persist(Argument::type(Notification::class))->shouldBeCalledTimes(1);
$eventSubscriber = $this->buildSubscriber(null, $notificationPersister->reveal(), null, null);
$eventSubscriber->resetPeriodLocation($event);
@@ -235,9 +236,9 @@ final class PersonMoveEventSubscriberTest extends KernelTestCase
->setPreviousAddress($household->getPreviousAddressOf($newAddress))
->setNextAddress($newAddress);
$em = $this->prophesize(EntityManagerInterface::class);
$em->persist(Argument::type(Notification::class))->shouldBeCalledTimes(1);
$eventSubscriber = $this->buildSubscriber(null, $em->reveal(), null, null);
$notificationPersister = $this->prophesize(NotificationPersisterInterface::class);
$notificationPersister->persist(Argument::type(Notification::class))->shouldBeCalledTimes(1);
$eventSubscriber = $this->buildSubscriber(null, $notificationPersister->reveal(), null, null);
$eventSubscriber->resetPeriodLocation($event);
@@ -247,7 +248,7 @@ final class PersonMoveEventSubscriberTest extends KernelTestCase
private function buildSubscriber(
?EngineInterface $engine = null,
?EntityManagerInterface $entityManager = null,
?NotificationPersisterInterface $notificationPersister = null,
?Security $security = null,
?TranslatorInterface $translator = null
): PersonAddressMoveEventSubscriber {
@@ -267,14 +268,13 @@ final class PersonMoveEventSubscriberTest extends KernelTestCase
$engine = $double->reveal();
}
if (null === $entityManager) {
$double = $this->prophesize(EntityManagerInterface::class);
$entityManager = $double->reveal();
if (null === $notificationPersister) {
$notificationPersister = new NotificationPersister();
}
return new PersonAddressMoveEventSubscriber(
$engine,
$entityManager,
$notificationPersister,
$security,
$translator
);

View File

@@ -13,6 +13,7 @@ namespace Chill\PersonBundle\Tests\Entity;
use ArrayIterator;
use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
use Chill\PersonBundle\Entity\AccompanyingPeriodParticipation;
@@ -62,6 +63,29 @@ final class AccompanyingPeriodTest extends \PHPUnit\Framework\TestCase
$this->assertFalse($period->isClosingAfterOpening());
}
public function testHasChangedUser()
{
$period = new AccompanyingPeriod();
$this->assertFalse($period->isChangedUser());
$this->assertFalse($period->hasPreviousUser());
$period->setUser($user1 = new User());
$this->assertTrue($period->isChangedUser());
$this->assertFalse($period->hasPreviousUser());
$period->resetPreviousUser();
$this->assertFalse($period->isChangedUser());
$this->assertFalse($period->hasPreviousUser());
$period->setUser($user2 = new User());
$this->assertTrue($period->isChangedUser());
$this->assertTrue($period->hasPreviousUser());
$this->assertSame($user1, $period->getPreviousUser());
}
public function testHistoryLocation()
{
$period = new AccompanyingPeriod();

View File

@@ -48,6 +48,12 @@ class AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler implements EntityW
{
$doc = $this->getRelatedEntity($entityWorkflow);
if (null === $doc) {
return [
'persons' => [],
];
}
return [
'persons' => $doc->getAccompanyingPeriodWorkEvaluation()
->getAccompanyingPeriodWork()->getPersons(),
@@ -58,6 +64,10 @@ class AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler implements EntityW
{
$doc = $this->getRelatedEntity($entityWorkflow);
if (null === $doc) {
return $this->translator->trans('workflow.doc for evaluation deleted');
}
return $this->translator->trans(
'workflow.Doc for evaluation (n°%eval%)',
['%eval%' => $entityWorkflow->getRelatedEntityId()]
@@ -98,7 +108,7 @@ class AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler implements EntityW
return [
'entity_workflow' => $entityWorkflow,
'evaluation' => $doc->getAccompanyingPeriodWorkEvaluation(),
'evaluation' => null !== $doc ? $doc->getAccompanyingPeriodWorkEvaluation() : $doc,
'doc' => $doc,
];
}

View File

@@ -114,3 +114,19 @@ household_composition:
few {# enfants dans le ménage}
other {# enfants dans le ménage}
}
periods:
show closed periods: >-
{nb_items, plural,
=0 {Aucun parcours clôturé}
one {Montrer un parcours clôturé}
many {Montrer # parcours clôturés}
other {Montrer # parcours clôturés}
}
hide closed periods: >-
{nb_items, plural,
=0 {Aucun parcours clôturé}
one {Masquer un parcours clôturé}
many {Masquer # parcours clôturés}
other {Masquer # parcours clôturés}
}

View File

@@ -214,7 +214,7 @@ No requestor: Pas de demandeur
No resources: "Pas d'interlocuteurs privilégiés"
Persons associated: Usagers concernés
Referrer: Référent
Referrers: Référents
Referrers: Agents traitants
Some peoples does not belong to any household currently. Add them to an household soon: Certaines personnes n'appartiennent à aucun ménage actuellement. Renseignez leur ménage dès que possible.
Add to household now: Ajouter à un ménage
Any resource for this accompanying course: Aucun interlocuteur privilégié pour ce parcours
@@ -465,6 +465,9 @@ fix it: Compléter
accompanying_course:
administrative_location: Localisation administrative
comment is pinned: Le commentaire est épinglé
show: Montrer
hide: Masquer
closed periods: parcours clôturer
# Accompanying Course comments
Accompanying Course Comment: Commentaire
@@ -498,6 +501,9 @@ Concerns household n°%id%: Concerne le ménage n°%id%
Composition: Composition
Budget: Budget
The composition has been successfully removed.: La composition a été supprimée.
edit address valid from: Modifier la date du déménagement
Edit household address valid from: Modifier la date du déménagement
# accompanying course work
Accompanying Course Actions: Actions d'accompagnements
@@ -578,9 +584,11 @@ Linked evaluations: Évaluations associées
# Accompanying period per user
My accompanying periods: Mes parcours
My accompanying periods in draft: Mes parcours brouillons
Number of periods: Nombre de parcours
workflow:
Doc for evaluation (n°%eval%): Document de l'évaluation n°%eval%
doc for evaluation deleted: Document supprimé dans une évaluation
period_by_user_list:
Period by user: Parcours d'accompagnement par utilisateur

View File

@@ -57,4 +57,8 @@ Only the referrer can change the confidentiality of a parcours: 'Seul le référ
# resource
You must associate at least one entity: Associez un usager, un tiers ou indiquez une description libre
You cannot associate a resource with the same person: Vous ne pouvez pas ajouter la personne elle-même en tant que ressource.
You cannot associate a resource with the same person: Vous ne pouvez pas ajouter la personne elle-même en tant que ressource.
#location
The period must remain located: 'Un parcours doit être localisé'
The person where the course is located must be associated to the course. Change course's location before removing the person.: "Le parcours est localisé auprès cet usager. Veuillez changer la localisation du parcours avant de suprimer l'usager"