Merge branch 'feature/household-accept-members-without-position' into 'master'

An household can have members without position

See merge request Chill-Projet/chill-bundles!189
This commit is contained in:
Julien Fastré 2021-11-05 09:26:16 +00:00
commit e1677cd2b6
6 changed files with 128 additions and 72 deletions

View File

@ -245,6 +245,16 @@ class Household
$members->getIterator()
->uasort(
function (HouseholdMember $a, HouseholdMember $b) {
if ($a->getPosition() === NULL) {
if ($b->getPosition() === NULL) {
return 0;
} else {
return -1;
}
} elseif ($b->getPosition() === NULL) {
return 1;
}
if ($a->getPosition()->getOrdering() < $b->getPosition()->getOrdering()) {
return -1;
}
@ -334,6 +344,26 @@ class Household
return $this->getNonCurrentMembers($now)->matching($criteria);
}
public function getCurrentMembersWithoutPosition(\DateTimeInterface $now = null)
{
$criteria = new Criteria();
$expr = Criteria::expr();
$criteria->where($expr->isNull('position'));
return $this->getCurrentMembers($now)->matching($criteria);
}
public function getNonCurrentMembersWithoutPosition(\DateTimeInterface $now = null)
{
$criteria = new Criteria();
$expr = Criteria::expr();
$criteria->where($expr->isNull('position'));
return $this->getNonCurrentMembers($now)->matching($criteria);
}
public function addMember(HouseholdMember $member): self
{
if (!$this->members->contains($member)) {

View File

@ -29,7 +29,7 @@ class HouseholdMember
/**
* @ORM\ManyToOne(targetEntity=Position::class)
* @Serializer\Groups({"read"})
* @Assert\NotNull(groups={"household_memberships"})
* @Assert\NotNull(groups={"household_memberships_created"})
*/
private ?Position $position = null;

View File

@ -19,8 +19,10 @@ class MembersEditor
private array $persistables = [];
private array $membershipsAffected = [];
private array $oldMembershipsHashes = [];
public const VALIDATION_GROUP = 'household_memberships';
public const VALIDATION_GROUP_CREATED = 'household_memberships_created';
public const VALIDATION_GROUP_AFFECTED = 'household_memberships';
public function __construct(ValidatorInterface $validator, ?Household $household)
{
@ -56,6 +58,7 @@ class MembersEditor
if ($participation->getEndDate() === NULL || $participation->getEndDate() > $date) {
$participation->setEndDate($date);
$this->membershipsAffected[] = $participation;
$this->oldMembershipsHashes[] = \spl_object_hash($participation);
}
}
}
@ -97,13 +100,18 @@ class MembersEditor
{
if ($this->hasHousehold()) {
$list = $this->validator
->validate($this->getHousehold(), null, [ self::VALIDATION_GROUP ]);
->validate($this->getHousehold(), null, [ self::VALIDATION_GROUP_AFFECTED ]);
} else {
$list = new ConstraintViolationList();
}
foreach ($this->membershipsAffected as $m) {
$list->addAll($this->validator->validate($m, null, [ self::VALIDATION_GROUP ]));
if (\in_array(\spl_object_hash($m), $this->oldMembershipsHashes)) {
$list->addAll($this->validator->validate($m, null, [ self::VALIDATION_GROUP_AFFECTED ]));
} else {
$list->addAll($this->validator->validate($m, null, [ self::VALIDATION_GROUP_CREATED,
self::VALIDATION_GROUP_AFFECTED ]));
}
}
return $list;

View File

@ -22,8 +22,11 @@
{%- for m in members -%}
<span
class="badge-member{%- if m.holder %} holder{% endif -%}{%- if m.position.ordering >= 2 %} child{% endif -%}"
title="{{ m.position.label.fr }}">
class="badge-member{%- if m.holder %} holder{% endif -%}"
{% if m.position is not null %}
title="{{ m.position.label.fr }}"
{% endif %}
>
<a href="{{ path('chill_person_view', { person_id: m.person.id}) }}">
{%- if m.holder %}
<span class="fa-stack fa-holder" title="{{ 'household.holder'|trans }}">

View File

@ -106,16 +106,29 @@
<h2 class="my-5">{{ 'household.Household members'|trans }}</h2>
{% for p in positions %}
{% for p in positions|merge([ '_none' ]) %}
{% if p == '_none' %}
{% set members = household.currentMembersWithoutPosition %}
{% set old_members = household.nonCurrentMembersWithoutPosition %}
{% else %}
{%- set members = household.currentMembersByPosition(p) %}
{% set old_members = household.nonCurrentMembersByPosition(p) %}
{% endif %}
{% if not (p == '_none' and members|length == 0 and old_members|length == 0) %}
<div class="mb-5">
{% if p != '_none' %}
<h3>{{ p.label|localize_translatable_string }}
{% if false == p.shareHousehold %}
<i class="chill-help-tooltip" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-html="true"
title="{{ 'household.Those members does not share address'|trans }}"></i>
{% endif %}
</h3>
{% else %}
<h3 class="chill-entity">{{ 'household.Members without position'|trans }}</h3>
{% endif %}
{%- set members = household.currentMembersByPosition(p) %}
{% macro customButtons(member, household) %}
<li>
@ -141,9 +154,7 @@
<p class="chill-no-data-statement">{{ 'household.Any persons into this position'|trans }}</p>
{% endif %}
{% set members = household.nonCurrentMembersByPosition(p) %}
{% if members|length > 0 %}
{% if old_members|length > 0 %}
<style>
button[aria-expanded="true"] > span.folded,
button[aria-expanded="false"] > span.unfolded { display: none; }
@ -152,24 +163,24 @@
</style>
<div class="accordion" id="nonCurrent">
<div class="accordion-item">
<h2 class="accordion-header" id="heading_{{ p.id }}">
<h2 class="accordion-header" id="heading_{{ p == '_none' ? '_none' : p.id }}">
<button
class="accordion-button collapsed"
type="button"
data-bs-toggle="collapse"
data-bs-target="#collapse_{{ p.id }}"
data-bs-target="#collapse_{{ p == '_none' ? '_none' : p.id }}"
aria-expanded="false"
aria-controls="collapse_{{ p.id }}">
<span class="folded">{{ 'household.Show future or past memberships'|trans({'length': members|length}) }}</span>
aria-controls="collapse_{{ p == '_none' ? '_none' : p.id }}">
<span class="folded">{{ 'household.Show future or past memberships'|trans({'length': old_members|length}) }}</span>
<span class="unfolded text-secondary">{{ 'household.Hide memberships'|trans }}</span>
</button>
</h2>
<div id="collapse_{{ p.id }}"
<div id="collapse_{{ p == '_none' ? '_none' : p.id }}"
class="accordion-collapse collapse"
aria-labelledby="heading_{{ p.id }}"
aria-labelledby="heading_{{ p == '_none' ? '_none' : p.id }}"
data-bs-parent="#nonCurrent">
<div class="flex-table my-0 list-household-members">
{% for m in members %}
{% for m in old_members %}
{% include '@ChillPerson/Household/_render_member.html.twig' with { 'member': m } %}
{% endfor %}
</div>
@ -179,8 +190,11 @@
{% endif %}
</div>
{% endif %}
{% endfor %}
<ul class="record_actions">
<li>
<a href="{{ chill_path_add_return_path('chill_person_household_members_editor', {'household': household.id }) }}"

View File

@ -77,6 +77,7 @@ household:
Household history for %name%: Historique des ménages pour {name}
Household shared: Ménages domiciliés
Household not shared: Ménage non domiciliés
Members without position: Membres non positionnés
Never in any household: Membre d'aucun ménage
Membership currently running: En cours
from: Depuis