mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
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:
commit
e1677cd2b6
@ -245,6 +245,16 @@ class Household
|
|||||||
$members->getIterator()
|
$members->getIterator()
|
||||||
->uasort(
|
->uasort(
|
||||||
function (HouseholdMember $a, HouseholdMember $b) {
|
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()) {
|
if ($a->getPosition()->getOrdering() < $b->getPosition()->getOrdering()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -334,6 +344,26 @@ class Household
|
|||||||
return $this->getNonCurrentMembers($now)->matching($criteria);
|
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
|
public function addMember(HouseholdMember $member): self
|
||||||
{
|
{
|
||||||
if (!$this->members->contains($member)) {
|
if (!$this->members->contains($member)) {
|
||||||
|
@ -29,7 +29,7 @@ class HouseholdMember
|
|||||||
/**
|
/**
|
||||||
* @ORM\ManyToOne(targetEntity=Position::class)
|
* @ORM\ManyToOne(targetEntity=Position::class)
|
||||||
* @Serializer\Groups({"read"})
|
* @Serializer\Groups({"read"})
|
||||||
* @Assert\NotNull(groups={"household_memberships"})
|
* @Assert\NotNull(groups={"household_memberships_created"})
|
||||||
*/
|
*/
|
||||||
private ?Position $position = null;
|
private ?Position $position = null;
|
||||||
|
|
||||||
|
@ -19,15 +19,17 @@ class MembersEditor
|
|||||||
|
|
||||||
private array $persistables = [];
|
private array $persistables = [];
|
||||||
private array $membershipsAffected = [];
|
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)
|
public function __construct(ValidatorInterface $validator, ?Household $household)
|
||||||
{
|
{
|
||||||
$this->validator = $validator;
|
$this->validator = $validator;
|
||||||
$this->household = $household;
|
$this->household = $household;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addMovement(\DateTimeImmutable $date, Person $person, Position $position, ?bool $holder = false, ?string $comment = null): self
|
public function addMovement(\DateTimeImmutable $date, Person $person, Position $position, ?bool $holder = false, ?string $comment = null): self
|
||||||
{
|
{
|
||||||
if (NULL === $this->household) {
|
if (NULL === $this->household) {
|
||||||
@ -56,6 +58,7 @@ class MembersEditor
|
|||||||
if ($participation->getEndDate() === NULL || $participation->getEndDate() > $date) {
|
if ($participation->getEndDate() === NULL || $participation->getEndDate() > $date) {
|
||||||
$participation->setEndDate($date);
|
$participation->setEndDate($date);
|
||||||
$this->membershipsAffected[] = $participation;
|
$this->membershipsAffected[] = $participation;
|
||||||
|
$this->oldMembershipsHashes[] = \spl_object_hash($participation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,13 +100,18 @@ class MembersEditor
|
|||||||
{
|
{
|
||||||
if ($this->hasHousehold()) {
|
if ($this->hasHousehold()) {
|
||||||
$list = $this->validator
|
$list = $this->validator
|
||||||
->validate($this->getHousehold(), null, [ self::VALIDATION_GROUP ]);
|
->validate($this->getHousehold(), null, [ self::VALIDATION_GROUP_AFFECTED ]);
|
||||||
} else {
|
} else {
|
||||||
$list = new ConstraintViolationList();
|
$list = new ConstraintViolationList();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->membershipsAffected as $m) {
|
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;
|
return $list;
|
||||||
|
@ -22,8 +22,11 @@
|
|||||||
|
|
||||||
{%- for m in members -%}
|
{%- for m in members -%}
|
||||||
<span
|
<span
|
||||||
class="badge-member{%- if m.holder %} holder{% endif -%}{%- if m.position.ordering >= 2 %} child{% endif -%}"
|
class="badge-member{%- if m.holder %} holder{% endif -%}"
|
||||||
title="{{ m.position.label.fr }}">
|
{% if m.position is not null %}
|
||||||
|
title="{{ m.position.label.fr }}"
|
||||||
|
{% endif %}
|
||||||
|
>
|
||||||
<a href="{{ path('chill_person_view', { person_id: m.person.id}) }}">
|
<a href="{{ path('chill_person_view', { person_id: m.person.id}) }}">
|
||||||
{%- if m.holder %}
|
{%- if m.holder %}
|
||||||
<span class="fa-stack fa-holder" title="{{ 'household.holder'|trans }}">
|
<span class="fa-stack fa-holder" title="{{ 'household.holder'|trans }}">
|
||||||
|
@ -106,81 +106,95 @@
|
|||||||
|
|
||||||
<h2 class="my-5">{{ 'household.Household members'|trans }}</h2>
|
<h2 class="my-5">{{ 'household.Household members'|trans }}</h2>
|
||||||
|
|
||||||
{% for p in positions %}
|
{% for p in positions|merge([ '_none' ]) %}
|
||||||
<div class="mb-5">
|
|
||||||
<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>
|
|
||||||
|
|
||||||
{%- set members = household.currentMembersByPosition(p) %}
|
{% 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 %}
|
||||||
|
|
||||||
{% macro customButtons(member, household) %}
|
{% if not (p == '_none' and members|length == 0 and old_members|length == 0) %}
|
||||||
<li>
|
<div class="mb-5">
|
||||||
<a href="{{ chill_path_add_return_path('chill_person_household_members_editor', {'persons': [ member.person.id ], 'allow_leave_without_household': true } ) }}"
|
{% if p != '_none' %}
|
||||||
class="btn btn-sm btn-unlink" title="{{ 'household.person.leave'|trans }}"></a>
|
<h3>{{ p.label|localize_translatable_string }}
|
||||||
</li>
|
{% if false == p.shareHousehold %}
|
||||||
<li>
|
<i class="chill-help-tooltip" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-html="true"
|
||||||
<a href="{{ chill_path_add_return_path('chill_person_household_members_editor', {'persons': [ member.person.id ], 'household': household.id} ) }}"
|
title="{{ 'household.Those members does not share address'|trans }}"></i>
|
||||||
class="btn btn-sm btn-misc" title="{{ 'household.Change position'|trans }}"><i class="fa fa-arrows-h"></i></a>
|
{% endif %}
|
||||||
</li>
|
</h3>
|
||||||
{% endmacro %}
|
{% else %}
|
||||||
|
<h3 class="chill-entity">{{ 'household.Members without position'|trans }}</h3>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if members|length > 0 %}
|
|
||||||
<div class="flex-table list-household-members">
|
|
||||||
{% for m in members %}
|
|
||||||
{% include '@ChillPerson/Household/_render_member.html.twig' with {
|
|
||||||
'member': m,
|
|
||||||
'customButtons': { 'after': _self.customButtons(m, household) }
|
|
||||||
} %}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<p class="chill-no-data-statement">{{ 'household.Any persons into this position'|trans }}</p>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% set members = household.nonCurrentMembersByPosition(p) %}
|
{% macro customButtons(member, household) %}
|
||||||
{% if members|length > 0 %}
|
<li>
|
||||||
|
<a href="{{ chill_path_add_return_path('chill_person_household_members_editor', {'persons': [ member.person.id ], 'allow_leave_without_household': true } ) }}"
|
||||||
|
class="btn btn-sm btn-unlink" title="{{ 'household.person.leave'|trans }}"></a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="{{ chill_path_add_return_path('chill_person_household_members_editor', {'persons': [ member.person.id ], 'household': household.id} ) }}"
|
||||||
|
class="btn btn-sm btn-misc" title="{{ 'household.Change position'|trans }}"><i class="fa fa-arrows-h"></i></a>
|
||||||
|
</li>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
<style>
|
{% if members|length > 0 %}
|
||||||
button[aria-expanded="true"] > span.folded,
|
<div class="flex-table list-household-members">
|
||||||
button[aria-expanded="false"] > span.unfolded { display: none; }
|
{% for m in members %}
|
||||||
button[aria-expanded="false"] > span.folded,
|
{% include '@ChillPerson/Household/_render_member.html.twig' with {
|
||||||
button[aria-expanded="true"] > span.unfolded { display: inline; }
|
'member': m,
|
||||||
</style>
|
'customButtons': { 'after': _self.customButtons(m, household) }
|
||||||
<div class="accordion" id="nonCurrent">
|
} %}
|
||||||
<div class="accordion-item">
|
{% endfor %}
|
||||||
<h2 class="accordion-header" id="heading_{{ p.id }}">
|
</div>
|
||||||
<button
|
{% else %}
|
||||||
class="accordion-button collapsed"
|
<p class="chill-no-data-statement">{{ 'household.Any persons into this position'|trans }}</p>
|
||||||
type="button"
|
{% endif %}
|
||||||
data-bs-toggle="collapse"
|
|
||||||
data-bs-target="#collapse_{{ p.id }}"
|
{% if old_members|length > 0 %}
|
||||||
aria-expanded="false"
|
<style>
|
||||||
aria-controls="collapse_{{ p.id }}">
|
button[aria-expanded="true"] > span.folded,
|
||||||
<span class="folded">{{ 'household.Show future or past memberships'|trans({'length': members|length}) }}</span>
|
button[aria-expanded="false"] > span.unfolded { display: none; }
|
||||||
<span class="unfolded text-secondary">{{ 'household.Hide memberships'|trans }}</span>
|
button[aria-expanded="false"] > span.folded,
|
||||||
</button>
|
button[aria-expanded="true"] > span.unfolded { display: inline; }
|
||||||
</h2>
|
</style>
|
||||||
<div id="collapse_{{ p.id }}"
|
<div class="accordion" id="nonCurrent">
|
||||||
class="accordion-collapse collapse"
|
<div class="accordion-item">
|
||||||
aria-labelledby="heading_{{ p.id }}"
|
<h2 class="accordion-header" id="heading_{{ p == '_none' ? '_none' : p.id }}">
|
||||||
data-bs-parent="#nonCurrent">
|
<button
|
||||||
<div class="flex-table my-0 list-household-members">
|
class="accordion-button collapsed"
|
||||||
{% for m in members %}
|
type="button"
|
||||||
{% include '@ChillPerson/Household/_render_member.html.twig' with { 'member': m } %}
|
data-bs-toggle="collapse"
|
||||||
{% endfor %}
|
data-bs-target="#collapse_{{ p == '_none' ? '_none' : p.id }}"
|
||||||
|
aria-expanded="false"
|
||||||
|
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 == '_none' ? '_none' : p.id }}"
|
||||||
|
class="accordion-collapse collapse"
|
||||||
|
aria-labelledby="heading_{{ p == '_none' ? '_none' : p.id }}"
|
||||||
|
data-bs-parent="#nonCurrent">
|
||||||
|
<div class="flex-table my-0 list-household-members">
|
||||||
|
{% for m in old_members %}
|
||||||
|
{% include '@ChillPerson/Household/_render_member.html.twig' with { 'member': m } %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{% endif %}
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<ul class="record_actions">
|
<ul class="record_actions">
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ chill_path_add_return_path('chill_person_household_members_editor', {'household': household.id }) }}"
|
<a href="{{ chill_path_add_return_path('chill_person_household_members_editor', {'household': household.id }) }}"
|
||||||
|
@ -77,6 +77,7 @@ household:
|
|||||||
Household history for %name%: Historique des ménages pour {name}
|
Household history for %name%: Historique des ménages pour {name}
|
||||||
Household shared: Ménages domiciliés
|
Household shared: Ménages domiciliés
|
||||||
Household not shared: Ménage non 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
|
Never in any household: Membre d'aucun ménage
|
||||||
Membership currently running: En cours
|
Membership currently running: En cours
|
||||||
from: Depuis
|
from: Depuis
|
||||||
|
Loading…
x
Reference in New Issue
Block a user