mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-12 13:24:25 +00:00
Merge branch 'feature/form-move-household-with-checkboxes' into 'master'
rewrite form move household See merge request Chill-Projet/chill-bundles!159
This commit is contained in:
commit
89b0b94d22
33
CHANGELOG.md
33
CHANGELOG.md
@ -14,6 +14,7 @@ and this project adheres to
|
|||||||
* [3party]: show parent in list
|
* [3party]: show parent in list
|
||||||
* [3party]: change color for badge "child"
|
* [3party]: change color for badge "child"
|
||||||
* [3party]: fix address creation
|
* [3party]: fix address creation
|
||||||
|
* [household members editor] finalisation of editor
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -40,10 +41,14 @@ and this project adheres to
|
|||||||
|
|
||||||
* [FilterOrder]: add development kit for generating filter and ordering in list
|
* [FilterOrder]: add development kit for generating filter and ordering in list
|
||||||
* [Capitalization of names] person names are capitalized on creation, on prePersist event
|
* [Capitalization of names] person names are capitalized on creation, on prePersist event
|
||||||
|
* [On-The-Fly] modale works for showing, editing and creating person or thirdparty ;
|
||||||
|
* [AccompanyingCourse Resume page] associated persons list, can see household when hover, and with show on-the-fly modale when clicking person ;
|
||||||
|
|
||||||
### test release 2021-10-04
|
### test release 2021-10-04
|
||||||
|
|
||||||
* [Household editor][UI] Update how household suggestion and addresses are picked;
|
* [Household editor][UI] Update how household suggestion and addresses are picked;
|
||||||
|
|
||||||
|
See https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/80
|
||||||
* [AddAddress] Handle address suggestion;
|
* [AddAddress] Handle address suggestion;
|
||||||
* [CenterType][Create a person] when overriding the ACL rules, allow to show a PickCenterType
|
* [CenterType][Create a person] when overriding the ACL rules, allow to show a PickCenterType
|
||||||
when no centers are reachable by the default ACL.
|
when no centers are reachable by the default ACL.
|
||||||
@ -62,8 +67,30 @@ and this project adheres to
|
|||||||
https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/37
|
https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/37
|
||||||
https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/221
|
https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/221
|
||||||
|
|
||||||
* [On-The-Fly] modale works for showing, editing and creating person or thirdparty ;
|
* [Household editor] suggest only temporarily addresses;
|
||||||
* [AccompanyingCourse Resume page] associated persons list, can see household when hover, and with show on-the-fly modale when clicking person ;
|
See https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/82
|
||||||
|
* On-The-Fly modale works for showing, editing and creating person and thirdparty ;
|
||||||
|
* AccompanyingCourse Resume page: list associated persons by household, see household when hover, and show on-the-fly modale when clicking on person ;
|
||||||
|
* [AddAddress] Handle address suggestion;
|
||||||
|
* [AddAddress][Entity address]: add a link between address and address reference;
|
||||||
|
* [Household editor] suggest household by comparing the temporary addresses from courses;
|
||||||
|
|
||||||
## Test release yyyy-mm-dd
|
See https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/81
|
||||||
|
* On-The-Fly modale works for showing, editing and creating person and thirdparty
|
||||||
|
|
||||||
|
|
||||||
|
## Test released
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Coming soon...
|
||||||
|
|
||||||
|
### Test release yyyy-mm-dd
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Stable releases
|
||||||
|
|
||||||
|
No stable releases for v2+
|
||||||
|
|
||||||
|
>>>>>>> 107b8131 (update changelog)
|
||||||
|
@ -23,7 +23,7 @@ class Address
|
|||||||
* @ORM\Id
|
* @ORM\Id
|
||||||
* @ORM\Column(name="id", type="integer")
|
* @ORM\Column(name="id", type="integer")
|
||||||
* @ORM\GeneratedValue(strategy="AUTO")
|
* @ORM\GeneratedValue(strategy="AUTO")
|
||||||
* @groups({"write"})
|
* @Groups({"write"})
|
||||||
*/
|
*/
|
||||||
private $id;
|
private $id;
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ class Address
|
|||||||
* @var string
|
* @var string
|
||||||
*
|
*
|
||||||
* @ORM\Column(type="string", length=255)
|
* @ORM\Column(type="string", length=255)
|
||||||
* @groups({"write"})
|
* @Groups({"write"})
|
||||||
*/
|
*/
|
||||||
private $street = '';
|
private $street = '';
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ class Address
|
|||||||
* @var string
|
* @var string
|
||||||
*
|
*
|
||||||
* @ORM\Column(type="string", length=255)
|
* @ORM\Column(type="string", length=255)
|
||||||
* @groups({"write"})
|
* @Groups({"write"})
|
||||||
*/
|
*/
|
||||||
private $streetNumber = '';
|
private $streetNumber = '';
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ class Address
|
|||||||
* @var PostalCode
|
* @var PostalCode
|
||||||
*
|
*
|
||||||
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\PostalCode")
|
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\PostalCode")
|
||||||
* @groups({"write"})
|
* @Groups({"write"})
|
||||||
*/
|
*/
|
||||||
private $postcode;
|
private $postcode;
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ class Address
|
|||||||
* @var string|null
|
* @var string|null
|
||||||
*
|
*
|
||||||
* @ORM\Column(type="string", length=16, nullable=true)
|
* @ORM\Column(type="string", length=16, nullable=true)
|
||||||
* @groups({"write"})
|
* @Groups({"write"})
|
||||||
*/
|
*/
|
||||||
private $floor;
|
private $floor;
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ class Address
|
|||||||
* @var string|null
|
* @var string|null
|
||||||
*
|
*
|
||||||
* @ORM\Column(type="string", length=16, nullable=true)
|
* @ORM\Column(type="string", length=16, nullable=true)
|
||||||
* @groups({"write"})
|
* @Groups({"write"})
|
||||||
*/
|
*/
|
||||||
private $corridor;
|
private $corridor;
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ class Address
|
|||||||
* @var string|null
|
* @var string|null
|
||||||
*
|
*
|
||||||
* @ORM\Column(type="string", length=16, nullable=true)
|
* @ORM\Column(type="string", length=16, nullable=true)
|
||||||
* @groups({"write"})
|
* @Groups({"write"})
|
||||||
*/
|
*/
|
||||||
private $steps;
|
private $steps;
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ class Address
|
|||||||
* @var string|null
|
* @var string|null
|
||||||
*
|
*
|
||||||
* @ORM\Column(type="string", length=255, nullable=true)
|
* @ORM\Column(type="string", length=255, nullable=true)
|
||||||
* @groups({"write"})
|
* @Groups({"write"})
|
||||||
*/
|
*/
|
||||||
private $buildingName;
|
private $buildingName;
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ class Address
|
|||||||
* @var string|null
|
* @var string|null
|
||||||
*
|
*
|
||||||
* @ORM\Column(type="string", length=16, nullable=true)
|
* @ORM\Column(type="string", length=16, nullable=true)
|
||||||
* @groups({"write"})
|
* @Groups({"write"})
|
||||||
*/
|
*/
|
||||||
private $flat;
|
private $flat;
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ class Address
|
|||||||
* @var string|null
|
* @var string|null
|
||||||
*
|
*
|
||||||
* @ORM\Column(type="string", length=255, nullable=true)
|
* @ORM\Column(type="string", length=255, nullable=true)
|
||||||
* @groups({"write"})
|
* @Groups({"write"})
|
||||||
*/
|
*/
|
||||||
private $distribution;
|
private $distribution;
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ class Address
|
|||||||
* @var string|null
|
* @var string|null
|
||||||
*
|
*
|
||||||
* @ORM\Column(type="string", length=255, nullable=true)
|
* @ORM\Column(type="string", length=255, nullable=true)
|
||||||
* @groups({"write"})
|
* @Groups({"write"})
|
||||||
*/
|
*/
|
||||||
private $extra;
|
private $extra;
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ class Address
|
|||||||
* @var \DateTime
|
* @var \DateTime
|
||||||
*
|
*
|
||||||
* @ORM\Column(type="date")
|
* @ORM\Column(type="date")
|
||||||
* @groups({"write"})
|
* @Groups({"write"})
|
||||||
*/
|
*/
|
||||||
private \DateTime $validFrom;
|
private \DateTime $validFrom;
|
||||||
|
|
||||||
@ -125,13 +125,13 @@ class Address
|
|||||||
* @var \DateTime|null
|
* @var \DateTime|null
|
||||||
*
|
*
|
||||||
* @ORM\Column(type="date", nullable=true)
|
* @ORM\Column(type="date", nullable=true)
|
||||||
* @groups({"write"})
|
* @Groups({"write"})
|
||||||
*/
|
*/
|
||||||
private ?\DateTime $validTo = null;
|
private ?\DateTime $validTo = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if the address is a "no address", aka homeless person, ...
|
* True if the address is a "no address", aka homeless person, ...
|
||||||
* @groups({"write"})
|
* @Groups({"write"})
|
||||||
* @ORM\Column(type="boolean")
|
* @ORM\Column(type="boolean")
|
||||||
*
|
*
|
||||||
* @var bool
|
* @var bool
|
||||||
@ -144,7 +144,7 @@ class Address
|
|||||||
* @var Point|null
|
* @var Point|null
|
||||||
*
|
*
|
||||||
* @ORM\Column(type="point", nullable=true)
|
* @ORM\Column(type="point", nullable=true)
|
||||||
* @groups({"write"})
|
* @Groups({"write"})
|
||||||
*/
|
*/
|
||||||
private $point;
|
private $point;
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ class Address
|
|||||||
* @var ThirdParty|null
|
* @var ThirdParty|null
|
||||||
*
|
*
|
||||||
* @ORM\ManyToOne(targetEntity="Chill\ThirdPartyBundle\Entity\ThirdParty")
|
* @ORM\ManyToOne(targetEntity="Chill\ThirdPartyBundle\Entity\ThirdParty")
|
||||||
* @groups({"write"})
|
* @Groups({"write"})
|
||||||
* @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
|
* @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
|
||||||
*/
|
*/
|
||||||
private $linkedToThirdParty;
|
private $linkedToThirdParty;
|
||||||
@ -166,6 +166,12 @@ class Address
|
|||||||
*/
|
*/
|
||||||
private $customs = [];
|
private $customs = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\ManyToOne(targetEntity=AddressReference::class)
|
||||||
|
* @Groups({"write"})
|
||||||
|
*/
|
||||||
|
private ?AddressReference $addressReference = null;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->validFrom = new \DateTime();
|
$this->validFrom = new \DateTime();
|
||||||
@ -376,6 +382,7 @@ class Address
|
|||||||
public static function createFromAddress(Address $original) : Address
|
public static function createFromAddress(Address $original) : Address
|
||||||
{
|
{
|
||||||
return (new Address())
|
return (new Address())
|
||||||
|
->setAddressReference($original->getAddressReference())
|
||||||
->setBuildingName($original->getBuildingName())
|
->setBuildingName($original->getBuildingName())
|
||||||
->setCorridor($original->getCorridor())
|
->setCorridor($original->getCorridor())
|
||||||
->setCustoms($original->getCustoms())
|
->setCustoms($original->getCustoms())
|
||||||
@ -402,6 +409,7 @@ class Address
|
|||||||
->setPostcode($original->getPostcode())
|
->setPostcode($original->getPostcode())
|
||||||
->setStreet($original->getStreet())
|
->setStreet($original->getStreet())
|
||||||
->setStreetNumber($original->getStreetNumber())
|
->setStreetNumber($original->getStreetNumber())
|
||||||
|
->setAddressReference($original)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -549,5 +557,22 @@ class Address
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return AddressReference|null
|
||||||
|
*/
|
||||||
|
public function getAddressReference(): ?AddressReference
|
||||||
|
{
|
||||||
|
return $this->addressReference;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param AddressReference|null $addressReference
|
||||||
|
* @return Address
|
||||||
|
*/
|
||||||
|
public function setAddressReference(?AddressReference $addressReference = null): Address
|
||||||
|
{
|
||||||
|
$this->addressReference = $addressReference;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
const _fetchAction = (page, uri, params) => {
|
||||||
|
const item_per_page = 50;
|
||||||
|
if (params === undefined) {
|
||||||
|
params = {};
|
||||||
|
}
|
||||||
|
let url = uri + '?' + new URLSearchParams({ item_per_page, page, ...params });
|
||||||
|
|
||||||
|
return fetch(url, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json;charset=utf-8'
|
||||||
|
},
|
||||||
|
}).then(response => {
|
||||||
|
if (response.ok) { return response.json(); }
|
||||||
|
throw Error({ m: response.statusText });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchResults = async (uri, params) => {
|
||||||
|
let promises = [],
|
||||||
|
page = 1;
|
||||||
|
let firstData = await _fetchAction(page, uri, params);
|
||||||
|
|
||||||
|
promises.push(Promise.resolve(firstData.results));
|
||||||
|
|
||||||
|
if (firstData.pagination.more) {
|
||||||
|
do {
|
||||||
|
page = ++page;
|
||||||
|
promises.push(_fetchAction(page, uri, params).then(r => Promise.resolve(r.results)));
|
||||||
|
} while (page * firstData.pagination.items_per_page < firstData.count)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.all(promises).then(values => values.flat());
|
||||||
|
};
|
||||||
|
|
||||||
|
export {
|
||||||
|
fetchResults
|
||||||
|
};
|
@ -1,15 +1,7 @@
|
|||||||
|
import { fetchResults } from 'ChillMainAssets/lib/api/download.js';
|
||||||
|
|
||||||
const fetchScopes = () => {
|
const fetchScopes = () => {
|
||||||
return window.fetch('/api/1.0/main/scope.json').then(response => {
|
return fetchResults('/api/1.0/main/scope.json');
|
||||||
if (response.ok) {
|
|
||||||
return response.json();
|
|
||||||
}
|
|
||||||
}).then(data => {
|
|
||||||
//console.log(data);
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
//console.log(data);
|
|
||||||
resolve(data.results);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
@ -589,6 +589,14 @@ export default {
|
|||||||
'point': this.entity.selected.address.point.coordinates
|
'point': this.entity.selected.address.point.coordinates
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add the address reference, if any
|
||||||
|
if (this.entity.selected.address.addressReference !== undefined) {
|
||||||
|
newAddress = Object.assign(newAddress, {
|
||||||
|
'addressReference': this.entity.selected.address.addressReference
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (this.validFrom) {
|
if (this.validFrom) {
|
||||||
console.log('add validFrom in fetch body', this.entity.selected.valid.from);
|
console.log('add validFrom in fetch body', this.entity.selected.valid.from);
|
||||||
newAddress = Object.assign(newAddress, {
|
newAddress = Object.assign(newAddress, {
|
||||||
@ -733,6 +741,9 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
*
|
||||||
|
* Called when the event pick-address is emitted, which is, by the way,
|
||||||
|
* called when an address suggestion is picked.
|
||||||
*
|
*
|
||||||
* @param address the address selected
|
* @param address the address selected
|
||||||
*/
|
*/
|
||||||
|
@ -95,6 +95,9 @@ export default {
|
|||||||
},
|
},
|
||||||
selectAddress(value) {
|
selectAddress(value) {
|
||||||
this.entity.selected.address = value;
|
this.entity.selected.address = value;
|
||||||
|
this.entity.selected.address.addressReference = {
|
||||||
|
id: value.id
|
||||||
|
};
|
||||||
this.entity.selected.address.street = value.street;
|
this.entity.selected.address.street = value.street;
|
||||||
this.entity.selected.address.streetNumber = value.streetNumber;
|
this.entity.selected.address.streetNumber = value.streetNumber;
|
||||||
this.entity.selected.writeNew.address = false;
|
this.entity.selected.writeNew.address = false;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace Chill\MainBundle\Serializer\Normalizer;
|
namespace Chill\MainBundle\Serializer\Normalizer;
|
||||||
|
|
||||||
use Chill\MainBundle\Entity\Address;
|
use Chill\MainBundle\Entity\Address;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||||
@ -33,6 +34,9 @@ class AddressNormalizer implements NormalizerAwareInterface, NormalizerInterface
|
|||||||
$data['extra'] = $address->getExtra();
|
$data['extra'] = $address->getExtra();
|
||||||
$data['validFrom'] = $address->getValidFrom();
|
$data['validFrom'] = $address->getValidFrom();
|
||||||
$data['validTo'] = $address->getValidTo();
|
$data['validTo'] = $address->getValidTo();
|
||||||
|
$data['addressReference'] = $this->normalizer->normalize($address->getAddressReference(), $format, [
|
||||||
|
AbstractNormalizer::GROUPS => ['read']
|
||||||
|
]);
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\Migrations\Main;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a link between address and address reference
|
||||||
|
*/
|
||||||
|
final class Version20210929192242 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return 'Add a link between address and address reference';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('ALTER TABLE chill_main_address ADD addressReference_id INT DEFAULT NULL');
|
||||||
|
$this->addSql('ALTER TABLE chill_main_address ADD CONSTRAINT FK_165051F647069464 FOREIGN KEY (addressReference_id) REFERENCES chill_main_address_reference (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||||
|
$this->addSql('CREATE INDEX IDX_165051F647069464 ON chill_main_address (addressReference_id)');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('ALTER TABLE chill_main_address DROP addressReference_id');
|
||||||
|
}
|
||||||
|
}
|
@ -4,24 +4,31 @@ namespace Chill\PersonBundle\Controller;
|
|||||||
|
|
||||||
use Chill\MainBundle\CRUD\Controller\ApiController;
|
use Chill\MainBundle\CRUD\Controller\ApiController;
|
||||||
use Chill\MainBundle\Entity\Address;
|
use Chill\MainBundle\Entity\Address;
|
||||||
|
use Chill\MainBundle\Entity\AddressReference;
|
||||||
use Chill\MainBundle\Serializer\Model\Collection;
|
use Chill\MainBundle\Serializer\Model\Collection;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Chill\PersonBundle\Entity\Household\Household;
|
use Chill\PersonBundle\Entity\Household\Household;
|
||||||
|
use Chill\PersonBundle\Repository\Household\HouseholdACLAwareRepositoryInterface;
|
||||||
use Chill\PersonBundle\Repository\Household\HouseholdRepository;
|
use Chill\PersonBundle\Repository\Household\HouseholdRepository;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||||
|
|
||||||
class HouseholdApiController extends ApiController
|
class HouseholdApiController extends ApiController
|
||||||
{
|
{
|
||||||
private HouseholdRepository $householdRepository;
|
private HouseholdRepository $householdRepository;
|
||||||
|
|
||||||
public function __construct(HouseholdRepository $householdRepository)
|
private HouseholdACLAwareRepositoryInterface $householdACLAwareRepository;
|
||||||
{
|
|
||||||
$this->householdRepository = $householdRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
HouseholdRepository $householdRepository,
|
||||||
|
HouseholdACLAwareRepositoryInterface $householdACLAwareRepository
|
||||||
|
) {
|
||||||
|
$this->householdRepository = $householdRepository;
|
||||||
|
$this->householdACLAwareRepository = $householdACLAwareRepository;
|
||||||
|
}
|
||||||
|
|
||||||
public function householdAddressApi($id, Request $request, string $_format): Response
|
public function householdAddressApi($id, Request $request, string $_format): Response
|
||||||
{
|
{
|
||||||
@ -93,4 +100,27 @@ class HouseholdApiController extends ApiController
|
|||||||
return $this->json(\array_values($addresses), Response::HTTP_OK, [],
|
return $this->json(\array_values($addresses), Response::HTTP_OK, [],
|
||||||
[ 'groups' => [ 'read' ] ]);
|
[ 'groups' => [ 'read' ] ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @Route("/api/1.0/person/household/by-address-reference/{id}.json",
|
||||||
|
* name="chill_api_person_household_by_address_reference")
|
||||||
|
* @param AddressReference $addressReference
|
||||||
|
* @return \Symfony\Component\HttpFoundation\JsonResponse
|
||||||
|
*/
|
||||||
|
public function getHouseholdByAddressReference(AddressReference $addressReference): Response
|
||||||
|
{
|
||||||
|
// TODO ACL
|
||||||
|
$this->denyAccessUnlessGranted('ROLE_USER');
|
||||||
|
|
||||||
|
$total = $this->householdACLAwareRepository->countByAddressReference($addressReference);
|
||||||
|
$paginator = $this->getPaginatorFactory()->create($total);
|
||||||
|
$households = $this->householdACLAwareRepository->findByAddressReference($addressReference,
|
||||||
|
$paginator->getCurrentPageFirstItemNumber(), $paginator->getItemsPerPage());
|
||||||
|
$collection = new Collection($households, $paginator);
|
||||||
|
|
||||||
|
return $this->json($collection, Response::HTTP_OK, [], [
|
||||||
|
AbstractNormalizer::GROUPS => ['read']
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,13 +77,6 @@ class PersonApiController extends ApiController
|
|||||||
$a = $participation->getAccompanyingPeriod()->getAddressLocation();
|
$a = $participation->getAccompanyingPeriod()->getAddressLocation();
|
||||||
$addresses[$a->getId()] = $a;
|
$addresses[$a->getId()] = $a;
|
||||||
}
|
}
|
||||||
if (null !== $personLocation = $participation
|
|
||||||
->getAccompanyingPeriod()->getPersonLocation()) {
|
|
||||||
$a = $personLocation->getCurrentHouseholdAddress();
|
|
||||||
if (null !== $a) {
|
|
||||||
$addresses[$a->getId()] = $a;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove the actual address
|
// remove the actual address
|
||||||
|
@ -0,0 +1,103 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\Repository\Household;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\AddressReference;
|
||||||
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||||
|
use Chill\PersonBundle\Entity\Household\Household;
|
||||||
|
use Chill\PersonBundle\Security\Authorization\HouseholdVoter;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
|
||||||
|
final class HouseholdACLAwareRepository implements HouseholdACLAwareRepositoryInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
private EntityManagerInterface $em;
|
||||||
|
|
||||||
|
private AuthorizationHelper $authorizationHelper;
|
||||||
|
|
||||||
|
private Security $security;
|
||||||
|
|
||||||
|
public function __construct(EntityManagerInterface $em, AuthorizationHelper $authorizationHelper, Security $security)
|
||||||
|
{
|
||||||
|
$this->em = $em;
|
||||||
|
$this->authorizationHelper = $authorizationHelper;
|
||||||
|
$this->security = $security;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function countByAddressReference(AddressReference $addressReference): int
|
||||||
|
{
|
||||||
|
$qb = $this->buildQueryByAddressReference($addressReference);
|
||||||
|
$qb = $this->addACL($qb);
|
||||||
|
|
||||||
|
return $qb->select('COUNT(h)')
|
||||||
|
->getQuery()
|
||||||
|
->getSingleScalarResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findByAddressReference(
|
||||||
|
AddressReference $addressReference,
|
||||||
|
?int $firstResult = 0,
|
||||||
|
?int $maxResult = 50
|
||||||
|
): array {
|
||||||
|
$qb = $this->buildQueryByAddressReference($addressReference);
|
||||||
|
$qb = $this->addACL($qb);
|
||||||
|
|
||||||
|
return $qb
|
||||||
|
->select('h')
|
||||||
|
->setFirstResult($firstResult)
|
||||||
|
->setMaxResults($maxResult)
|
||||||
|
->getQuery()
|
||||||
|
->getResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildQueryByAddressReference(AddressReference $addressReference): QueryBuilder
|
||||||
|
{
|
||||||
|
$qb = $this->em->createQueryBuilder();
|
||||||
|
$qb
|
||||||
|
->select('h')
|
||||||
|
->from(Household::class, 'h')
|
||||||
|
->join('h.addresses', 'address')
|
||||||
|
->where(
|
||||||
|
$qb->expr()->eq('address.addressReference', ':reference')
|
||||||
|
)
|
||||||
|
->setParameter(':reference', $addressReference)
|
||||||
|
->andWhere(
|
||||||
|
$qb->expr()->andX(
|
||||||
|
$qb->expr()->lte('address.validFrom', ':today'),
|
||||||
|
$qb->expr()->orX(
|
||||||
|
$qb->expr()->isNull('address.validTo'),
|
||||||
|
$qb->expr()->gt('address.validTo', ':today')
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
->setParameter('today', new \DateTime('today'))
|
||||||
|
;
|
||||||
|
|
||||||
|
return $qb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addACL(QueryBuilder $qb, string $alias = 'h'): QueryBuilder
|
||||||
|
{
|
||||||
|
$centers = $this->authorizationHelper->getReachableCenters(
|
||||||
|
$this->security->getUser(),
|
||||||
|
HouseholdVoter::SHOW
|
||||||
|
);
|
||||||
|
|
||||||
|
if ([] === $centers) {
|
||||||
|
return $qb
|
||||||
|
->andWhere("'FALSE' = 'TRUE'");
|
||||||
|
}
|
||||||
|
|
||||||
|
$qb
|
||||||
|
->join($alias.'.members', 'members')
|
||||||
|
->join('members.person', 'person')
|
||||||
|
->andWhere(
|
||||||
|
$qb->expr()->in('person.center', ':centers')
|
||||||
|
)
|
||||||
|
->setParameter('centers', $centers);
|
||||||
|
|
||||||
|
return $qb;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\Repository\Household;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\AddressReference;
|
||||||
|
use Chill\PersonBundle\Entity\Household\Household;
|
||||||
|
|
||||||
|
interface HouseholdACLAwareRepositoryInterface
|
||||||
|
{
|
||||||
|
public function countByAddressReference(AddressReference $addressReference): int;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param AddressReference $addressReference
|
||||||
|
* @param int|null $firstResult
|
||||||
|
* @param int|null $maxResult
|
||||||
|
* @return array|Household[]
|
||||||
|
*/
|
||||||
|
public function findByAddressReference(
|
||||||
|
AddressReference $addressReference,
|
||||||
|
?int $firstResult = 0,
|
||||||
|
?int $maxResult = 50
|
||||||
|
): array;
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
import { fetchResults } from 'ChillMainAssets/lib/api/download.js';
|
||||||
|
|
||||||
|
const fetchHouseholdByAddressReference = async (reference) => {
|
||||||
|
const url = `/api/1.0/person/household/by-address-reference/${reference.id}.json`
|
||||||
|
return fetchResults(url);
|
||||||
|
};
|
||||||
|
|
||||||
|
export {
|
||||||
|
fetchHouseholdByAddressReference
|
||||||
|
};
|
@ -1,34 +1,150 @@
|
|||||||
<template>
|
<template>
|
||||||
<household></household>
|
<ol class="breadcrumb">
|
||||||
<concerned v-if="hasHouseholdOrLeave"></concerned>
|
<li
|
||||||
<dates v-if="showConfirm"></dates>
|
v-for="s in steps"
|
||||||
<confirmation v-if="showConfirm"></confirmation>
|
class="breadcrumb-item" :class="{ active: step === s }"
|
||||||
|
>
|
||||||
|
{{ $t('household_members_editor.app.steps.'+s) }}
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<concerned v-if="step === 'concerned'"></concerned>
|
||||||
|
<household v-if="step === 'household'" @ready-to-go="goToNext"></household>
|
||||||
|
<household-address v-if="step === 'household_address'"></household-address>
|
||||||
|
<positioning v-if="step === 'positioning'"></positioning>
|
||||||
|
<dates v-if="step === 'confirm'"></dates>
|
||||||
|
<confirmation v-if="step === 'confirm'"></confirmation>
|
||||||
|
|
||||||
|
<ul class="record_actions sticky-form-buttons">
|
||||||
|
<li class="cancel" v-if="step !== 'concerned' || hasReturnPath">
|
||||||
|
<button class="btn btn-cancel" @click="goToPrevious">
|
||||||
|
{{ $t('household_members_editor.app.cancel') }}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li v-if="step !== 'confirm'">
|
||||||
|
<button class="btn btn-action" @click="goToNext" :disabled="!isNextAllowed">
|
||||||
|
{{ $t('household_members_editor.app.next') }} <i class="fa fa-arrow-right"></i>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li v-else>
|
||||||
|
<button class="btn btn-save" @click="confirm" :disabled="hasWarnings">
|
||||||
|
{{ $t('household_members_editor.app.save') }}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
import { mapGetters } from 'vuex';
|
import {mapGetters, mapState} from 'vuex';
|
||||||
import Concerned from './components/Concerned.vue';
|
import Concerned from './components/Concerned.vue';
|
||||||
import Household from './components/Household.vue';
|
import Household from './components/Household.vue';
|
||||||
|
import HouseholdAddress from './components/HouseholdAddress';
|
||||||
import Dates from './components/Dates.vue';
|
import Dates from './components/Dates.vue';
|
||||||
import Confirmation from './components/Confirmation.vue';
|
import Confirmation from './components/Confirmation.vue';
|
||||||
|
import Positioning from "./components/Positioning";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
components: {
|
components: {
|
||||||
|
Positioning,
|
||||||
Concerned,
|
Concerned,
|
||||||
Household,
|
Household,
|
||||||
|
HouseholdAddress,
|
||||||
Dates,
|
Dates,
|
||||||
Confirmation,
|
Confirmation,
|
||||||
},
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
step: 'concerned',
|
||||||
|
};
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapState({
|
||||||
'hasHouseholdOrLeave',
|
hasWarnings: (state) => state.warnings.length > 0 || state.errors.length > 0,
|
||||||
'hasPersonsWellPositionnated',
|
}),
|
||||||
]),
|
steps() {
|
||||||
showConfirm () {
|
let s = ['concerned', 'household'];
|
||||||
|
|
||||||
|
if (this.$store.getters.isHouseholdNew) {
|
||||||
|
s.push('household_address');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.$store.getters.isModeLeave) {
|
||||||
|
s.push('positioning');
|
||||||
|
}
|
||||||
|
|
||||||
|
s.push('confirm');
|
||||||
|
|
||||||
|
return s;
|
||||||
|
},
|
||||||
|
hasReturnPath() {
|
||||||
|
let params = new URLSearchParams(window.location.search);
|
||||||
|
|
||||||
|
return params.has('returnPath');
|
||||||
|
},
|
||||||
|
// return true if the next step is allowed
|
||||||
|
isNextAllowed() {
|
||||||
|
switch (this.$data.step) {
|
||||||
|
case 'concerned':
|
||||||
|
return this.$store.state.concerned.length > 0;
|
||||||
|
case 'household':
|
||||||
|
return this.$store.state.mode !== null;
|
||||||
|
case 'household_address':
|
||||||
|
return this.$store.getters.hasHouseholdAddress || this.$store.getters.isHouseholdForceNoAddress;
|
||||||
|
case 'positioning':
|
||||||
return this.$store.getters.hasHouseholdOrLeave
|
return this.$store.getters.hasHouseholdOrLeave
|
||||||
&& this.$store.getters.hasPersonsWellPositionnated;
|
&& this.$store.getters.hasPersonsWellPositionnated;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
goToNext() {
|
||||||
|
console.log('go to next');
|
||||||
|
switch (this.$data.step) {
|
||||||
|
case 'concerned':
|
||||||
|
this.$data.step = 'household';
|
||||||
|
break;
|
||||||
|
case 'household':
|
||||||
|
if (this.$store.getters.isHouseholdNew) {
|
||||||
|
this.$data.step = 'household_address';
|
||||||
|
break;
|
||||||
|
} else if (this.$store.getters.isModeLeave) {
|
||||||
|
this.$data.step = 'confirm';
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
this.$data.step = 'positioning';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'household_address':
|
||||||
|
this.$data.step = 'positioning';
|
||||||
|
break;
|
||||||
|
case 'positioning':
|
||||||
|
this.$data.step = 'confirm';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
goToPrevious() {
|
||||||
|
if (this.$data.step === 'concerned') {
|
||||||
|
let params = new URLSearchParams(window.location.search);
|
||||||
|
if (params.has('returnPath')) {
|
||||||
|
window.location.replace(params.get('returnPath'));
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let s = this.steps;
|
||||||
|
let index = s.indexOf(this.$data.step);
|
||||||
|
if (s[index - 1] === undefined) {
|
||||||
|
throw Error("step not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$data.step = s[index - 1];
|
||||||
|
},
|
||||||
|
confirm() {
|
||||||
|
this.$store.dispatch('confirm');
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,75 +1,28 @@
|
|||||||
<template>
|
<template>
|
||||||
<h2 class="mt-4">{{ $t('household_members_editor.concerned.title') }}</h2>
|
<h2 class="mt-4">{{ $t('household_members_editor.concerned.title') }}</h2>
|
||||||
|
|
||||||
<h3 v-if="needsPositionning">
|
|
||||||
{{ $t('household_members_editor.concerned.persons_to_positionnate') }}
|
|
||||||
</h3>
|
|
||||||
<h3 v-else>
|
|
||||||
{{ $t('household_members_editor.concerned.persons_leaving') }}
|
|
||||||
</h3>
|
|
||||||
|
|
||||||
<div v-if="noPerson">
|
<div v-if="noPerson">
|
||||||
<div class="alert alert-info">
|
<div class="alert alert-info">
|
||||||
{{ $t('household_members_editor.add_at_least_onePerson') }}
|
{{ $t('household_members_editor.concerned.add_at_least_onePerson') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="allPersonsPositionnated">
|
|
||||||
<span class="chill-no-data-statement">{{ $t('household_members_editor.all_positionnated') }}</span>
|
|
||||||
</div>
|
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div class="flex-table list-household-members">
|
<p>
|
||||||
<div v-for="conc in concUnpositionned"
|
{{ $t('household_members_editor.concerned.persons_will_be_moved') }} :
|
||||||
class="item-bloc"
|
<span v-for="c in concerned">
|
||||||
v-bind:key="conc.person.id"
|
<person-render-box render="badge" :options="{addLink: false}" :person="c.person"></person-render-box>
|
||||||
>
|
<button class="btn" @click="removePerson(c.person)" v-if="c.allowRemove" style="padding-left:0;">
|
||||||
<div class="item-row">
|
<span class="fa-stack fa-lg" :title="$t('household_members_editor.concerned.remove_concerned')">
|
||||||
<div class="item-col">
|
<i class="fa fa-circle fa-stack-1x text-danger"></i>
|
||||||
<div>
|
<i class="fa fa-times fa-stack-1x"></i>
|
||||||
<person-render-box render="badge" :options="{}" :person="conc.person"></person-render-box>
|
</span>
|
||||||
</div>
|
|
||||||
<div v-if="conc.person.birthdate !== null">
|
|
||||||
{{ $t('person.born', {'gender': conc.person.gender} ) }}
|
|
||||||
{{ $d(conc.person.birthdate.datetime, 'short') }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="item-col">
|
|
||||||
<ul class="list-content fa-ul">
|
|
||||||
<li>
|
|
||||||
<i class="fa fa-li fa-map-marker"></i>
|
|
||||||
<span class="chill-no-data-statement">Sans adresse</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="needsPositionning" class="item-row move_to">
|
|
||||||
<div class="item-col">
|
|
||||||
|
|
||||||
<p class="move_hint">{{ $t('household_members_editor.concerned.move_to') }}:</p>
|
|
||||||
|
|
||||||
<template
|
|
||||||
v-for="position in positions"
|
|
||||||
>
|
|
||||||
|
|
||||||
<button
|
|
||||||
class="btn btn-outline-primary"
|
|
||||||
@click="moveToPosition(conc.person.id, position.id)"
|
|
||||||
>
|
|
||||||
{{ position.label.fr }}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<button v-if="conc.allowRemove" @click="removeConcerned(conc)" class="btn btn-primary">
|
|
||||||
{{ $t('household_members_editor.remove_concerned') }}
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</span>
|
||||||
</div>
|
</p>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<ul class="record_actions">
|
||||||
|
<li>
|
||||||
<add-persons
|
<add-persons
|
||||||
buttonTitle="household_members_editor.concerned.add_persons"
|
buttonTitle="household_members_editor.concerned.add_persons"
|
||||||
modalTitle="household_members_editor.concerned.search"
|
modalTitle="household_members_editor.concerned.search"
|
||||||
@ -78,41 +31,11 @@
|
|||||||
@addNewPersons="addNewPersons"
|
@addNewPersons="addNewPersons"
|
||||||
ref="addPersons"> <!-- to cast child method -->
|
ref="addPersons"> <!-- to cast child method -->
|
||||||
</add-persons>
|
</add-persons>
|
||||||
</div>
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<div v-if="needsPositionning" class="positions">
|
|
||||||
<div
|
|
||||||
v-for="position in positions"
|
|
||||||
>
|
|
||||||
<h3>{{ position.label.fr }}</h3>
|
|
||||||
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<div v-else>
|
|
||||||
<p class="chill-no-data-statement">{{ $t('household_members_editor.concerned.no_person_in_position') }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
div.person {
|
|
||||||
cursor: move;
|
|
||||||
|
|
||||||
* {
|
|
||||||
cursor: move
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.move_to {
|
.move_to {
|
||||||
.move_hint {
|
.move_hint {
|
||||||
@ -124,33 +47,26 @@ div.person {
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex';
|
import { mapState, mapGetters } from 'vuex';
|
||||||
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue';
|
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue';
|
||||||
import PersonRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/PersonRenderBox.vue';
|
import PersonRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/PersonRenderBox.vue';
|
||||||
import MemberDetails from './MemberDetails.vue';
|
|
||||||
import { ISOToDatetime } from 'ChillMainAssets/chill/js/date.js';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Concerned',
|
name: 'Concerned',
|
||||||
components: {
|
components: {
|
||||||
AddPersons,
|
AddPersons,
|
||||||
MemberDetails,
|
|
||||||
PersonRenderBox,
|
PersonRenderBox,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
...mapState([
|
||||||
|
'concerned'
|
||||||
|
]),
|
||||||
...mapGetters([
|
...mapGetters([
|
||||||
'concUnpositionned',
|
'persons',
|
||||||
'positions',
|
|
||||||
'concByPosition',
|
|
||||||
'needsPositionning'
|
|
||||||
]),
|
]),
|
||||||
noPerson () {
|
noPerson () {
|
||||||
return this.$store.getters.persons.length === 0;
|
return this.$store.getters.persons.length === 0;
|
||||||
},
|
},
|
||||||
allPersonsPositionnated () {
|
|
||||||
return this.$store.getters.persons.length > 0
|
|
||||||
&& this.$store.getters.concUnpositionned.length === 0;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -172,11 +88,9 @@ export default {
|
|||||||
this.$refs.addPersons.resetSearch(); // to cast child method
|
this.$refs.addPersons.resetSearch(); // to cast child method
|
||||||
modal.showModal = false;
|
modal.showModal = false;
|
||||||
},
|
},
|
||||||
moveToPosition(person_id, position_id) {
|
removePerson(person) {
|
||||||
this.$store.dispatch('markPosition', { person_id, position_id });
|
console.log('remove person in concerned', person);
|
||||||
},
|
this.$store.dispatch('removePerson', person);
|
||||||
removeConcerned(conc) {
|
|
||||||
this.$store.dispatch('removeConcerned', conc);
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,29 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<div v-if="hasWarning" class="alert alert-warning">
|
||||||
<div v-if="hasWarnings" class="alert alert-warning">
|
|
||||||
{{ $t('household_members_editor.confirmation.there_are_warnings') }}
|
{{ $t('household_members_editor.confirmation.there_are_warnings') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p v-if="hasWarnings">
|
<p v-if="hasWarning">
|
||||||
{{ $t('household_members_editor.confirmation.check_those_items') }}
|
{{ $t('household_members_editor.confirmation.check_those_items') }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="(msg, index) in warnings">
|
<li v-for="(msg, index) in warnings" class="warning">
|
||||||
{{ $t(msg.m, msg.a) }}
|
{{ $t(msg.m, msg.a) }}
|
||||||
</li>
|
</li>
|
||||||
<li v-for="msg in errors">
|
<li v-for="msg in errors" class="error">
|
||||||
{{ msg }}
|
{{ msg }}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<ul class="record_actions sticky-form-buttons">
|
|
||||||
<li>
|
|
||||||
<button class="btn btn-save" :disabled="hasWarnings" @click="confirm">
|
|
||||||
{{ $t('household_members_editor.confirmation.save') }}
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@ -36,17 +27,11 @@ export default {
|
|||||||
name: 'Confirmation',
|
name: 'Confirmation',
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
...mapState({
|
||||||
|
hasWarnings: (state) => state.warnings.length > 0 || state.errors.length > 0,
|
||||||
warnings: (state) => state.warnings,
|
warnings: (state) => state.warnings,
|
||||||
errors: (state) => state.errors,
|
errors: (state) => state.errors,
|
||||||
hasNoWarnings: (state) => state.warnings.length === 0 && state.errors.length === 0,
|
|
||||||
hasWarnings: (state) => state.warnings.length > 0 || state.errors.length > 0,
|
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
methods: {
|
|
||||||
confirm() {
|
|
||||||
this.$store.dispatch('confirm');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
<template>
|
||||||
|
<div class="flex-table" v-if="hasHousehold">
|
||||||
|
<div class="item-bloc">
|
||||||
|
<household-render-box :household="fakeHouseholdWithConcerned"></household-render-box>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex-table" v-if="isModeLeave">
|
||||||
|
<div class="item-bloc">
|
||||||
|
<section>
|
||||||
|
<div class="item-row">
|
||||||
|
<div class="item-col">
|
||||||
|
<div class="h4">
|
||||||
|
<span class="fa-stack fa-lg">
|
||||||
|
<i class="fa fa-home fa-stack-1x"></i>
|
||||||
|
<i class="fa fa-ban fa-stack-2x text-danger"></i>
|
||||||
|
</span>
|
||||||
|
{{ $t('household_members_editor.household.leave_without_household') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-row">
|
||||||
|
{{ $t('household_members_editor.household.will_leave_any_household_explanation')}}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapGetters } from 'vuex';
|
||||||
|
import HouseholdRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/HouseholdRenderBox.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "CurrentHousehold",
|
||||||
|
components: {
|
||||||
|
HouseholdRenderBox,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters([
|
||||||
|
'hasHousehold',
|
||||||
|
'fakeHouseholdWithConcerned',
|
||||||
|
'isModeLeave'
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
</style>
|
@ -1,5 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<h2>{{ $t('household_members_editor.dates_title') }}</h2>
|
|
||||||
|
<current-household></current-household>
|
||||||
|
|
||||||
|
<h2>{{ $t('household_members_editor.dates.dates_title') }}</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<label for="start_date">
|
<label for="start_date">
|
||||||
@ -11,8 +14,13 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
import CurrentHousehold from "./CurrentHousehold";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Dates',
|
name: 'Dates',
|
||||||
|
components: {
|
||||||
|
CurrentHousehold
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
startDate: {
|
startDate: {
|
||||||
get() {
|
get() {
|
||||||
|
@ -2,66 +2,48 @@
|
|||||||
|
|
||||||
<h2 class="mt-4">{{ $t('household_members_editor.household_part') }}</h2>
|
<h2 class="mt-4">{{ $t('household_members_editor.household_part') }}</h2>
|
||||||
|
|
||||||
<div v-if="mode == null">
|
<div class="alert alert-info" v-if="!hasHousehold">
|
||||||
|
{{ $t('household_members_editor.household.no_household_choose_one') }}
|
||||||
|
</div>
|
||||||
|
<template v-else>
|
||||||
|
<current-household></current-household>
|
||||||
|
</template>
|
||||||
|
|
||||||
<div class="alert alert-info">{{ $t('household_members_editor.household.no_household_choose_one') }}</div>
|
<div v-if="hasHouseholdSuggestion" class="householdSuggestions my-5">
|
||||||
|
<h4 class="mb-3">
|
||||||
<div class="flex-table householdSuggestionList">
|
{{ $t('household_members_editor.household.household_suggested') }}
|
||||||
<div v-if="isModeNewAllowed" class="item-bloc">
|
</h4>
|
||||||
<div>
|
<p>{{ $t('household_members_editor.household.household_suggested_explanation') }}</p>
|
||||||
<section>
|
<div class="accordion" id="householdSuggestions">
|
||||||
<div class="item-row">
|
<div class="accordion-item">
|
||||||
<div class="item-col">
|
<h2 class="accordion-header" id="heading_household_suggestions">
|
||||||
<div class="h4">
|
<button v-if="!showHouseholdSuggestion"
|
||||||
<i class="fa fa-home"></i> {{ $t('household_members_editor.household.new_household') }}
|
class="accordion-button collapsed"
|
||||||
</div>
|
type="button"
|
||||||
</div>
|
data-bs-toggle="collapse"
|
||||||
</div>
|
aria-expanded="false"
|
||||||
</section>
|
@click="toggleHouseholdSuggestion">
|
||||||
<ul class="record_actions">
|
{{ $tc('household_members_editor.show_household_suggestion', countHouseholdSuggestion) }}
|
||||||
<li>
|
|
||||||
<button @click="setModeNew" class="btn btn-sm btn-create">{{ $t('household_members_editor.household.create_household') }}</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- if allow leave household -->
|
|
||||||
<div v-if="isModeLeaveAllowed" class="item-bloc">
|
|
||||||
<div>
|
|
||||||
<section>
|
|
||||||
<div class="item-row">
|
|
||||||
<div class="item-col">
|
|
||||||
<div class="h4">
|
|
||||||
<span class="fa-stack fa-lg">
|
|
||||||
<i class="fa fa-home fa-stack-1x"></i>
|
|
||||||
<i class="fa fa-ban fa-stack-2x text-danger"></i>
|
|
||||||
</span>
|
|
||||||
{{ $t('household_members_editor.household.leave_without_household') }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="item-row">
|
|
||||||
{{ $t('household_members_editor.household.will_leave_any_household_explanation')}}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<ul class="record_actions">
|
|
||||||
<li>
|
|
||||||
<button @click="setModeLeave" class="btn btn-sm">
|
|
||||||
<i class="fa fa-sign-out"></i>
|
|
||||||
{{ $t('household_members_editor.household.leave') }}
|
|
||||||
</button>
|
</button>
|
||||||
</li>
|
<button v-if="showHouseholdSuggestion"
|
||||||
</ul>
|
class="accordion-button"
|
||||||
</div>
|
type="button"
|
||||||
</div>
|
data-bs-toggle="collapse"
|
||||||
|
aria-expanded="true"
|
||||||
<div v-for="item in getSuggestions">
|
@click="toggleHouseholdSuggestion">
|
||||||
<div class="item-bloc">
|
{{ $t('household_members_editor.hide_household_suggestion') }}
|
||||||
<household-render-box :household="item.household"></household-render-box>
|
</button>
|
||||||
|
<!-- disabled bootstrap behaviour: data-bs-target="#collapse_household_suggestions" aria-controls="collapse_household_suggestions" -->
|
||||||
|
</h2>
|
||||||
|
<div class="accordion-collapse" id="collapse_household_suggestions"
|
||||||
|
aria-labelledby="heading_household_suggestions" data-bs-parent="#householdSuggestions">
|
||||||
|
<div v-if="showHouseholdSuggestion">
|
||||||
|
<div class="flex-table householdSuggestionList">
|
||||||
|
<div v-for="s in getSuggestions" class="item-bloc">
|
||||||
|
<household-render-box :household="s.household"></household-render-box>
|
||||||
<ul class="record_actions">
|
<ul class="record_actions">
|
||||||
<li>
|
<li>
|
||||||
<button class="btn btn-sm btn-choose" @click="selectHousehold(item.household)">
|
<button class="btn btn-sm btn-choose" @click="selectHousehold(s.household)">
|
||||||
{{ $t('household_members_editor.select_household') }}
|
{{ $t('household_members_editor.select_household') }}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
@ -70,73 +52,39 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div v-else>
|
|
||||||
<div class="flex-table">
|
|
||||||
<div class="item-bloc">
|
|
||||||
<template v-if="isModeLeave">
|
|
||||||
<section>
|
|
||||||
<div class="item-row">
|
|
||||||
<div class="item-col">
|
|
||||||
<div class="h4">
|
|
||||||
<span class="fa-stack fa-lg">
|
|
||||||
<i class="fa fa-home fa-stack-1x"></i>
|
|
||||||
<i class="fa fa-ban fa-stack-2x text-danger"></i>
|
|
||||||
</span>
|
|
||||||
{{ $t('household_members_editor.household.leave_without_household') }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="item-row">
|
|
||||||
{{ $t('household_members_editor.household.will_leave_any_household_explanation')}}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
<household-render-box :household="household" :isAddressMultiline="true"></household-render-box>
|
|
||||||
<ul class="record_actions">
|
<ul class="record_actions">
|
||||||
<li>
|
<li v-if="hasHousehold">
|
||||||
<add-address
|
<button @click="resetMode" class="btn btn-sm btn-misc">{{ $t('household_members_editor.household.reset_mode')}}</button>
|
||||||
:context="getAddressContext"
|
|
||||||
:key="addAddress.key"
|
|
||||||
:options="addAddress.options"
|
|
||||||
:addressChangedCallback="addressChanged"
|
|
||||||
></add-address>
|
|
||||||
</li>
|
</li>
|
||||||
<li v-if="hasHouseholdAddress">
|
<li v-if="!hasHousehold">
|
||||||
<button class="btn btn-remove"
|
<button @click="setModeNew" class="btn btn-sm btn-create">{{ $t('household_members_editor.household.create_household') }}</button>
|
||||||
@click="removeHouseholdAddress">
|
</li>
|
||||||
{{ $t('household_members_editor.household.remove_address') }}
|
<li v-if="isModeLeaveAllowed && !hasHousehold">
|
||||||
|
<button @click="setModeLeave" class="btn btn-sm btn-misc">
|
||||||
|
<i class="fa fa-sign-out"></i>
|
||||||
|
{{ $t('household_members_editor.household.leave') }}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul v-if="isModeNewAllowed || isModeLeaveAllowed || getModeSuggestions.length > 0" class="record_actions">
|
|
||||||
<li>
|
|
||||||
<button class="btn btn-sm btn-chill-beige" @click="resetMode">
|
|
||||||
{{ $t('household_members_editor.household.reset_mode') }}
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters, mapState } from 'vuex';
|
import { mapGetters, mapState } from 'vuex';
|
||||||
import HouseholdRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/HouseholdRenderBox.vue';
|
import HouseholdRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/HouseholdRenderBox.vue';
|
||||||
import AddressRenderBox from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue';
|
import CurrentHousehold from './CurrentHousehold';
|
||||||
import AddAddress from 'ChillMainAssets/vuejs/Address/components/AddAddress.vue';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Household',
|
name: 'Household',
|
||||||
components: {
|
components: {
|
||||||
|
CurrentHousehold,
|
||||||
HouseholdRenderBox,
|
HouseholdRenderBox,
|
||||||
AddressRenderBox,
|
|
||||||
AddAddress,
|
|
||||||
},
|
},
|
||||||
|
emits: ['readyToGo'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
addAddress: {
|
addAddress: {
|
||||||
@ -179,6 +127,7 @@ export default {
|
|||||||
'getAddressContext',
|
'getAddressContext',
|
||||||
]),
|
]),
|
||||||
...mapState([
|
...mapState([
|
||||||
|
'household',
|
||||||
'showHouseholdSuggestion',
|
'showHouseholdSuggestion',
|
||||||
'showAddressSuggestion',
|
'showAddressSuggestion',
|
||||||
'mode',
|
'mode',
|
||||||
@ -190,13 +139,21 @@ export default {
|
|||||||
return false;
|
return false;
|
||||||
return this.$store.state.allowHouseholdSearch && !this.$store.getters.hasHousehold;
|
return this.$store.state.allowHouseholdSearch && !this.$store.getters.hasHousehold;
|
||||||
},
|
},
|
||||||
|
isHouseholdNewDesactivated() {
|
||||||
|
return this.$store.state.mode !== null && !this.$store.getters.isHouseholdNew;
|
||||||
|
},
|
||||||
|
isHouseholdLeaveDesactivated() {
|
||||||
|
return this.$store.state.mode !== null && this.$store.state.mode !== "leave";
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setModeNew() {
|
setModeNew() {
|
||||||
this.$store.dispatch('createHousehold');
|
this.$store.dispatch('createHousehold');
|
||||||
|
this.$emit('readyToGo');
|
||||||
},
|
},
|
||||||
setModeLeave() {
|
setModeLeave() {
|
||||||
this.$store.dispatch('forceLeaveWithoutHousehold');
|
this.$store.dispatch('forceLeaveWithoutHousehold');
|
||||||
|
this.$emit('readyToGo');
|
||||||
},
|
},
|
||||||
resetMode() {
|
resetMode() {
|
||||||
this.$store.commit('resetMode');
|
this.$store.commit('resetMode');
|
||||||
@ -207,10 +164,14 @@ export default {
|
|||||||
},
|
},
|
||||||
selectHousehold(h) {
|
selectHousehold(h) {
|
||||||
this.$store.dispatch('selectHousehold', h);
|
this.$store.dispatch('selectHousehold', h);
|
||||||
|
this.$emit('readyToGo');
|
||||||
},
|
},
|
||||||
removeHouseholdAddress() {
|
removeHouseholdAddress() {
|
||||||
this.$store.commit('removeHouseholdAddress');
|
this.$store.commit('removeHouseholdAddress');
|
||||||
},
|
},
|
||||||
|
toggleHouseholdSuggestion() {
|
||||||
|
this.$store.commit('toggleHouseholdSuggestion');
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -218,6 +179,18 @@ export default {
|
|||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|
||||||
|
.filtered {
|
||||||
|
filter: grayscale(1) opacity(0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.filteredButActive {
|
||||||
|
|
||||||
|
filter: grayscale(1) opacity(0.6);
|
||||||
|
&:hover {
|
||||||
|
filter: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
div#household_members_editor div,
|
div#household_members_editor div,
|
||||||
div.householdSuggestionList {
|
div.householdSuggestionList {
|
||||||
&.flex-table {
|
&.flex-table {
|
||||||
|
@ -0,0 +1,88 @@
|
|||||||
|
<template>
|
||||||
|
<current-household></current-household>
|
||||||
|
|
||||||
|
<ul class="record_actions">
|
||||||
|
<li v-if="!hasHouseholdAddress && !isHouseholdForceAddress">
|
||||||
|
<button class="btn" @click="markNoAddress">
|
||||||
|
{{ $t('household_members_editor.household_address.mark_no_address') }}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li v-if="!hasHouseholdAddress">
|
||||||
|
<add-address
|
||||||
|
:context="getAddressContext"
|
||||||
|
:key="addAddress.key"
|
||||||
|
:options="addAddress.options"
|
||||||
|
:addressChangedCallback="addressChanged"
|
||||||
|
></add-address>
|
||||||
|
</li>
|
||||||
|
<li v-if="hasHouseholdAddress">
|
||||||
|
<button class="btn btn-remove"
|
||||||
|
@click="removeHouseholdAddress">
|
||||||
|
{{ $t('household_members_editor.household_address.remove_address') }}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import AddAddress from 'ChillMainAssets/vuejs/Address/components/AddAddress.vue';
|
||||||
|
import CurrentHousehold from './CurrentHousehold';
|
||||||
|
import { mapGetters } from 'vuex';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "HouseholdAddress.vue",
|
||||||
|
components: {
|
||||||
|
CurrentHousehold,
|
||||||
|
AddAddress,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
addAddress: {
|
||||||
|
key: 'household_new',
|
||||||
|
options: {
|
||||||
|
useDate: {
|
||||||
|
validFrom: false,
|
||||||
|
validTo: false,
|
||||||
|
},
|
||||||
|
onlyButton: true,
|
||||||
|
button: {
|
||||||
|
text: {
|
||||||
|
create: 'household_members_editor.household_address.set_address',
|
||||||
|
edit: 'household_members_editor.household_address.update_address',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
create: 'household_members_editor.household_address.create_new_address',
|
||||||
|
edit: 'household_members_editor.household_address.update_address_title',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters([
|
||||||
|
'isHouseholdNew',
|
||||||
|
'hasHouseholdAddress',
|
||||||
|
'getAddressContext',
|
||||||
|
'isHouseholdForceNoAddress'
|
||||||
|
])
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
addressChanged(payload) {
|
||||||
|
console.log("addressChanged", payload);
|
||||||
|
this.$store.dispatch('setHouseholdNewAddress', payload.address);
|
||||||
|
},
|
||||||
|
markNoAddress() {
|
||||||
|
this.$store.commit('markHouseholdNoAddress');
|
||||||
|
},
|
||||||
|
removeHouseholdAddress() {
|
||||||
|
this.$store.commit('removeHouseholdAddress');
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@ -0,0 +1,106 @@
|
|||||||
|
<template>
|
||||||
|
<current-household></current-household>
|
||||||
|
|
||||||
|
<h2>{{ $t('household_members_editor.positioning.persons_to_positionnate')}}</h2>
|
||||||
|
|
||||||
|
<div class="list-household-members">
|
||||||
|
<div
|
||||||
|
v-for="conc in concerned"
|
||||||
|
class="item-bloc"
|
||||||
|
v-bind:key="conc.person.id"
|
||||||
|
>
|
||||||
|
<div class="pick-position">
|
||||||
|
<div class="person">
|
||||||
|
<person-render-box render="badge" :options="{}" :person="conc.person"></person-render-box>
|
||||||
|
</div>
|
||||||
|
<div class="holder">
|
||||||
|
<button
|
||||||
|
class="btn"
|
||||||
|
:disabled="!allowHolderForConcerned(conc)"
|
||||||
|
:class="{'btn-outline-chill-green': !conc.holder, 'btn-chill-green': conc.holder }"
|
||||||
|
@click="toggleHolder(conc)"
|
||||||
|
>
|
||||||
|
{{ $t('household_members_editor.positioning.holder') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-for="position in positions"
|
||||||
|
class="position"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="btn"
|
||||||
|
:class="{ 'btn-primary': conc.position === position, 'btn-outline-primary': conc.position !== position }"
|
||||||
|
@click="moveToPosition(conc.person.id, position.id)"
|
||||||
|
>
|
||||||
|
{{ position.label.fr }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import MemberDetails from './MemberDetails.vue';
|
||||||
|
import {mapGetters, mapState} from "vuex";
|
||||||
|
import CurrentHousehold from "./CurrentHousehold";
|
||||||
|
import PersonRenderBox from 'ChillPersonAssets/vuejs/_components/Entity/PersonRenderBox.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Positioning",
|
||||||
|
components: {
|
||||||
|
CurrentHousehold,
|
||||||
|
PersonRenderBox,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState([
|
||||||
|
'concerned'
|
||||||
|
]),
|
||||||
|
...mapGetters([
|
||||||
|
'persons',
|
||||||
|
'concUnpositionned',
|
||||||
|
'positions',
|
||||||
|
'concByPosition',
|
||||||
|
]),
|
||||||
|
allPersonsPositionnated () {
|
||||||
|
return this.$store.getters.persons.length > 0
|
||||||
|
&& this.$store.getters.concUnpositionned.length === 0;
|
||||||
|
},
|
||||||
|
allowHolderForConcerned: (app) => (conc) => {
|
||||||
|
console.log('allow holder for concerned', conc);
|
||||||
|
if (conc.position === null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return conc.position.allowHolder;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
moveToPosition(person_id, position_id) {
|
||||||
|
this.$store.dispatch('markPosition', { person_id, position_id });
|
||||||
|
},
|
||||||
|
toggleHolder(conc) {
|
||||||
|
console.log('toggle holder', conc);
|
||||||
|
this.$store.dispatch('toggleHolder', conc);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
.pick-position {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.person {
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
.holder {
|
||||||
|
margin-right: 1.2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -5,65 +5,80 @@ const appMessages = {
|
|||||||
fr: {
|
fr: {
|
||||||
household_members_editor: {
|
household_members_editor: {
|
||||||
household: {
|
household: {
|
||||||
no_household_choose_one: "Aucun ménage de destination. Choisissez un ménage. Les usagers concernés par la modification apparaitront ensuite.",
|
no_household_choose_one: "Aucun ménage de destination. Choisissez un ménage.",
|
||||||
new_household: "Nouveau ménage",
|
// new_household: "Nouveau ménage",
|
||||||
create_household: "Créer",
|
create_household: "Créer",
|
||||||
search_household: "Chercher un ménage",
|
search_household: "Chercher un ménage",
|
||||||
will_leave_any_household: "Les usagers ne rejoignent pas de ménage",
|
will_leave_any_household: "Les usagers ne rejoignent pas de ménage",
|
||||||
leave: "Quitter",
|
leave: "Quitter sans rejoindre un ménage",
|
||||||
will_leave_any_household_explanation: "Les usagers quitteront leur ménage actuel, et ne seront pas associés à un autre ménage. Par ailleurs, ils seront enregistrés comme étant sans adresse connue.",
|
will_leave_any_household_explanation: "Les usagers quitteront leur ménage actuel, et ne seront pas associés à un autre ménage. Par ailleurs, ils seront enregistrés comme étant sans adresse connue.",
|
||||||
leave_without_household: "Sans nouveau ménage",
|
leave_without_household: "Sans nouveau ménage",
|
||||||
set_address: "Indiquer une adresse",
|
|
||||||
reset_mode: "Modifier la destination",
|
reset_mode: "Modifier la destination",
|
||||||
remove_address: "Supprimer l'adresse",
|
household_suggested: "Suggestions de ménage",
|
||||||
update_address: "Mettre à jour l'adresse",
|
household_suggested_explanation: "Les ménages suivants sont connus et pourraient peut-être correspondre à des ménages recherchés."
|
||||||
// remove ?
|
// remove ?
|
||||||
/*
|
/*
|
||||||
where_live_the_household: "À quelle adresse habite ce ménage ?",
|
where_live_the_household: "À quelle adresse habite ce ménage ?",
|
||||||
household_live_to_this_address: "Sélectionner l'adresse",
|
household_live_to_this_address: "Sélectionner l'adresse",
|
||||||
no_suggestions: "Aucune adresse à suggérer",
|
no_suggestions: "Aucune adresse à suggérer",
|
||||||
delete_this_address: "Supprimer cette adresse",
|
|
||||||
create_new_address: "Créer une nouvelle adresse",
|
|
||||||
or_create_new_address: "Ou créer une nouvelle adresse",
|
or_create_new_address: "Ou créer une nouvelle adresse",
|
||||||
|
|
||||||
*/
|
*/
|
||||||
// end remove ?
|
// end remove ?
|
||||||
},
|
},
|
||||||
|
household_address: {
|
||||||
|
mark_no_address: "Ne pas indiquer d'adresse",
|
||||||
|
remove_address: "Supprimer l'adresse",
|
||||||
|
update_address: "Mettre à jour l'adresse",
|
||||||
|
set_address: "Indiquer une adresse",
|
||||||
|
create_new_address: "Créer une nouvelle adresse",
|
||||||
|
},
|
||||||
concerned: {
|
concerned: {
|
||||||
title: "Nouveaux membres du ménage",
|
title: "Usagers déplacés",
|
||||||
|
persons_will_be_moved: "Les usagers suivants vont être déplacés",
|
||||||
|
add_at_least_onePerson: "Indiquez au moins un usager à déplacer",
|
||||||
|
remove_concerned: "Ne plus transférer",
|
||||||
|
// old ?
|
||||||
add_persons: "Ajouter d'autres usagers",
|
add_persons: "Ajouter d'autres usagers",
|
||||||
search: "Rechercher des usagers",
|
search: "Rechercher des usagers",
|
||||||
move_to: "Déplacer vers",
|
move_to: "Déplacer vers",
|
||||||
persons_to_positionnate: 'Usagers à positionner',
|
|
||||||
persons_leaving: "Usagers quittant leurs ménages",
|
persons_leaving: "Usagers quittant leurs ménages",
|
||||||
no_person_in_position: "Aucun usager ne sera ajouté à cette position",
|
no_person_in_position: "Aucun usager ne sera ajouté à cette position",
|
||||||
|
},
|
||||||
|
positioning: {
|
||||||
|
persons_to_positionnate: 'Usagers à positionner',
|
||||||
|
holder: "Titulaire",
|
||||||
|
},
|
||||||
|
app: {
|
||||||
|
next: 'Suivant',
|
||||||
|
cancel: 'Annuler',
|
||||||
|
save: 'Enregistrer',
|
||||||
|
steps: {
|
||||||
|
concerned: 'Usagers concernés',
|
||||||
|
household: 'Ménage de destination',
|
||||||
|
household_address: 'Adresse du nouveau ménage',
|
||||||
|
positioning: 'Position dans le ménage',
|
||||||
|
confirm: 'Confirmation'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
drop_persons_here: "Glissez-déposez ici les usagers pour la position \"{position}\"",
|
drop_persons_here: "Glissez-déposez ici les usagers pour la position \"{position}\"",
|
||||||
all_positionnated: "Tous les usagers sont positionnés",
|
all_positionnated: "Tous les usagers sont positionnés",
|
||||||
holder: "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: "Destination",
|
household_part: "Destination",
|
||||||
suggestions: "Suggestions",
|
suggestions: "Suggestions",
|
||||||
hide_household_suggestion: "Masquer les suggestions",
|
hide_household_suggestion: "Masquer les suggestions",
|
||||||
show_household_suggestion: 'Aucune suggestion | Afficher une suggestion | Afficher {count} suggestions',
|
show_household_suggestion: 'Aucune suggestion | Afficher une suggestion | Afficher {count} suggestions',
|
||||||
household_for_participants_accompanying_period: "Des ménages partagent le même parcours",
|
household_for_participants_accompanying_period: "Des ménages partagent le même parcours",
|
||||||
select_household: "Sélectionner le ménage",
|
select_household: "Sélectionner le ménage",
|
||||||
dates_title: "Période de validité",
|
|
||||||
dates: {
|
dates: {
|
||||||
start_date: "Début de validité",
|
start_date: "Début de validité",
|
||||||
end_date: "Fin de validité",
|
end_date: "Fin de validité",
|
||||||
|
dates_title: "Période de validité",
|
||||||
},
|
},
|
||||||
confirmation: {
|
confirmation: {
|
||||||
save: "Enregistrer",
|
save: "Enregistrer",
|
||||||
there_are_warnings: "Impossible de valider actuellement",
|
there_are_warnings: "Impossible de valider actuellement",
|
||||||
check_those_items: "Veuillez corriger les éléments suivants",
|
check_those_items: "Veuillez corriger les éléments suivants",
|
||||||
},
|
},
|
||||||
give_a_position_to_every_person: "Indiquez une position pour chaque usager concerné",
|
|
||||||
add_destination: "Indiquez un ménage de destination",
|
|
||||||
add_at_least_onePerson: "Indiquez au moins un usager à transférer",
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { createStore } from 'vuex';
|
import { createStore } from 'vuex';
|
||||||
import { householdMove, fetchHouseholdSuggestionByAccompanyingPeriod, fetchAddressSuggestionByPerson} from './../api.js';
|
import { householdMove, fetchHouseholdSuggestionByAccompanyingPeriod, fetchAddressSuggestionByPerson} from './../api.js';
|
||||||
|
import { fetchHouseholdByAddressReference } from 'ChillPersonAssets/lib/household.js';
|
||||||
import { datetimeToISO } from 'ChillMainAssets/chill/js/date.js';
|
import { datetimeToISO } from 'ChillMainAssets/chill/js/date.js';
|
||||||
|
|
||||||
const debug = process.env.NODE_ENV !== 'production';
|
const debug = process.env.NODE_ENV !== 'production';
|
||||||
@ -42,7 +43,16 @@ const store = createStore({
|
|||||||
allowHouseholdSearch: window.household_members_editor_data.allowHouseholdSearch,
|
allowHouseholdSearch: window.household_members_editor_data.allowHouseholdSearch,
|
||||||
allowLeaveWithoutHousehold: window.household_members_editor_data.allowLeaveWithoutHousehold,
|
allowLeaveWithoutHousehold: window.household_members_editor_data.allowLeaveWithoutHousehold,
|
||||||
forceLeaveWithoutHousehold: false,
|
forceLeaveWithoutHousehold: false,
|
||||||
householdSuggestionByAccompanyingPeriod: [],
|
/**
|
||||||
|
* If true, the user explicitly said that no address is possible
|
||||||
|
*/
|
||||||
|
forceHouseholdNoAddress: false,
|
||||||
|
/**
|
||||||
|
* Household suggestions
|
||||||
|
*
|
||||||
|
* (this is not restricted to "suggestion by accompanying periods")
|
||||||
|
*/
|
||||||
|
householdSuggestionByAccompanyingPeriod: [], // TODO rename into householdsSuggestion
|
||||||
showHouseholdSuggestion: window.household_members_editor_expand_suggestions === 1,
|
showHouseholdSuggestion: window.household_members_editor_expand_suggestions === 1,
|
||||||
addressesSuggestion: [],
|
addressesSuggestion: [],
|
||||||
showAddressSuggestion: true,
|
showAddressSuggestion: true,
|
||||||
@ -74,10 +84,12 @@ const store = createStore({
|
|||||||
isModeLeave(state) {
|
isModeLeave(state) {
|
||||||
return state.mode === "leave";
|
return state.mode === "leave";
|
||||||
},
|
},
|
||||||
|
isHouseholdForceNoAddress(state) {
|
||||||
|
return state.forceHouseholdNoAddress;
|
||||||
|
},
|
||||||
getSuggestions(state) {
|
getSuggestions(state) {
|
||||||
let suggestions = [];
|
let suggestions = [];
|
||||||
state.householdSuggestionByAccompanyingPeriod.forEach(h => {
|
state.householdSuggestionByAccompanyingPeriod.forEach(h => {
|
||||||
console.log(h);
|
|
||||||
suggestions.push({household: h});
|
suggestions.push({household: h});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -85,15 +97,12 @@ const store = createStore({
|
|||||||
},
|
},
|
||||||
isHouseholdNew(state) {
|
isHouseholdNew(state) {
|
||||||
return state.mode === "new";
|
return state.mode === "new";
|
||||||
/*
|
|
||||||
if (state.household === null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return !Number.isInteger(state.household.id);
|
|
||||||
|
|
||||||
*/
|
|
||||||
},
|
},
|
||||||
getAddressContext(state, getters) {
|
getAddressContext(state, getters) {
|
||||||
|
if (state.household === null) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
if (!getters.hasHouseholdAddress) {
|
if (!getters.hasHouseholdAddress) {
|
||||||
return {
|
return {
|
||||||
edit: false,
|
edit: false,
|
||||||
@ -198,6 +207,40 @@ const store = createStore({
|
|||||||
needsPositionning(state) {
|
needsPositionning(state) {
|
||||||
return state.forceLeaveWithoutHousehold === false;
|
return state.forceLeaveWithoutHousehold === false;
|
||||||
},
|
},
|
||||||
|
fakeHouseholdWithConcerned(state, getters) {
|
||||||
|
if (null === state.household) {
|
||||||
|
throw Error('cannot create fake household without household');
|
||||||
|
}
|
||||||
|
let h = {
|
||||||
|
type: 'household',
|
||||||
|
members: state.household.members,
|
||||||
|
current_address: state.household.current_address,
|
||||||
|
current_members_id: state.household.current_members_id,
|
||||||
|
new_members: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!getters.isHouseholdNew){
|
||||||
|
h.id = state.household.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.concerned.forEach((c, index) => {
|
||||||
|
let m = {
|
||||||
|
id: index * -1,
|
||||||
|
person: c.person,
|
||||||
|
holder: c.holder,
|
||||||
|
position: c.position,
|
||||||
|
};
|
||||||
|
if (c.position === null) {
|
||||||
|
m.position = {
|
||||||
|
ordering: 999999
|
||||||
|
}
|
||||||
|
}
|
||||||
|
h.new_members.push(m);
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log('fake household', h);
|
||||||
|
return h;
|
||||||
|
},
|
||||||
buildPayload: (state, getters) => {
|
buildPayload: (state, getters) => {
|
||||||
let
|
let
|
||||||
conc,
|
conc,
|
||||||
@ -272,6 +315,10 @@ const store = createStore({
|
|||||||
position = state.positions.find(pos => pos.id === position_id),
|
position = state.positions.find(pos => pos.id === position_id),
|
||||||
conc = state.concerned.find(c => c.person.id === person_id);
|
conc = state.concerned.find(c => c.person.id === person_id);
|
||||||
conc.position = position;
|
conc.position = position;
|
||||||
|
// reset position if changed:
|
||||||
|
if (!position.allowHolder && conc.holder) {
|
||||||
|
conc.holder = false;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
setComment(state, {conc, comment}) {
|
setComment(state, {conc, comment}) {
|
||||||
conc.comment = comment;
|
conc.comment = comment;
|
||||||
@ -283,9 +330,9 @@ const store = createStore({
|
|||||||
conc.holder = false;
|
conc.holder = false;
|
||||||
conc.position = null;
|
conc.position = null;
|
||||||
},
|
},
|
||||||
removeConcerned(state, conc) {
|
removePerson(state, person) {
|
||||||
state.concerned = state.concerned.filter(c =>
|
state.concerned = state.concerned.filter(c =>
|
||||||
c.person.id !== conc.person.id
|
c.person.id !== person.id
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
createHousehold(state) {
|
createHousehold(state) {
|
||||||
@ -310,6 +357,7 @@ const store = createStore({
|
|||||||
}
|
}
|
||||||
|
|
||||||
state.household.current_address = address;
|
state.household.current_address = address;
|
||||||
|
state.forceHouseholdNoAddress = false;
|
||||||
},
|
},
|
||||||
removeHouseholdAddress(state, address) {
|
removeHouseholdAddress(state, address) {
|
||||||
if (null === state.household) {
|
if (null === state.household) {
|
||||||
@ -319,6 +367,9 @@ const store = createStore({
|
|||||||
|
|
||||||
state.household.current_address = null;
|
state.household.current_address = null;
|
||||||
},
|
},
|
||||||
|
markHouseholdNoAddress(state) {
|
||||||
|
state.forceHouseholdNoAddress = true;
|
||||||
|
},
|
||||||
forceLeaveWithoutHousehold(state) {
|
forceLeaveWithoutHousehold(state) {
|
||||||
state.household = null;
|
state.household = null;
|
||||||
state.mode = "leave";
|
state.mode = "leave";
|
||||||
@ -329,7 +380,7 @@ const store = createStore({
|
|||||||
state.mode = "existing";
|
state.mode = "existing";
|
||||||
state.forceLeaveWithoutHousehold = false;
|
state.forceLeaveWithoutHousehold = false;
|
||||||
},
|
},
|
||||||
setHouseholdSuggestionByAccompanyingPeriod(state, households) {
|
addHouseholdSuggestionByAccompanyingPeriod(state, households) {
|
||||||
let existingIds = state.householdSuggestionByAccompanyingPeriod
|
let existingIds = state.householdSuggestionByAccompanyingPeriod
|
||||||
.map(h => h.id);
|
.map(h => h.id);
|
||||||
for (let i in households) {
|
for (let i in households) {
|
||||||
@ -384,8 +435,8 @@ const store = createStore({
|
|||||||
commit('removePosition', conc);
|
commit('removePosition', conc);
|
||||||
dispatch('computeWarnings');
|
dispatch('computeWarnings');
|
||||||
},
|
},
|
||||||
removeConcerned({ commit, dispatch }, conc) {
|
removePerson({ commit, dispatch }, person) {
|
||||||
commit('removeConcerned', conc);
|
commit('removePerson', person);
|
||||||
dispatch('computeWarnings');
|
dispatch('computeWarnings');
|
||||||
dispatch('fetchAddressSuggestions');
|
dispatch('fetchAddressSuggestions');
|
||||||
},
|
},
|
||||||
@ -418,20 +469,33 @@ const store = createStore({
|
|||||||
fetchHouseholdSuggestionForConcerned({ commit, state }, person) {
|
fetchHouseholdSuggestionForConcerned({ commit, state }, person) {
|
||||||
fetchHouseholdSuggestionByAccompanyingPeriod(person.id)
|
fetchHouseholdSuggestionByAccompanyingPeriod(person.id)
|
||||||
.then(households => {
|
.then(households => {
|
||||||
commit('setHouseholdSuggestionByAccompanyingPeriod', households);
|
commit('addHouseholdSuggestionByAccompanyingPeriod', households);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
fetchAddressSuggestions({ commit, state }) {
|
fetchAddressSuggestions({ commit, state, dispatch }) {
|
||||||
for (let i in state.concerned) {
|
for (let i in state.concerned) {
|
||||||
fetchAddressSuggestionByPerson(state.concerned[i].person.id)
|
fetchAddressSuggestionByPerson(state.concerned[i].person.id)
|
||||||
.then(addresses => {
|
.then(addresses => {
|
||||||
commit('addAddressesSuggestion', addresses);
|
commit('addAddressesSuggestion', addresses);
|
||||||
|
dispatch('fetchHouseholdSuggestionByAddresses', addresses);
|
||||||
})
|
})
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async fetchHouseholdSuggestionByAddresses({commit}, addresses) {
|
||||||
|
console.log('fetchHouseholdSuggestionByAddresses', addresses);
|
||||||
|
// foreach address, find household suggestions
|
||||||
|
addresses.forEach(async a => {
|
||||||
|
if (a.addressReference !== null) {
|
||||||
|
let households = await fetchHouseholdByAddressReference(a.addressReference);
|
||||||
|
commit('addHouseholdSuggestionByAccompanyingPeriod', households);
|
||||||
|
} else {
|
||||||
|
console.log('not an adresse reference')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
computeWarnings({ commit, state, getters }) {
|
computeWarnings({ commit, state, getters }) {
|
||||||
let warnings = [],
|
let warnings = [],
|
||||||
payload;
|
payload;
|
||||||
|
@ -19,15 +19,18 @@
|
|||||||
|
|
||||||
<!-- member part -->
|
<!-- member part -->
|
||||||
<li v-if="hasCurrentMembers" class="members" :title="$t('current_members')">
|
<li v-if="hasCurrentMembers" class="members" :title="$t('current_members')">
|
||||||
<template v-for="m in currentMembers()" :key="m.id">
|
<span v-for="m in currentMembers()" :key="m.id" class="m" :class="{ is_new: m.is_new === true}">
|
||||||
<person-render-box render="badge"
|
<person-render-box render="badge"
|
||||||
:person="m.person"
|
:person="m.person"
|
||||||
:options="{
|
:options="{
|
||||||
isHolder: m.holder,
|
isHolder: m.holder,
|
||||||
addLink: true
|
addLink: true
|
||||||
}">
|
}">
|
||||||
</person-render-box>
|
<template v-slot:post-badge v-if="m.is_new === true">
|
||||||
|
<span class="post-badge is_new"><i class="fa fa-sign-in"></i></span>
|
||||||
</template>
|
</template>
|
||||||
|
</person-render-box>
|
||||||
|
</span>
|
||||||
</li>
|
</li>
|
||||||
<li v-else class="members" :title="$t('current_members')">
|
<li v-else class="members" :title="$t('current_members')">
|
||||||
<p class="chill-no-data-statement">{{ $t('no_members_yet') }}</p>
|
<p class="chill-no-data-statement">{{ $t('no_members_yet') }}</p>
|
||||||
@ -82,7 +85,7 @@ export default {
|
|||||||
return this.household.current_members_id.length > 0;
|
return this.household.current_members_id.length > 0;
|
||||||
},
|
},
|
||||||
currentMembers() {
|
currentMembers() {
|
||||||
return this.household.members.filter(m => this.household.current_members_id.includes(m.id))
|
let members = this.household.members.filter(m => this.household.current_members_id.includes(m.id))
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
if (a.position.ordering < b.position.ordering) {
|
if (a.position.ordering < b.position.ordering) {
|
||||||
return -1;
|
return -1;
|
||||||
@ -98,6 +101,17 @@ export default {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (this.household.new_members !== undefined) {
|
||||||
|
this.household.new_members.map(m => {
|
||||||
|
m.is_new = true;
|
||||||
|
return m;
|
||||||
|
}).forEach(m => {
|
||||||
|
members.push(m);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return members;
|
||||||
},
|
},
|
||||||
currentMembersLength() {
|
currentMembersLength() {
|
||||||
return this.household.current_members_id.length;
|
return this.household.current_members_id.length;
|
||||||
@ -121,6 +135,13 @@ section.chill-entity {
|
|||||||
content: '';
|
content: '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.members {
|
||||||
|
.post-badge.is_new {
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
color: var(--bs-chill-green);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -126,6 +126,7 @@
|
|||||||
</span>
|
</span>
|
||||||
{{ person.text }}
|
{{ person.text }}
|
||||||
</span>
|
</span>
|
||||||
|
<slot name="post-badge"></slot>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
@ -94,7 +94,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<ul class="record_actions">
|
<ul class="record_actions">
|
||||||
<li>
|
<li>
|
||||||
<button type="submit" class="btn btn-save">
|
<button type="submit" class="btn btn-save" id="form_household_comment_confirm">
|
||||||
{{ 'Save'|trans }}
|
{{ 'Save'|trans }}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\Security\Authorization;
|
||||||
|
|
||||||
|
class HouseholdVoter
|
||||||
|
{
|
||||||
|
const SHOW = PersonVoter::SEE;
|
||||||
|
}
|
@ -2,9 +2,14 @@
|
|||||||
|
|
||||||
namespace Chill\PersonBundle\Tests\Controller;
|
namespace Chill\PersonBundle\Tests\Controller;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Address;
|
||||||
|
use Chill\MainBundle\Entity\AddressReference;
|
||||||
|
use Chill\MainBundle\Entity\Center;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
use Chill\MainBundle\Test\PrepareClientTrait;
|
use Chill\MainBundle\Test\PrepareClientTrait;
|
||||||
use Chill\PersonBundle\Entity\Household\Household;
|
use Chill\PersonBundle\Entity\Household\Household;
|
||||||
|
use Chill\PersonBundle\Entity\Household\HouseholdMember;
|
||||||
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||||
@ -15,6 +20,8 @@ class HouseholdApiControllerTest extends WebTestCase
|
|||||||
|
|
||||||
use PrepareClientTrait;
|
use PrepareClientTrait;
|
||||||
|
|
||||||
|
private array $toDelete = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider generatePersonId
|
* @dataProvider generatePersonId
|
||||||
*/
|
*/
|
||||||
@ -45,6 +52,77 @@ class HouseholdApiControllerTest extends WebTestCase
|
|||||||
$this->assertResponseIsSuccessful();
|
$this->assertResponseIsSuccessful();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider generateHouseholdAssociatedWithAddressReference
|
||||||
|
*/
|
||||||
|
public function testFindHouseholdByAddressReference(int $addressReferenceId, int $expectedHouseholdId)
|
||||||
|
{
|
||||||
|
$client = $this->getClientAuthenticated();
|
||||||
|
|
||||||
|
$client->request(
|
||||||
|
Request::METHOD_GET,
|
||||||
|
"/api/1.0/person/household/by-address-reference/$addressReferenceId.json"
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertResponseIsSuccessful();
|
||||||
|
$data = json_decode($client->getResponse()->getContent(), true);
|
||||||
|
$this->assertArrayHasKey('count', $data);
|
||||||
|
$this->assertArrayHasKey('results', $data);
|
||||||
|
|
||||||
|
$householdIds = \array_map(function($r) {
|
||||||
|
return $r['id'];
|
||||||
|
}, $data['results']);
|
||||||
|
|
||||||
|
$this->assertContains($expectedHouseholdId, $householdIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generateHouseholdAssociatedWithAddressReference()
|
||||||
|
{
|
||||||
|
self::bootKernel();
|
||||||
|
$em = self::$container->get(EntityManagerInterface::class);
|
||||||
|
$centerA = $em->getRepository(Center::class)->findOneBy(['name' => 'Center A']);
|
||||||
|
$nbReference = $em->createQueryBuilder()->select('count(ar)')->from(AddressReference::class, 'ar')
|
||||||
|
->getQuery()->getSingleScalarResult();
|
||||||
|
$reference = $em->createQueryBuilder()->select('ar')->from(AddressReference::class, 'ar')
|
||||||
|
->setFirstResult(\random_int(0, $nbReference))
|
||||||
|
->setMaxResults(1)
|
||||||
|
->getQuery()->getSingleResult();
|
||||||
|
$p = new Person();
|
||||||
|
$p->setFirstname('test')->setLastName('test lastname')
|
||||||
|
->setGender(Person::BOTH_GENDER)
|
||||||
|
->setCenter($centerA)
|
||||||
|
;
|
||||||
|
$em->persist($p);
|
||||||
|
$h = new Household();
|
||||||
|
$h->addMember($m = (new HouseholdMember())->setPerson($p));
|
||||||
|
$h->addAddress(Address::createFromAddressReference($reference)->setValidFrom(new \DateTime('today')));
|
||||||
|
$em->persist($m);
|
||||||
|
$em->persist($h);
|
||||||
|
|
||||||
|
$em->flush();
|
||||||
|
|
||||||
|
$this->toDelete = $this->toDelete + [
|
||||||
|
[HouseholdMember::class, $m->getId()],
|
||||||
|
[User::class, $p->getId()],
|
||||||
|
[Household::class, $h->getId()]
|
||||||
|
];
|
||||||
|
|
||||||
|
yield [$reference->getId(), $h->getId()];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function tearDown()
|
||||||
|
{
|
||||||
|
self::bootKernel();
|
||||||
|
$em = self::$container->get(EntityManagerInterface::class);
|
||||||
|
|
||||||
|
foreach ($this->toDelete as list($class, $id)) {
|
||||||
|
$obj = $em->getRepository($class)->find($id);
|
||||||
|
$em->remove($obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
$em->flush();
|
||||||
|
}
|
||||||
|
|
||||||
public function generatePersonId()
|
public function generatePersonId()
|
||||||
{
|
{
|
||||||
self::bootKernel();
|
self::bootKernel();
|
||||||
|
@ -49,7 +49,7 @@ class HouseholdControllerTest extends WebTestCase
|
|||||||
|
|
||||||
$this->assertResponseIsSuccessful();
|
$this->assertResponseIsSuccessful();
|
||||||
|
|
||||||
$form = $crawler->selectButton('Enregistrer')
|
$form = $crawler->filter('#form_household_comment_confirm')
|
||||||
->form();
|
->form();
|
||||||
|
|
||||||
$form['household[commentMembers][comment]'] = "This is a text **generated** by automatic tests";
|
$form['household[commentMembers][comment]'] = "This is a text **generated** by automatic tests";
|
||||||
|
@ -1127,6 +1127,32 @@ paths:
|
|||||||
401:
|
401:
|
||||||
description: "Unauthorized"
|
description: "Unauthorized"
|
||||||
|
|
||||||
|
/1.0/person/household/by-address-reference/{address_id}.json:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- household
|
||||||
|
summary: Return a list of household which are sharing the same address reference
|
||||||
|
parameters:
|
||||||
|
- name: address_id
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: the address reference id
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: integer
|
||||||
|
minimum: 1
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: "ok"
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Household"
|
||||||
|
404:
|
||||||
|
description: "not found"
|
||||||
|
401:
|
||||||
|
description: "Unauthorized"
|
||||||
|
|
||||||
/1.0/person/household/suggest/by-person/{person_id}/through-accompanying-period-participation.json:
|
/1.0/person/household/suggest/by-person/{person_id}/through-accompanying-period-participation.json:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
|
@ -10,3 +10,5 @@ services:
|
|||||||
Chill\PersonBundle\Repository\PersonACLAwareRepositoryInterface: '@Chill\PersonBundle\Repository\PersonACLAwareRepository'
|
Chill\PersonBundle\Repository\PersonACLAwareRepositoryInterface: '@Chill\PersonBundle\Repository\PersonACLAwareRepository'
|
||||||
|
|
||||||
Chill\PersonBundle\Repository\AccompanyingPeriodACLAwareRepositoryInterface: '@Chill\PersonBundle\Repository\AccompanyingPeriodACLAwareRepository'
|
Chill\PersonBundle\Repository\AccompanyingPeriodACLAwareRepositoryInterface: '@Chill\PersonBundle\Repository\AccompanyingPeriodACLAwareRepository'
|
||||||
|
|
||||||
|
Chill\PersonBundle\Repository\Household\HouseholdACLAwareRepositoryInterface: '@Chill\PersonBundle\Repository\Household\HouseholdACLAwareRepository'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user