mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge remote-tracking branch 'origin/master' into features/create-social-action
This commit is contained in:
commit
50be29308d
@ -1,4 +1,5 @@
|
||||
<template>
|
||||
<div class="chill_address_address chill_address_address--multiline">
|
||||
<div v-if="address.text">
|
||||
{{ address.text }}
|
||||
</div>
|
||||
@ -28,7 +29,8 @@
|
||||
</div>
|
||||
<div v-if="address.distribution">
|
||||
<span>{{ $t('distribution') }}</span>: {{ address.distribution }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
namespace Chill\PersonBundle\Controller;
|
||||
|
||||
use Chill\PersonBundle\Form\HouseholdType;
|
||||
use Chill\MainBundle\Entity\Address;
|
||||
use Chill\PersonBundle\Form\HouseholdType;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
@ -13,6 +13,7 @@ use Symfony\Component\Translation\TranslatorInterface;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
||||
use Chill\PersonBundle\Entity\Household\Household;
|
||||
use Chill\PersonBundle\Entity\Household\Position;
|
||||
use Chill\PersonBundle\Repository\Household\PositionRepository;
|
||||
|
||||
/**
|
||||
* @Route("/{_locale}/person/household")
|
||||
@ -21,12 +22,13 @@ class HouseholdController extends AbstractController
|
||||
{
|
||||
private TranslatorInterface $translator;
|
||||
|
||||
/**
|
||||
* @param TranslatorInterface $translator
|
||||
*/
|
||||
public function __construct(TranslatorInterface $translator)
|
||||
private PositionRepository $positionRepository;
|
||||
|
||||
public function __construct(TranslatorInterface $translator, PositionRepository $positionRepository)
|
||||
|
||||
{
|
||||
$this->translator = $translator;
|
||||
$this->positionRepository = $positionRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -41,37 +43,8 @@ class HouseholdController extends AbstractController
|
||||
{
|
||||
// TODO ACL
|
||||
|
||||
$positions = $this->getDoctrine()->getManager()
|
||||
->getRepository(Position::class)
|
||||
->findAll()
|
||||
;
|
||||
|
||||
// little performance improvement:
|
||||
// initialize members collection, which will avoid
|
||||
// some queries
|
||||
$household->getMembers()->initialize();
|
||||
return $this->render('@ChillPerson/Household/summary.html.twig',
|
||||
[
|
||||
'household' => $household,
|
||||
'positions' => $positions
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* "/{household_id}/members",
|
||||
* name="chill_person_household_members",
|
||||
* methods={"GET", "HEAD"}
|
||||
* )
|
||||
* @ParamConverter("household", options={"id" = "household_id"})
|
||||
*/
|
||||
public function members(Request $request, Household $household)
|
||||
{
|
||||
// TODO ACL
|
||||
$positions = $this->getDoctrine()->getManager()
|
||||
->getRepository(Position::class)
|
||||
->findAll()
|
||||
$positions = $this->positionRepository
|
||||
->findByActiveOrdered()
|
||||
;
|
||||
|
||||
// little performance improvement:
|
||||
@ -85,11 +58,11 @@ class HouseholdController extends AbstractController
|
||||
$form = null;
|
||||
}
|
||||
|
||||
return $this->render('@ChillPerson/Household/members.html.twig',
|
||||
return $this->render('@ChillPerson/Household/summary.html.twig',
|
||||
[
|
||||
'household' => $household,
|
||||
'positions' => $positions,
|
||||
'form' => NULL !== $form ? $form->createView(): $form
|
||||
'form' => NULL !== $form ? $form->createView() : null,
|
||||
]
|
||||
);
|
||||
}
|
||||
@ -142,6 +115,28 @@ class HouseholdController extends AbstractController
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* "/{household_id}/address/edit",
|
||||
* name="chill_person_household_address_edit",
|
||||
* methods={"GET", "HEAD", "POST"}
|
||||
* )
|
||||
* @ParamConverter("household", options={"id" = "household_id"})
|
||||
*/
|
||||
public function addressEdit(Request $request, Household $household)
|
||||
{
|
||||
// TODO ACL
|
||||
//$address = $this->findAddressById($household, $address_id); //TODO
|
||||
|
||||
|
||||
return $this->render('@ChillPerson/Household/address_edit.html.twig',
|
||||
[
|
||||
'household' => $household,
|
||||
//'address' => $address,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* "/{household_id}/members/metadata/edit",
|
||||
@ -162,7 +157,7 @@ class HouseholdController extends AbstractController
|
||||
|
||||
$this->addFlash('success', $this->translator->trans('household.data_saved'));
|
||||
|
||||
return $this->redirectToRoute('chill_person_household_members', [
|
||||
return $this->redirectToRoute('chill_person_household_summary', [
|
||||
'household_id' => $household->getId()
|
||||
]);
|
||||
}
|
||||
@ -191,25 +186,4 @@ class HouseholdController extends AbstractController
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* "/{household_id}/address/edit",
|
||||
* name="chill_person_household_address_edit",
|
||||
* methods={"GET", "HEAD", "POST"}
|
||||
* )
|
||||
* @ParamConverter("household", options={"id" = "household_id"})
|
||||
*/
|
||||
public function addressEdit(Request $request, Household $household)
|
||||
{
|
||||
// TODO ACL
|
||||
//$address = $this->findAddressById($household, $address_id); //TODO
|
||||
|
||||
|
||||
return $this->render('@ChillPerson/Household/address_edit.html.twig',
|
||||
[
|
||||
'household' => $household,
|
||||
//'address' => $address,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ class HouseholdMemberController extends ApiController
|
||||
|
||||
return $this->redirect(
|
||||
$request->get('returnPath', null) ??
|
||||
$this->generator->generate('chill_person_household_members', [ 'household_id' =>
|
||||
$this->generator->generate('chill_person_household_summary', [ 'household_id' =>
|
||||
$member->getHousehold()->getId() ])
|
||||
);
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ class Household
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
* @Serializer\Groups({"write"})
|
||||
* @Serializer\Groups({"read"})
|
||||
*/
|
||||
private ?int $id = null;
|
||||
|
||||
@ -196,6 +196,11 @@ class Household
|
||||
}
|
||||
|
||||
public function getCurrentMembers(?\DateTimeImmutable $now = null): Collection
|
||||
{
|
||||
return $this->getMembers()->matching($this->buildCriteriaCurrentMembers($now));
|
||||
}
|
||||
|
||||
private function buildCriteriaCurrentMembers(?\DateTimeImmutable $now = null): Criteria
|
||||
{
|
||||
$criteria = new Criteria();
|
||||
$expr = Criteria::expr();
|
||||
@ -211,7 +216,53 @@ class Household
|
||||
$expr->gte('endDate', $date)
|
||||
));
|
||||
|
||||
return $this->getMembers()->matching($criteria);
|
||||
return $criteria;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HouseholdMember[]
|
||||
*/
|
||||
public function getCurrentMembersOrdered(?\DateTimeImmutable $now = null): Collection
|
||||
{
|
||||
$members = $this->getCurrentMembers($now);
|
||||
|
||||
$members->getIterator()
|
||||
->uasort(
|
||||
function (HouseholdMember $a, HouseholdMember $b) {
|
||||
if ($a->getPosition()->getOrdering() < $b->getPosition()->getOrdering()) {
|
||||
return -1;
|
||||
}
|
||||
if ($a->getPosition()->getOrdering() > $b->getPosition()->getOrdering()) {
|
||||
return 1;
|
||||
}
|
||||
if ($a->isHolder() && !$b->isHolder()) {
|
||||
return 1;
|
||||
}
|
||||
if (!$a->isHolder() && $b->isHolder()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
);
|
||||
|
||||
return $members;
|
||||
}
|
||||
|
||||
/**
|
||||
* get current members ids
|
||||
*
|
||||
* Used in serialization
|
||||
*
|
||||
* @Serializer\Groups({"read"})
|
||||
* @Serializer\SerializedName("current_members_id")
|
||||
*
|
||||
*/
|
||||
public function getCurrentMembersIds(?\DateTimeImmutable $now = null): Collection
|
||||
{
|
||||
return $this->getCurrentMembers($now)->map(
|
||||
fn (HouseholdMember $m) => $m->getId()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1264,15 +1264,24 @@ class Person implements HasCenterInterface
|
||||
}
|
||||
|
||||
public function getCurrentHousehold(?\DateTimeImmutable $at = null): ?Household
|
||||
{
|
||||
$participation = $this->getCurrentHouseholdParticipationShareHousehold($at);
|
||||
|
||||
return $participation instanceof HouseholdMember ?
|
||||
$participation->getHousehold()
|
||||
: null;
|
||||
}
|
||||
|
||||
public function getCurrentHouseholdParticipationShareHousehold(?\DateTimeImmutable $at = null): ?HouseholdMember
|
||||
{
|
||||
$criteria = new Criteria();
|
||||
$expr = Criteria::expr();
|
||||
$date = NULL === $at ? new \DateTimeImmutable('now') : $at;
|
||||
$date = NULL === $at ? new \DateTimeImmutable('today') : $at;
|
||||
$datef = $date->format('Y-m-d');
|
||||
|
||||
if (
|
||||
NULL !== ($this->currentHouseholdAt[$datef] ?? NULL)) {
|
||||
return $this->currentHouseholdAt[$datef];
|
||||
NULL !== ($this->currentHouseholdParticipationAt[$datef] ?? NULL)) {
|
||||
return $this->currentHouseholdParticipationAt[$datef];
|
||||
}
|
||||
|
||||
$criteria
|
||||
@ -1281,7 +1290,7 @@ class Person implements HasCenterInterface
|
||||
$expr->lte('startDate', $date),
|
||||
$expr->orX(
|
||||
$expr->isNull('endDate'),
|
||||
$expr->gte('endDate', $date)
|
||||
$expr->gt('endDate', $date)
|
||||
),
|
||||
$expr->eq('shareHousehold', true)
|
||||
)
|
||||
@ -1292,8 +1301,7 @@ class Person implements HasCenterInterface
|
||||
;
|
||||
|
||||
return $participations->count() > 0 ?
|
||||
$this->currentHouseholdAt[$datef] = $participations->first()
|
||||
->getHousehold()
|
||||
$this->currentHouseholdParticipationAt[$datef] = $participations->first()
|
||||
: null;
|
||||
}
|
||||
|
||||
|
@ -35,13 +35,6 @@ class HouseholdMenuBuilder implements LocalMenuBuilderInterface
|
||||
'household_id' => $household->getId()
|
||||
]])
|
||||
->setExtras(['order' => 10]);
|
||||
|
||||
$menu->addChild($this->translator->trans('household.Household members'), [
|
||||
'route' => 'chill_person_household_members',
|
||||
'routeParameters' => [
|
||||
'household_id' => $household->getId()
|
||||
]])
|
||||
->setExtras(['order' => 20]);
|
||||
|
||||
$menu->addChild($this->translator->trans('household.Addresses'), [
|
||||
'route' => 'chill_person_household_addresses',
|
||||
|
@ -7,14 +7,9 @@ use Chill\PersonBundle\Entity\Household\Position;
|
||||
//use Doctrine\Persistence\ManagerRegistry;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
|
||||
/**
|
||||
* @method Position|null find($id, $lockMode = null, $lockVersion = null)
|
||||
* @method Position|null findOneBy(array $criteria, array $orderBy = null)
|
||||
* @method Position[] findAll()
|
||||
* @method Position[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||
*/
|
||||
final class PositionRepository
|
||||
final class PositionRepository implements ObjectRepository
|
||||
{
|
||||
private EntityRepository $repository;
|
||||
|
||||
@ -30,4 +25,45 @@ final class PositionRepository
|
||||
{
|
||||
return $this->repository->findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Position[]
|
||||
*/
|
||||
public function findByActiveOrdered(): array
|
||||
{
|
||||
return $this->repository->createQueryBuilder('p')
|
||||
->select('p')
|
||||
->orderBy('p.ordering', 'ASC')
|
||||
->getQuery()
|
||||
->getResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Position[]
|
||||
*/
|
||||
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): array
|
||||
{
|
||||
return $this->repository->findBy($criteria, $orderBy, $limit, $offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Position[]
|
||||
*/
|
||||
public function findOneBy(array $criteria): array
|
||||
{
|
||||
return $this->repository->findOneBy($criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Position
|
||||
*/
|
||||
public function find($id)
|
||||
{
|
||||
return $this->repository->find($id);
|
||||
}
|
||||
|
||||
public function getClassName()
|
||||
{
|
||||
return Position::class;
|
||||
}
|
||||
}
|
||||
|
@ -1,2 +1,3 @@
|
||||
require('./sass/person.scss');
|
||||
require('./sass/person_with_period.scss');
|
||||
require('./sass/household_banner.scss');
|
||||
|
@ -0,0 +1,5 @@
|
||||
.banner-household {
|
||||
.current-members-explain {
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
/// complete and overwrite flex-table in chillmain.scss
|
||||
div.list-with-period,
|
||||
div.list-household-members,
|
||||
div.list-household-members--summary {
|
||||
div.list-household-members {
|
||||
|
||||
.chill-entity__person {
|
||||
.chill-entity__person__first-name,
|
||||
|
@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<household></household>
|
||||
<concerned></concerned>
|
||||
<dates></dates>
|
||||
<confirmation></confirmation>
|
||||
<concerned v-if="hasHouseholdOrLeave"></concerned>
|
||||
<dates v-if="showConfirm"></dates>
|
||||
<confirmation v-if="showConfirm"></confirmation>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { mapState } from 'vuex';
|
||||
import { mapGetters } from 'vuex';
|
||||
import Concerned from './components/Concerned.vue';
|
||||
import Household from './components/Household.vue';
|
||||
import Dates from './components/Dates.vue';
|
||||
@ -22,11 +22,14 @@ export default {
|
||||
Confirmation,
|
||||
},
|
||||
computed: {
|
||||
// for debugging purpose
|
||||
// (not working)
|
||||
//...mapState({
|
||||
// 'concerned', 'household', 'positions'
|
||||
// })
|
||||
...mapGetters([
|
||||
'hasHouseholdOrLeave',
|
||||
'hasPersonsWellPositionnated',
|
||||
]),
|
||||
showConfirm () {
|
||||
return this.$store.getters.hasHouseholdOrLeave
|
||||
&& this.$store.getters.hasPersonsWellPositionnated;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,13 +21,10 @@
|
||||
<div v-for="conc in concUnpositionned"
|
||||
class="item-bloc"
|
||||
v-bind:key="conc.person.id"
|
||||
draggable="true"
|
||||
@dragstart="onStartDragConcern($event, conc.person.id)"
|
||||
>
|
||||
<div class="item-row person">
|
||||
<div class="item-col box-person">
|
||||
<div>
|
||||
<img src="~ChillMainAssets/img/draggable.svg" class="drag-icon" />
|
||||
<person :person="conc.person"></person>
|
||||
</div>
|
||||
<div v-if="conc.person.birthdate !== null">
|
||||
@ -89,21 +86,18 @@
|
||||
v-for="position in positions"
|
||||
>
|
||||
<h3>{{ position.label.fr }}</h3>
|
||||
<div class="flex-table list-household-members">
|
||||
|
||||
<div v-if="concByPosition(position.id).length > 0" class="flex-table list-household-members">
|
||||
<member-details
|
||||
v-for="conc in concByPosition(position.id)"
|
||||
v-bind:key="conc.person.id"
|
||||
v-bind:conc="conc"
|
||||
>
|
||||
</member-details>
|
||||
<div
|
||||
class="droppable_zone"
|
||||
@drop="onDropConcern($event, position.id)"
|
||||
@dragover.prevent
|
||||
@dragenter.prevent
|
||||
>
|
||||
{{ $t('household_members_editor.drop_persons_here', {'position': position.label.fr }) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<p class="chill-no-data-statement">{{ $t('household_members_editor.concerned.no_person_in_position') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -120,22 +114,6 @@ div.person {
|
||||
}
|
||||
}
|
||||
|
||||
.drag-icon {
|
||||
height: 1.1em;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.droppable_zone {
|
||||
background-color: var(--chill-llight-gray);
|
||||
color: white;
|
||||
font-size: large;
|
||||
text-align: center;
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
padding: 1em;
|
||||
background: linear-gradient(to top, var(--chill-light-gray), 30%, var(--chill-llight-gray));
|
||||
}
|
||||
|
||||
.move_to {
|
||||
.move_hint {
|
||||
text-align: center;
|
||||
@ -194,18 +172,8 @@ export default {
|
||||
this.$refs.addPersons.resetSearch(); // to cast child method
|
||||
modal.showModal = false;
|
||||
},
|
||||
onStartDragConcern(evt, person_id) {
|
||||
evt.dataTransfer.dropEffect = 'move'
|
||||
evt.dataTransfer.effectAllowed = 'move'
|
||||
evt.dataTransfer.setData('application/x.person', person_id)
|
||||
},
|
||||
onDropConcern(evt, position_id) {
|
||||
const person_id = Number(evt.dataTransfer.getData('application/x.person'));
|
||||
this.moveToPosition(person_id, position_id);
|
||||
},
|
||||
moveToPosition(person_id, position_id) {
|
||||
this.$store.dispatch('markPosition', { person_id, position_id });
|
||||
|
||||
},
|
||||
removeConcerned(conc) {
|
||||
this.$store.dispatch('removeConcerned', conc);
|
||||
|
@ -2,11 +2,8 @@
|
||||
<h2>{{ $t('household_members_editor.household_part') }}</h2>
|
||||
|
||||
<div v-if="hasHousehold">
|
||||
<span v-if="isHouseholdNew">
|
||||
{{ $t('household_members_editor.household.new_household') }}
|
||||
</span>
|
||||
<div v-else>
|
||||
Ménage existant
|
||||
<div>
|
||||
<household-viewer :household="household"></household-viewer>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="isForceLeaveWithoutHousehold">
|
||||
@ -39,16 +36,20 @@
|
||||
<script>
|
||||
|
||||
import { mapGetters } from 'vuex';
|
||||
import HouseholdViewer from 'ChillPersonAssets/vuejs/_components/Household/Household.vue';
|
||||
|
||||
export default {
|
||||
name: 'Household',
|
||||
components: {
|
||||
HouseholdViewer,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'hasHousehold',
|
||||
'isHouseholdNew',
|
||||
]),
|
||||
household() {
|
||||
return this.$store.household;
|
||||
return this.$store.state.household;
|
||||
},
|
||||
allowHouseholdCreate() {
|
||||
return this.$store.state.allowHouseholdCreate;
|
||||
|
@ -19,12 +19,13 @@ const appMessages = {
|
||||
move_to: "Déplacer vers",
|
||||
persons_to_positionnate: 'Usagers à positionner',
|
||||
persons_leaving: "Usagers quittant leurs ménages",
|
||||
no_person_in_position: "Aucun usager ne sera ajouté à cette position",
|
||||
},
|
||||
drop_persons_here: "Glissez-déposez ici les usagers pour la position \"{position}\"",
|
||||
all_positionnated: "Tous les usagers sont positionnés",
|
||||
holder: "Titulaire",
|
||||
is_holder: "Sera titulaire",
|
||||
is_not_holder: "Ne sera pas titulaire",
|
||||
is_holder: "Est titulaire",
|
||||
is_not_holder: "N'est pas titulaire",
|
||||
remove_position: "Retirer des {position}",
|
||||
remove_concerned: "Ne plus transférer",
|
||||
household_part: "Ménage de destination",
|
||||
|
@ -19,7 +19,15 @@ const store = createStore({
|
||||
state: {
|
||||
concerned,
|
||||
household: window.household_members_editor_data.household,
|
||||
positions: window.household_members_editor_data.positions,
|
||||
positions: window.household_members_editor_data.positions.sort((a, b) => {
|
||||
if (a.ordering < b.ordering) {
|
||||
return -1;
|
||||
}
|
||||
if (a.ordering > b.ordering) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}),
|
||||
startDate: new Date(),
|
||||
allowHouseholdCreate: window.household_members_editor_data.allowHouseholdCreate,
|
||||
allowHouseholdSearch: window.household_members_editor_data.allowHouseholdSearch,
|
||||
@ -35,6 +43,13 @@ const store = createStore({
|
||||
hasHousehold(state) {
|
||||
return state.household !== null;
|
||||
},
|
||||
hasHouseholdOrLeave(state) {
|
||||
return state.household !== null || state.forceLeaveWithoutHousehold;
|
||||
},
|
||||
hasPersonsWellPositionnated(state, getters) {
|
||||
return getters.needsPositionning === false
|
||||
|| (getters.persons.length > 0 && getters.concUnpositionned.length === 0);
|
||||
},
|
||||
persons(state) {
|
||||
return state.concerned.map(conc => conc.person);
|
||||
},
|
||||
@ -150,7 +165,7 @@ const store = createStore({
|
||||
)
|
||||
},
|
||||
createHousehold(state) {
|
||||
state.household = { type: 'household', members: [], address: null }
|
||||
state.household = { type: 'household', members: [], current_address: null }
|
||||
state.forceLeaveWithoutHousehold = false;
|
||||
},
|
||||
forceLeaveWithoutHousehold(state) {
|
||||
|
@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<div class="chill-entity chill-entity__household">
|
||||
<!-- identifier -->
|
||||
<div v-if="isHouseholdNew()" class="identifier">
|
||||
<i class="fa fa-home"></i>
|
||||
{{ $t('new_household') }}
|
||||
</div>
|
||||
<div v-else class="identifier">
|
||||
<i class="fa fa-home"></i>
|
||||
{{ $t('household_number', { number: household.id } ) }}
|
||||
</div>
|
||||
|
||||
<!-- member part -->
|
||||
<div v-if="hasCurrentMembers" class="members">
|
||||
<span class="current-members">{{ $t('current_members') }}: </span>
|
||||
<template v-for="(m, index) in currentMembers()" :key="m.id">
|
||||
<person :person="m.person"></person>
|
||||
<span v-if="m.holder">
|
||||
<span class="badge badge-primary">{{ $t('holder') }}</span>
|
||||
</span>
|
||||
<span v-if="index != (currentMembersLength() - 1)">, </span>
|
||||
</template>
|
||||
</div>
|
||||
<div v-else class="members">
|
||||
<p class="chill-no-data-statement">{{ $t('no_members_yet') }}</p>
|
||||
</div>
|
||||
|
||||
<!-- address part -->
|
||||
<div v-if="hasAddress()" class="where">
|
||||
<i class="fa fa-where"></i>
|
||||
<show-address :address="household.current_address"></show-address>
|
||||
</div>
|
||||
<div v-else class="where">
|
||||
<i class="fa fa-where"></i>
|
||||
<p class="chill-no-data-statement">{{ $t('no_current_address') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.chill-entity__household {
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"identifier identifier where"
|
||||
"who who where"
|
||||
;
|
||||
grid-template-columns:
|
||||
auto auto 30%
|
||||
;
|
||||
|
||||
.identifier {
|
||||
grid-area: identifier;
|
||||
|
||||
font-size: 1.3em;
|
||||
font-weight: 700;
|
||||
color: var(--chill-blue);
|
||||
|
||||
}
|
||||
.members {
|
||||
grid-area: who;
|
||||
|
||||
.current-members {
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
.where {
|
||||
grid-area: where
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
import Person from 'ChillPersonAssets/vuejs/_components/Person/Person.vue';
|
||||
import ShowAddress from 'ChillMainAssets/vuejs/_components/ShowAddress.vue';
|
||||
|
||||
const i18n = {
|
||||
"messages":
|
||||
{
|
||||
"fr":
|
||||
{
|
||||
"household_number": "Ménage #{number}",
|
||||
"current_members": "Membres actuels",
|
||||
"no_current_address": "Sans adresse actuellement",
|
||||
"new_household": "Nouveau ménage",
|
||||
"no_members_yet": "Aucun membre actuellement",
|
||||
"holder": "titulaire",
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
export default {
|
||||
name: 'Household',
|
||||
props: ['household'],
|
||||
components: {
|
||||
Person,
|
||||
ShowAddress,
|
||||
},
|
||||
i18n,
|
||||
methods: {
|
||||
hasCurrentMembers() {
|
||||
return this.household.current_members_id.length > 0;
|
||||
},
|
||||
currentMembers() {
|
||||
return this.household.members.filter(m => this.household.current_members_id.includes(m.id))
|
||||
.sort((a, b) => {
|
||||
if (a.position.ordering < b.position.ordering) {
|
||||
return -1;
|
||||
}
|
||||
if (a.position.ordering > b.position.ordering) {
|
||||
return 1;
|
||||
}
|
||||
if (a.holder && !b.holder) {
|
||||
return -1;
|
||||
}
|
||||
if (!a.holder && b.holder) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
},
|
||||
currentMembersLength() {
|
||||
return this.household.current_members_id.length;
|
||||
},
|
||||
isHouseholdNew() {
|
||||
return !Number.isInteger(this.household.id);
|
||||
},
|
||||
hasAddress() {
|
||||
return this.household.current_address !== null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
@ -12,7 +12,7 @@
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
<li class="cancel">
|
||||
<a
|
||||
href="{{ chill_return_path_or('chill_person_household_members', { 'household_id': household.id}) }}"
|
||||
href="{{ chill_return_path_or('chill_person_household_summary', { 'household_id': household.id}) }}"
|
||||
class="sc-button bt-cancel"
|
||||
>
|
||||
{{ 'Cancel'|trans }}
|
||||
|
@ -12,25 +12,35 @@
|
||||
|
||||
<div class="grid-3" id="banner-flags"></div>
|
||||
|
||||
<div class="grid-3" id="banner-status"></div>
|
||||
<div class="grid-3" id="banner-status">
|
||||
{% set address = household.currentAddress %}
|
||||
{% if address is empty %}
|
||||
<p class="chill-no-data-statement">{{ 'household.Household does not have any address currently'|trans }}</p>
|
||||
{% else %}
|
||||
<div>
|
||||
{{ address|chill_entity_render_box({'multiline': true, 'with_valid_from': false}) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid-12 parent" id="header-accompanying_course-details" >
|
||||
<div class="grid-10 push-1 grid-mobile-12 grid-tablet-12 push-mobile-0 push-tablet-0 parent">
|
||||
<div id="banner-misc">
|
||||
{%- set persons = household.getCurrentPersons() -%}
|
||||
{%- if persons|length > 0 -%}
|
||||
{%- set members = household.getCurrentMembersOrdered() -%}
|
||||
{%- if members|length > 0 -%}
|
||||
<span class="current-members-explain">
|
||||
{{- 'household.Current household members'|trans }}:
|
||||
</span>
|
||||
{%- for p in persons|slice(0, 5) -%}
|
||||
{{- p|chill_entity_render_box({'addLink': false}) -}}
|
||||
{%- for m in members|slice(0, 5) -%}
|
||||
{{- m.person|chill_entity_render_box({'addLink': false}) -}}
|
||||
{%- if m.holder %} <span class="badge badge-primary">{{ 'household.holder'|trans }}</span>{% endif -%}
|
||||
{%- if false == loop.last -%}, {% endif -%}
|
||||
{%- endfor -%}
|
||||
{% if persons|length > 5 %}
|
||||
{% if members|length > 5 %}
|
||||
<span class="current-members-more">
|
||||
{{ 'household.and x other persons'|trans({'x': persons|length-5}) }}
|
||||
{{ 'household.and x other persons'|trans({'x': members|length-5}) }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{%- endif -%}
|
||||
|
@ -5,49 +5,233 @@
|
||||
{% block content %}
|
||||
<h1>{{ block('title') }}</h1>
|
||||
|
||||
<h2>{{ 'household.Current household members'|trans }}</h2>
|
||||
<h2>{{ 'household.Current address'|trans }}</h2>
|
||||
|
||||
{% set address = household.currentAddress %}
|
||||
|
||||
{% if address is empty %}
|
||||
<p class="chill-no-data-statement">{{ 'household.Household does not have any address currently'|trans }}</p>
|
||||
{% else %}
|
||||
<div>
|
||||
{{ address|chill_entity_render_box({'multiline': true}) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<h2>{{ 'household.Household members'|trans }}</h2>
|
||||
|
||||
{% if form is not null %}
|
||||
{{ form_start(form) }}
|
||||
|
||||
{{ form_row(form.commentMembers) }}
|
||||
|
||||
<div id="waitingForBirthContainer">
|
||||
{{ form_row(form.waitingForBirth) }}
|
||||
</div>
|
||||
|
||||
<div id="waitingForBirthDateContainer">
|
||||
{{ form_row(form.waitingForBirthDate) }}
|
||||
</div>
|
||||
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<button type="submit" class="sc-button bt-save">
|
||||
{{ 'Save'|trans }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{{ form_end(form) }}
|
||||
{% else %}
|
||||
|
||||
{% if not household.commentMembers.isEmpty() %}
|
||||
{{ household.commentMembers|chill_entity_render_box }}
|
||||
{% endif %}
|
||||
|
||||
{% if household.waitingForBirth %}
|
||||
{% if household.waitingForBirthDate is not null %}
|
||||
{{ 'household.Expecting for birth on date'|trans({ 'date': household.waitingForBirthDate|format_date('long') }) }}
|
||||
{% else %}
|
||||
{{ 'household.Expecting for birth'|trans }}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<p class="chill-no-data-statement">
|
||||
{{ 'household.Any expecting birth'|trans }}
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a
|
||||
href="{{ chill_path_add_return_path('chill_person_household_summary', { 'household_id': household.id, 'edit': 1 }) }}"
|
||||
class="sc-button bt-edit"
|
||||
>
|
||||
{{ 'household.Comment and expecting birth'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% for p in positions %}
|
||||
{%- set members = household.currentMembersByPosition(p) %}
|
||||
{% if members|length > 0 %}
|
||||
<h3>{{ p.label|localize_translatable_string }}</h3>
|
||||
<h3>{{ p.label|localize_translatable_string }}</h3>
|
||||
|
||||
{% if false == p.shareHousehold %}
|
||||
<p>{{ 'household.Those members does not share address'|trans }}</p>
|
||||
{% endif %}
|
||||
{% if false == p.shareHousehold %}
|
||||
<p>{{ 'household.Those members does not share address'|trans }}</p>
|
||||
{% endif %}
|
||||
|
||||
<div class="flex-table list-household-members--summary">
|
||||
{% for m in members %}
|
||||
<div class="item-bloc">
|
||||
<div class="item-row person">
|
||||
<div class="item-col box-person">
|
||||
<div>
|
||||
{{ m.person|chill_entity_render_box({'addLink': true}) }}
|
||||
{% if m.holder %}
|
||||
<span class="badge badge-primary">{{ 'household.holder'|trans }}</span>
|
||||
{%- set members = household.currentMembersByPosition(p) %}
|
||||
{% if members|length > 0 %}
|
||||
<div class="flex-table list-household-members">
|
||||
{% for m in members %}
|
||||
<div class="item-bloc">
|
||||
<div class="item-row person">
|
||||
<div class="item-col box-person">
|
||||
<div>
|
||||
{{ m.person|chill_entity_render_box({'addLink': true}) }}
|
||||
{% if m.holder %}
|
||||
<span class="badge badge-primary">{{ 'household.holder'|trans }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div>
|
||||
{{ 'Born the date'|trans({ 'gender': m.person.gender, 'birthdate': m.person.birthdate|format_date('long') }) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-col box-where">
|
||||
<ul class="list-content fa-ul">
|
||||
{% if m.startDate is not empty %}
|
||||
<li>{{ 'Since %date%'|trans({'%date%': m.startDate|format_date('long') }) }}</li>
|
||||
{% endif %}
|
||||
{% if m.endDate is not empty %}
|
||||
<li>{{ 'Until %date%'|trans({'%date%': m.endDate|format_date('long') }) }}</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a
|
||||
href="{{ chill_path_add_return_path('chill_person_household_member_edit', { 'id': m.id }) }}"
|
||||
class="sc-button bt-edit"
|
||||
/>
|
||||
{{ 'household.Update membership'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="{{ chill_path_add_return_path(
|
||||
'chill_person_household_members_editor',
|
||||
{
|
||||
'persons': [ m.person.id ],
|
||||
'household': household.id
|
||||
} ) }}"
|
||||
class="sc-button"
|
||||
/>
|
||||
<i class="fa fa-arrows-h"></i>
|
||||
{{ 'household.Change position'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="{{ chill_path_add_return_path(
|
||||
'chill_person_household_members_editor',
|
||||
{
|
||||
'persons': [ m.person.id ],
|
||||
'allow_leave_without_household': true
|
||||
} ) }}"
|
||||
class="sc-button"
|
||||
/>
|
||||
<i class="fa fa-sign-out"></i>
|
||||
{{ 'household.Leave'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{% if m.comment is not empty %}
|
||||
<div class="item-row comment">
|
||||
<blockquote class="chill-user-quote">
|
||||
{{ m.comment|chill_markdown_to_html }}
|
||||
</blockquote>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div>
|
||||
{{ 'Born the date'|trans({ 'gender': m.person.gender, 'birthdate': m.person.birthdate|format_date('long') }) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-col box-where">
|
||||
<ul class="list-content fa-ul">
|
||||
{% if m.startDate is not empty %}
|
||||
<li>{{ 'Since %date%'|trans({'%date%': m.startDate|format_date('long') }) }}</li>
|
||||
{% endif %}
|
||||
{% if m.endDate is not empty %}
|
||||
<li>{{ 'Until %date%'|trans({'%date%': m.endDate|format_date('long') }) }}</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="chill-no-data-statement">{{ 'household.Any persons into this position'|trans }}</p>
|
||||
{% endif %}
|
||||
|
||||
{% set members = household.nonCurrentMembersByPosition(p) %}
|
||||
{% if members|length > 0 %}
|
||||
<p><!-- force a space after table --></p>
|
||||
<button class="sc-button bt-green" type="button" data-toggle="collapse" data-target="#nonCurrent_{{ p.id }}" aria-expanded="false" aria-controls="collapse non current members">
|
||||
{{ 'household.Show future or past memberships'|trans({'length': members|length}) }}
|
||||
</button>
|
||||
|
||||
<div id="nonCurrent_{{ p.id }}" class="collapse">
|
||||
<div class="flex-table list-household-members">
|
||||
{% for m in members %}
|
||||
<div class="item-bloc">
|
||||
<div class="item-row person">
|
||||
<div class="item-col box-person">
|
||||
<div>
|
||||
{{ m.person|chill_entity_render_box({'addLink': true}) }}
|
||||
{% if m.holder %}
|
||||
<span class="badge badge-primary">{{ 'household.holder'|trans }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div>
|
||||
{{ 'Born the date'|trans({ 'gender': m.person.gender, 'birthdate': m.person.birthdate|format_date('long') }) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-col box-where">
|
||||
<ul class="list-content fa-ul">
|
||||
{% if m.startDate is not empty %}
|
||||
<li>{{ 'Since %date%'|trans({'%date%': m.startDate|format_date('long') }) }}</li>
|
||||
{% endif %}
|
||||
{% if m.endDate is not empty %}
|
||||
<li>{{ 'Until %date%'|trans({'%date%': m.endDate|format_date('long') }) }}</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a
|
||||
href="{{ chill_path_add_return_path('chill_person_household_member_edit', { 'id': m.id }) }}"
|
||||
class="sc-button bt-edit"
|
||||
/>
|
||||
{{ 'household.Update membership'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{% if m.comment is not empty %}
|
||||
<div class="item-row comment">
|
||||
<blockquote class="chill-user-quote">
|
||||
{{ m.comment|chill_markdown_to_html }}
|
||||
</blockquote>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a
|
||||
href="{{ chill_path_add_return_path('chill_person_household_members_editor', {'household': household.id }) }}"
|
||||
class="sc-button bt-create">
|
||||
{{ 'household.Add a member'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
{{ encore_entry_script_tags('household_edit_metadata') }}
|
||||
{% endblock %}
|
||||
|
||||
|
@ -36,14 +36,30 @@ class HouseholdControllerTest extends WebTestCase
|
||||
/**
|
||||
* @dataProvider generateValidHouseholdIds
|
||||
*/
|
||||
public function testMembers($householdId)
|
||||
public function testEditMetadata($householdId)
|
||||
{
|
||||
$this->client->request(
|
||||
|
||||
$crawler = $this->client->request(
|
||||
Request::METHOD_GET,
|
||||
"/fr/person/household/{$householdId}/members"
|
||||
"/fr/person/household/{$householdId}/summary",
|
||||
[
|
||||
'edit' => true
|
||||
]
|
||||
);
|
||||
|
||||
$this->assertResponseIsSuccessful();
|
||||
|
||||
$form = $crawler->selectButton('Enregistrer')
|
||||
->form();
|
||||
|
||||
$form['household[commentMembers][comment]'] = "This is a text **generated** by automatic tests";
|
||||
$form['household[waitingForBirth]']->tick();
|
||||
$form['household[waitingForBirthDate]'] = (new \DateTime('today'))
|
||||
->add(new \DateInterval('P1M'))->format('Y-m-d');
|
||||
|
||||
$this->client->submit($form);
|
||||
|
||||
$this->assertResponseRedirects("/fr/person/household/{$householdId}/summary");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,6 +73,7 @@ class HouseholdControllerTest extends WebTestCase
|
||||
);
|
||||
|
||||
$this->assertResponseIsSuccessful();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -93,5 +110,7 @@ class HouseholdControllerTest extends WebTestCase
|
||||
\shuffle($ids);
|
||||
|
||||
yield [ \array_pop($ids)['id'] ];
|
||||
yield [ \array_pop($ids)['id'] ];
|
||||
yield [ \array_pop($ids)['id'] ];
|
||||
}
|
||||
}
|
||||
|
@ -205,19 +205,18 @@ class HouseholdMemberControllerTest extends WebTestCase
|
||||
{
|
||||
self::bootKernel();
|
||||
$em = self::$container->get(EntityManagerInterface::class);
|
||||
$yesterday = new \DateTimeImmutable('yesterday');
|
||||
|
||||
$personIds = $em->createQuery("SELECT p.id FROM ".Person::class." p ".
|
||||
"JOIN p.center c ".
|
||||
"JOIN p.householdParticipations hp ".
|
||||
"WHERE ".
|
||||
"c.name = :center ".
|
||||
"AND hp.startDate < CURRENT_DATE() ".
|
||||
"AND hp.endDate IS NULL "
|
||||
"c.name = :center "
|
||||
)
|
||||
->setParameter('center', "Center A")
|
||||
->setMaxResults(100)
|
||||
->getScalarResult()
|
||||
;
|
||||
|
||||
\shuffle($personIds);
|
||||
|
||||
$household = new Household();
|
||||
@ -229,12 +228,31 @@ class HouseholdMemberControllerTest extends WebTestCase
|
||||
->getResult()
|
||||
;
|
||||
|
||||
yield [
|
||||
\array_pop($personIds)['id'],
|
||||
$household->getId(),
|
||||
$positions[\random_int(0, count($positions) - 1)]['id'],
|
||||
new \DateTimeImmutable('today')
|
||||
];
|
||||
$i = 0;
|
||||
do {
|
||||
$id = \array_pop($personIds)['id'];
|
||||
$person = self::$container->get(EntityManagerInterface::class)
|
||||
->getRepository(Person::Class)
|
||||
->find($id);
|
||||
|
||||
$participation = $person->getCurrentHouseholdParticipationShareHousehold();
|
||||
|
||||
if (NULL == $participation ||
|
||||
(
|
||||
NULL === $participation->getEndDate()
|
||||
&& $participation->getStartDate() <= $yesterday
|
||||
)) {
|
||||
|
||||
$i++;
|
||||
yield [
|
||||
$id,
|
||||
$household->getId(),
|
||||
$positions[\random_int(0, count($positions) - 1)]['id'],
|
||||
new \DateTimeImmutable('tomorrow')
|
||||
];
|
||||
}
|
||||
|
||||
} while ($i <= 1);
|
||||
}
|
||||
|
||||
public function provideValidDataEditMember(): \Iterator
|
||||
|
@ -23,6 +23,7 @@ household:
|
||||
Any persons into this position: Aucune personne n'appartient au ménage à cette position.
|
||||
Leave: Quitter le ménage
|
||||
Join: Rejoindre un ménage
|
||||
Change position: Repositionner
|
||||
Household file: Dossier ménage
|
||||
Add a member: Ajouter un membre
|
||||
Update membership: Modifier
|
||||
@ -37,6 +38,8 @@ household:
|
||||
Current household members: Membres actuels du ménage
|
||||
Household summary: Résumé
|
||||
Addresses: Adresses
|
||||
Current address: Adresse actuelle
|
||||
Household does not have any address currently: Le ménage n'a pas d'adresse renseignée actuellement
|
||||
Edit household members: Modifier l'appartenance au ménage
|
||||
and x other persons: >-
|
||||
{x, plural,
|
||||
|
Loading…
x
Reference in New Issue
Block a user