Historique ménage pour une personne

This commit is contained in:
Julien Fastré 2021-06-15 17:03:38 +02:00
parent efdfd10e49
commit e95d8fbc7a
9 changed files with 420 additions and 5 deletions

View File

@ -41,6 +41,8 @@ use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
use Chill\PersonBundle\Repository\PersonNotDuplicateRepository;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
final class PersonController extends AbstractController
{
@ -416,4 +418,29 @@ final class PersonController extends AbstractController
return $person;
}
/**
*
* @Route(
* "/{_locale}/person/household/{person_id}/history",
* name="chill_person_household_person_history",
* methods={"GET", "POST"}
* )
* @ParamConverter("person", options={"id" = "person_id"})
*/
public function householdHistoryByPerson(Request $request, Person $person): Response
{
$this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person,
"You are not allowed to see this person.");
$event = new PrivacyEvent($person);
$this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
return $this->render(
'@ChillPerson/Person/household_history.html.twig',
[
'person' => $person
]
);
}
}

View File

@ -117,6 +117,41 @@ class Household
return $this->members;
}
public function getMembersOnRange(\DateTimeImmutable $from, ?\DateTimeImmutable $to): Collection
{
$criteria = new Criteria();
$expr = Criteria::expr();
$criteria->where(
$expr->gte('startDate', $from)
);
if (NULL !== $to) {
$criteria->andWhere(
$expr->orX(
$expr->lte('endDate', $to),
$expr->eq('endDate', NULL)
),
);
}
return $this->getMembers()
->matching($criteria)
;
}
public function getMembersDuringMembership(HouseholdMember $membership)
{
return $this->getMembersOnRange(
$membership->getStartDate(),
$membership->getEndDate()
)->filter(
function(HouseholdMember $m) use ($membership) {
return $m !== $membership;
}
);
}
public function getMembersHolder(): Collection
{
$criteria = new Criteria();

View File

@ -206,4 +206,13 @@ class HouseholdMember
{
return $this->holder;
}
public function isCurrent(\DateTimeImmutable $at = null): bool
{
$at = NULL === $at ? new \DateTimeImmutable('now'): $at;
return $this->getStartDate() < $at && (
NULL === $this->getEndDate() || $at < $this->getEndDate()
);
}
}

View File

@ -1209,14 +1209,44 @@ class Person implements HasCenterInterface
return $this->householdParticipations;
}
/**
* Get participation where the person does share the household.
*
* Order by startDate, desc
*/
public function getHouseholdParticipationsShareHousehold(): Collection
{
$criteria = new Criteria();
$expr = Criteria::expr();
$criteria->where(
$expr->eq('shareHousehold', true)
);
$criteria
->where(
$expr->eq('shareHousehold', true)
)
->orderBy(['startDate' => Criteria::DESC])
;
return $this->getHouseholdParticipations()
->matching($criteria)
;
}
/**
* Get participation where the person does not share the household.
*
* Order by startDate, desc
*/
public function getHouseholdParticipationsNotShareHousehold(): Collection
{
$criteria = new Criteria();
$expr = Criteria::expr();
$criteria
->where(
$expr->eq('shareHousehold', false)
)
->orderBy(['startDate' => Criteria::DESC])
;
return $this->getHouseholdParticipations()
->matching($criteria)

View File

@ -64,6 +64,16 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface
'order' => 50
]);
$menu->addChild($this->translator->trans('household.person history'), [
'route' => 'chill_person_household_person_history',
'routeParameters' => [
'person_id' => $parameters['person']->getId()
]
])
->setExtras([
'order' => 99999
]);
$menu->addChild($this->translator->trans('Person duplicate'), [
'route' => 'chill_person_duplicate_view',
'routeParameters' => [
@ -71,7 +81,7 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface
]
])
->setExtras([
'order' => 51
'order' => 99999
]);
if ($this->showAccompanyingPeriod === 'visible') {

View File

@ -86,3 +86,83 @@ div.person-view {
}
}
/*
* HOUSEHOLD
*/
div.household__address, div.person__address {
div.row {
height: 100px;
width: 100%;
position: relative;
& > div {
position: absolute;
display: table;
height: 100%;
border: 1px dotted #c3c3c3;
}
div.household__address--date, div.person__address--date {
width: 30%;
background-color: #c3c3c3;
height: 100%;
div.cell {
box-sizing: border-box;
position: relative;
height: 100%;
width: 100%;
margin-left: 50%;
div.pill {
position: absolute;
box-sizing: border-box;
width: 120px;
height: 40px;
bottom: -20px;
background-color: white;
padding: 10px;
border-radius: 30px;
left: -60px;
text-align: center;
z-index: 10;
}
}
}
div.household__address--content, div.person__address--content {
width: 70%;
left: 30%;
text-align: left;
background-color: #ececec;
border: 1px solid #888;
div.cell {
display: table-cell;
padding: 5px 30px;
vertical-align: middle;
& > div {
display: flex;
justify-content: space-between;
}
i.dot::before, i.dot::after {
position: absolute;
width: 20px;
height: 20px;
content: '';
border: 0;
background-color: white;
border-radius: 50%;
border: 5px solid #c3c3c3;
z-index: 10;
left: -15px;
bottom: -15px;
}
}
}
}
}
div.household__address-move {
div.household__address-move__create {
display: flex;
flex-direction: column;
}
}

View File

@ -0,0 +1,213 @@
{% extends "@ChillPerson/layout.html.twig" %}
{% set activeRouteKey = 'chill_person_view' %}
{% block title 'household.Household history for %name%'|trans({'name': person|chill_entity_render_string}) %}
{% block personcontent %}
<h1>{{ block('title') }}</h1>
<h2>{{ 'household.Household shared'|trans }}</h2>
{% set memberships = person.getHouseholdParticipationsShareHousehold() %}
{% if memberships|length == 0 %}
<p class="chill-no-data-statement">{{ 'household.Never in any household'|trans }}</p>
<ul class="record_actions">
<li>
<a class="sc-button"
href="{{
chill_path_add_return_path(
'chill_person_household_members_editor',
{ 'persons': [ person.id ]}) }}"
>
<i class="fa fa-sign-out"></i>
{{ 'household.Join'|trans }}
</a>
</li>
</ul>
{% else %}
<div class="household">
<div class="household__address">
{% if not person.isSharingHousehold() %}
<div class="row">
<div class="household__address--date"></div>
<div class="household__address--content">
<div class="cell">
<a class="sc-button"
href="{{
chill_path_add_return_path(
'chill_person_household_members_editor',
{ 'persons': [ person.id ]}) }}"
>
<i class="fa fa-sign-out"></i>
{{ 'household.Join'|trans }}
</a>
</div>
</div>
</div>
{% endif %}
{% for p in memberships %}
<div class="row">
<div class="household__address--date">
<div class="cell">
<div class="pill">
{{ p.startDate|format_date('long') }}
</div>
</div>
</div>
<div class="household__address--content">
<div class="cell">
<i class="dot"></i>
<div>
<div>
<p>
<i class="fa fa-home"></i>
<a
href="{{ chill_path_add_return_path(
'chill_person_household_summary',
{ 'household_id': p.household.id }
) }}"
>
{{ 'household.Household number'|trans({'household_num': p.household.id }) }}
</a>
</p>
<p>{{ p.position.label|localize_translatable_string }} {% if p.holder %}<span class="badge badge-primary">{{ 'household.holder'|trans }}</span>{% endif %}
</div>
<div>
{% set simultaneous = p.household.getMembersDuringMembership(p) %}
{% if simultaneous|length == 0 %}
<p class="chill-no-data-statement">
{{ 'household.Any simultaneous members'|trans }}
</p>
{% else %}
{{ 'household.Members at same time'|trans }}:
{% for p in simultaneous -%}
{{- p.person|chill_entity_render_box({'addLink': true }) -}}
{%- if p.holder %} <span class="badge badge-primary">{{'household.holder'|trans }}</span> {% endif %}
{%- if not loop.last %}, {% endif -%}
{%- endfor -%}
{% endif %}
<ul class="record_actions">
<li>
<a
href="{{ chill_path_add_return_path('chill_person_household_member_edit', { id: p.id }) }}"
class="sc-button bt-edit"
></a>
</li>
{% if p.isCurrent() %}
<li>
<a class="sc-button"
href="{{ chill_path_add_return_path(
'chill_person_household_members_editor',
{ 'persons': [ person.id ], 'allow_leave_household': true }) }}"
>
<i class="fa fa-sign-out"></i>
{{ 'household.Leave'|trans }}
</a>
</li>
{% endif %}
</ul>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% endif %}
<h2>{{ 'household.Household not shared'|trans }}</h2>
{% set memberships = person.getHouseholdParticipationsNotShareHousehold() %}
{% if memberships|length == 0 %}
<p class="chill-no-data-statement">{{ 'household.Never in any household'|trans }}</p>
{% else %}
<table>
<thead>
<tr>
<th>{{ 'household.from'|trans }}</th>
<th>{{ 'household.to'|trans }}</th>
<th>{{ 'household.Household'|trans }}</th>
</tr>
</thead>
<tbody>
{% for p in memberships %}
<tr>
<td>{{ p.startDate|format_date('long') }}</td>
<td>
{% if p.endDate is not empty %}
{{ p.endDate|format_date('long') }}
{% else %}
{{ 'household.Membership currently running'|trans }}
{% endif %}
</td>
<td>
<div>
<p>
<i class="fa fa-home"></i>
<a
href="{{ chill_path_add_return_path(
'chill_person_household_summary',
{ 'household_id': p.household.id }
) }}"
>
{{ 'household.Household number'|trans({'household_num': p.household.id }) }}
</a>
</p>
<p>{{ p.position.label|localize_translatable_string }} {% if p.holder %}<span class="badge badge-primary">{{ 'household.holder'|trans }}</span>{% endif %}
</div>
<div>
{% set simultaneous = p.household.getMembersDuringMembership(p) %}
{% if simultaneous|length == 0 %}
<p class="chill-no-data-statement">
{{ 'household.Any simultaneous members'|trans }}
</p>
{% else %}
{{ 'household.Members at same time'|trans }}:
{% for p in simultaneous -%}
{{- p.person|chill_entity_render_box({'addLink': true }) -}}
{%- if p.holder %} <span class="badge badge-primary">{{'household.holder'|trans }}</span> {% endif %}
{%- if not loop.last %}, {% endif -%}
{%- endfor -%}
{% endif %}
</div>
</td>
<td>
<ul class="record_actions">
{% if p.isCurrent() %}
<li>
<a class="sc-button"
href="{{ chill_path_add_return_path(
'chill_person_household_members_editor',
{ 'persons': [ person.id ], 'allow_leave_household': true }) }}"
>
<i class="fa fa-sign-out"></i>
{{ 'household.Leave'|trans }}
</a>
</li>
{% endif %}
<li>
<a
href="{{ chill_path_add_return_path('chill_person_household_member_edit', { id: p.id }) }}"
class="sc-button bt-edit"
></a>
</li>
</ul>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% endblock %}

View File

@ -7,8 +7,11 @@ Born the date: >-
household:
Household: Ménage
Household number: Ménage {household_num}
Household members: Membres du ménage
Household editor: Modifier l'appartenance
Members at same time: Membres simultanés
Any simultaneous members: Aucun membre simultanément
Select people to move: Choisir les usagers
Show future or past memberships: >-
{length, plural,
@ -19,6 +22,7 @@ household:
Those members does not share address: Ces usagers ne partagent pas l'adresse du ménage.
Any persons into this position: Aucune personne n'appartient au ménage à cette position.
Leave: Quitter le ménage
Join: Rejoindre un ménage
Household file: Dossier ménage
Add a member: Ajouter un membre
Update membership: Modifier
@ -49,5 +53,12 @@ household:
expecting_birth: Naissance attendue ?
date_expecting_birth: Date de la naissance attendue
data_saved: Données enregistrées
Household history for %name%: Historique des ménages pour {name}
Household shared: Ménages domiciliés
Household not shared: Ménage non domiciliés
Never in any household: Membre d'aucun ménage
Membership currently running: En cours
from: Depuis
to: Jusqu'au
person history: Ménages