mirror of
				https://gitlab.com/Chill-Projet/chill-bundles.git
				synced 2025-10-31 01:08:26 +00:00 
			
		
		
		
	Historique ménage pour une personne
This commit is contained in:
		| @@ -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 | ||||
|             ] | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
| @@ -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() | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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') { | ||||
|   | ||||
| @@ -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; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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 %} | ||||
| @@ -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 | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user