Merge branch 'master' into HEAD

This commit is contained in:
2021-10-18 13:49:00 +02:00
86 changed files with 2566 additions and 789 deletions

View File

@@ -17,20 +17,21 @@ class LoadCivility extends Fixture implements FixtureGroupInterface
public function load(ObjectManager $manager): void
{
$civilities = [
['name' => ['fr' => "Monsieur" ]],
['name' => ['fr' => "Madame" ]],
['name' => ['fr' => "Docteur" ]],
['name' => ['fr' => "Professeur" ]],
['name' => ['fr' => "Madame la Directrice" ]],
['name' => ['fr' => "Monsieur le Directeur" ]],
['name' => ['fr' => "Monsieur" ], 'abbrev' => ['fr' => 'M.']],
['name' => ['fr' => "Madame" ], 'abbrev' => ['fr' => 'Mme']],
['name' => ['fr' => "Docteur" ], 'abbrev' => ['fr' => 'Dr']],
['name' => ['fr' => "Professeur" ], 'abbrev' => ['fr' => 'Pr']],
['name' => ['fr' => "Madame la Directrice" ], 'abbrev' => ['fr' => 'Mme']],
['name' => ['fr' => "Monsieur le Directeur" ], 'abbrev' => ['fr' => 'M.']],
['name' => ['fr' => "Madame la Maire" ]],
['name' => ['fr' => "Monsieur le Maire" ]],
['name' => ['fr' => "Maître" ]],
['name' => ['fr' => "Maître" ], 'abbrev' => ['fr' => 'Me']],
];
foreach ( $civilities as $val) {
$civility = (new Civility())
->setName($val['name'])
->setAbbreviation($val['abbrev'] ?? [])
->setActive(true);
$manager->persist($civility);
}

View File

@@ -23,7 +23,7 @@ class Address
* @ORM\Id
* @ORM\Column(name="id", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
* @groups({"write"})
* @Groups({"write"})
*/
private $id;
@@ -31,7 +31,7 @@ class Address
* @var string
*
* @ORM\Column(type="string", length=255)
* @groups({"write"})
* @Groups({"write"})
*/
private $street = '';
@@ -39,7 +39,7 @@ class Address
* @var string
*
* @ORM\Column(type="string", length=255)
* @groups({"write"})
* @Groups({"write"})
*/
private $streetNumber = '';
@@ -47,7 +47,7 @@ class Address
* @var PostalCode
*
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\PostalCode")
* @groups({"write"})
* @Groups({"write"})
*/
private $postcode;
@@ -55,7 +55,7 @@ class Address
* @var string|null
*
* @ORM\Column(type="string", length=16, nullable=true)
* @groups({"write"})
* @Groups({"write"})
*/
private $floor;
@@ -63,7 +63,7 @@ class Address
* @var string|null
*
* @ORM\Column(type="string", length=16, nullable=true)
* @groups({"write"})
* @Groups({"write"})
*/
private $corridor;
@@ -71,7 +71,7 @@ class Address
* @var string|null
*
* @ORM\Column(type="string", length=16, nullable=true)
* @groups({"write"})
* @Groups({"write"})
*/
private $steps;
@@ -79,7 +79,7 @@ class Address
* @var string|null
*
* @ORM\Column(type="string", length=255, nullable=true)
* @groups({"write"})
* @Groups({"write"})
*/
private $buildingName;
@@ -87,7 +87,7 @@ class Address
* @var string|null
*
* @ORM\Column(type="string", length=16, nullable=true)
* @groups({"write"})
* @Groups({"write"})
*/
private $flat;
@@ -95,7 +95,7 @@ class Address
* @var string|null
*
* @ORM\Column(type="string", length=255, nullable=true)
* @groups({"write"})
* @Groups({"write"})
*/
private $distribution;
@@ -103,7 +103,7 @@ class Address
* @var string|null
*
* @ORM\Column(type="string", length=255, nullable=true)
* @groups({"write"})
* @Groups({"write"})
*/
private $extra;
@@ -114,7 +114,7 @@ class Address
* @var \DateTime
*
* @ORM\Column(type="date")
* @groups({"write"})
* @Groups({"write"})
*/
private \DateTime $validFrom;
@@ -125,13 +125,13 @@ class Address
* @var \DateTime|null
*
* @ORM\Column(type="date", nullable=true)
* @groups({"write"})
* @Groups({"write"})
*/
private ?\DateTime $validTo = null;
/**
* True if the address is a "no address", aka homeless person, ...
* @groups({"write"})
* @Groups({"write"})
* @ORM\Column(type="boolean")
*
* @var bool
@@ -144,7 +144,7 @@ class Address
* @var Point|null
*
* @ORM\Column(type="point", nullable=true)
* @groups({"write"})
* @Groups({"write"})
*/
private $point;
@@ -154,7 +154,7 @@ class Address
* @var ThirdParty|null
*
* @ORM\ManyToOne(targetEntity="Chill\ThirdPartyBundle\Entity\ThirdParty")
* @groups({"write"})
* @Groups({"write"})
* @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
*/
private $linkedToThirdParty;
@@ -166,6 +166,12 @@ class Address
*/
private $customs = [];
/**
* @ORM\ManyToOne(targetEntity=AddressReference::class)
* @Groups({"write"})
*/
private ?AddressReference $addressReference = null;
public function __construct()
{
$this->validFrom = new \DateTime();
@@ -376,6 +382,7 @@ class Address
public static function createFromAddress(Address $original) : Address
{
return (new Address())
->setAddressReference($original->getAddressReference())
->setBuildingName($original->getBuildingName())
->setCorridor($original->getCorridor())
->setCustoms($original->getCustoms())
@@ -402,6 +409,7 @@ class Address
->setPostcode($original->getPostcode())
->setStreet($original->getStreet())
->setStreetNumber($original->getStreetNumber())
->setAddressReference($original)
;
}
@@ -549,5 +557,22 @@ class Address
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;
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace Chill\MainBundle\Form\Type\DataTransformer;
use Chill\MainBundle\Repository\AddressRepository;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
final class AddressToIdDataTransformer implements DataTransformerInterface
{
private AddressRepository $addressRepository;
public function __construct(AddressRepository $addressRepository)
{
$this->addressRepository = $addressRepository;
}
public function reverseTransform($value)
{
if (NULL === $value || '' === $value) {
return null;
}
$address = $this->addressRepository->find($value);
if (NULL === $address) {
$failure = new TransformationFailedException(sprintf("Address with id %s does not exists", $value));
$failure
->setInvalidMessage("The given {{ value }} is not a valid address id", [ '{{ value }}' => $value]);
throw $failure;
}
return $address;
}
public function transform($value)
{
if (NULL === $value) {
return '';
}
return $value->getId();
}
}

View File

@@ -32,7 +32,7 @@ final class FilterOrderType extends \Symfony\Component\Form\AbstractType
foreach ($this->requestStack->getCurrentRequest()->query->getIterator() as $key => $value) {
switch($key) {
case 'q':
continue;
break;
case 'page':
$builder->add($key, HiddenType::class, [
'data' => 1

View File

@@ -0,0 +1,79 @@
<?php
namespace Chill\MainBundle\Form\Type;
use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Form\Type\DataTransformer\AddressToIdDataTransformer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
* Form type for picking an address.
*
* In the UI, this resolve to a vuejs component which will insert the created address id into the
* hidden's value. It will also allow to edit existing addresses without changing the id.
*
* In every page where this component is shown, you must include the required module:
*
* ```twig
* {% block js %}
* {{ encore_entry_script_tags('mod_input_address') }}
* {% endblock %}
*
* {% block css %}
* {{ encore_entry_link_tags('mod_input_address') }}
* {% endblock %}
* ```
*/
final class PickAddressType extends AbstractType
{
private AddressToIdDataTransformer $addressToIdDataTransformer;
private TranslatorInterface $translator;
public function __construct(
AddressToIdDataTransformer $addressToIdDataTransformer,
TranslatorInterface $translator
) {
$this->addressToIdDataTransformer = $addressToIdDataTransformer;
$this->translator = $translator;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addModelTransformer($this->addressToIdDataTransformer);
}
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars['uniqid'] = $view->vars['attr']['data-input-address'] =\uniqid('input_address_');
$view->vars['attr']['data-use-valid-from'] = (int) $options['use_valid_from'];
$view->vars['attr']['data-use-valid-to'] = (int) $options['use_valid_to'];
$view->vars['attr']['data-button-text-create'] = $this->translator->trans($options['button_text_create']);
$view->vars['attr']['data-button-text-update'] = $this->translator->trans($options['button_text_update']);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'class' => Address::class,
'use_valid_to' => false,
'use_valid_from' => false,
'button_text_create' => 'Create an address',
'button_text_update' => 'Update address',
// reset default from hidden type
'required' => true,
'error_bubbling' => false,
]);
}
public function getParent()
{
return HiddenType::class;
}
}

View File

@@ -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
};

View File

@@ -1,15 +1,7 @@
import { fetchResults } from 'ChillMainAssets/lib/api/download.js';
const fetchScopes = () => {
return window.fetch('/api/1.0/main/scope.json').then(response => {
if (response.ok) {
return response.json();
}
}).then(data => {
//console.log(data);
return new Promise((resolve, reject) => {
//console.log(data);
resolve(data.results);
});
});
return fetchResults('/api/1.0/main/scope.json');
};
export {

View File

@@ -17,7 +17,8 @@ export default {
components: {
AddAddress
},
props: ['addAddress'],
props: ['addAddress', 'callback'],
emits: ['addressEdited', 'addressCreated'],
computed: {
context() {
return this.addAddress.context;
@@ -46,6 +47,7 @@ export default {
// address is already linked, just finish !
this.$refs.addAddress.afterLastPaneAction({});
this.$emit('addressEdited', payload);
// New created address
} else {
@@ -57,6 +59,8 @@ export default {
* Post new created address to targetEntity
*/
postAddressTo(payload) {
this.$emit('addressCreated', payload);
console.log('postAddress', payload.addressId, 'To', payload.target, payload.targetId);
switch (payload.target) {
case 'household':

View File

@@ -267,6 +267,9 @@ export default {
title: { create: 'add_an_address_title', edit: 'edit_address' },
openPanesInModal: true,
stickyActions: false,
// show a message when no address.
// if set to undefined, the value will be equivalent to false if stickyActions is false, true otherwise.
showMessageWhenNoAddress: undefined,
useDate: {
validFrom: false,
validTo: false
@@ -586,6 +589,14 @@ export default {
'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) {
console.log('add validFrom in fetch body', this.entity.selected.valid.from);
newAddress = Object.assign(newAddress, {
@@ -606,7 +617,7 @@ export default {
let newPostcode = this.entity.selected.postcode;
newPostcode = Object.assign(newPostcode, {
'country': {'id': this.entity.selected.country.id },
});
});//TODO why not assign postcodeBody here = Object.assign(postcodeBody, {'origin': 3}); ?
console.log('writeNew postcode is true! newPostcode: ', newPostcode);
newAddress = Object.assign(newAddress, {
'newPostcode': newPostcode
@@ -638,9 +649,7 @@ export default {
if ('newPostcode' in payload) {
let postcodeBody = payload.newPostcode;
if (this.context.target.name === 'person') { // !!! maintain here ?
postcodeBody = Object.assign(postcodeBody, {'origin': 3});
}
postcodeBody = Object.assign(postcodeBody, {'origin': 3});
console.log('juste before post new postcode', postcodeBody);
return postPostalCode(postcodeBody)
.then(postalCode => {
@@ -730,6 +739,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
*/

View File

@@ -95,6 +95,9 @@ export default {
},
selectAddress(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.streetNumber = value.streetNumber;
this.entity.selected.writeNew.address = false;

View File

@@ -50,7 +50,7 @@ import VueMultiselect from 'vue-multiselect';
export default {
name: 'CitySelection',
components: { VueMultiselect },
props: ['entity', 'focusOnAddress'],
props: ['entity', 'focusOnAddress', 'updateMapCenter'],
emits: ['getReferenceAddresses'],
data() {
return {
@@ -95,6 +95,7 @@ export default {
return (value.code && value.name) ? `${value.code}-${value.name}` : '';
},
selectCity(value) {
console.log(value)
this.entity.selected.city = value;
this.entity.selected.postcode.name = value.name;
this.entity.selected.postcode.code = value.code;
@@ -102,6 +103,7 @@ export default {
console.log('writeNew.postcode false, in selectCity');
this.$emit('getReferenceAddresses', value);
this.focusOnAddress();
this.updateMapCenter(value.center);
},
listenInputSearch(query) {
//console.log('listenInputSearch', query, this.isCitySelectorOpen);

View File

@@ -31,6 +31,7 @@
<city-selection
v-bind:entity="entity"
v-bind:focusOnAddress="focusOnAddress"
v-bind:updateMapCenter="updateMapCenter"
@getReferenceAddresses="$emit('getReferenceAddresses', selected.city)">
</city-selection>
@@ -135,7 +136,7 @@ export default {
}
},
updateMapCenter(point) {
//console.log('point', point);
console.log('point', point);
this.addressMap.center[0] = point.coordinates[1]; // TODO use reverse()
this.addressMap.center[1] = point.coordinates[0];
this.$refs.addressMap.update(); // cast child methods

View File

@@ -15,7 +15,7 @@
<span v-if="forceRedirect">{{ $t('wait_redirection') }}</span>
</div>
<div v-if="noAddressWithStickyActions" class="mt-5">
<div v-if="showMessageWhenNoAddress" class="mt-5">
<p class="chill-no-data-statement">
{{ $t('not_yet_address') }}
</p>
@@ -50,8 +50,8 @@ export default {
},
props: [
'context',
'options',
'defaultz',
'options',
'flag',
'entity',
'errorMsg',
@@ -91,7 +91,11 @@ export default {
forceRedirect() {
return (!(this.context.backUrl === null || typeof this.context.backUrl === 'undefined'));
},
noAddressWithStickyActions() {
showMessageWhenNoAddress() {
let showMessageWhenNoAddress = this.options.showMessageWhenNoAddress === undefined ? this.defaultz.showMessageWhenNoAddress : this.options.showMessageWhenNoAddress;
if (showMessageWhenNoAddress === true || showMessageWhenNoAddress === false) {
return !this.context.edit && !this.address.id && showMessageWhenNoAddress;
}
return !this.context.edit && !this.address.id && this.options.stickyActions;
}
}

View File

@@ -0,0 +1,86 @@
import {createApp} from 'vue';
import {_createI18n} from 'ChillMainAssets/vuejs/_js/i18n';
import {addressMessages} from './i18n';
import App from './App.vue';
const i18n = _createI18n(addressMessages);
let inputs = document.querySelectorAll('input[type="hidden"][data-input-address]');
const isNumeric = function(v) { return !isNaN(v); };
inputs.forEach(el => {
let
addressId = el.value,
uniqid = el.dataset.inputAddress,
container = document.querySelector('div[data-input-address-container="' + uniqid + '"]'),
isEdit = addressId !== '',
addressIdInt = addressId !== '' ? parseInt(addressId) : null
;
if (container === null) {
throw Error("no container");
}
console.log('useValidFrom', el.dataset.useValidFrom === '1');
const app = createApp({
template: `<app v-bind:addAddress="this.addAddress" @address-created="associateToInput"></app>`,
data() {
return {
addAddress: {
context: {
// for legacy ? can be remove ?
target: {
name: 'input-address',
id: addressIdInt,
},
edit: isEdit,
addressId: addressIdInt,
},
options: {
/// Options override default.
/// null value take default component value defined in AddAddress data()
button: {
text: {
create: el.dataset.buttonTextCreate || null,
edit: el.dataset.buttonTextUpdate || null,
},
size: null,
displayText: true
},
/// Modal title text if create or edit address (trans chain, see i18n)
title: {
create: null,
edit: null,
},
/// Display panes in Modal for step123
openPanesInModal: true,
/// Display actions buttons of panes in a sticky-form-button navbar
stickyActions: false,
showMessageWhenNoAddress: true,
/// Use Date fields
useDate: {
validFrom: el.dataset.useValidFrom === '1' || false, //boolean, default: false
validTo: el.dataset.useValidTo === '1' || false, //boolean, default: false
},
/// Don't display show renderbox Address: showPane display only a button
onlyButton: false,
}
}
}
},
methods: {
associateToInput(payload) {
el.value = payload.addressId;
}
}
})
.use(i18n)
.component('app', App)
.mount(container);
});

View File

@@ -166,6 +166,7 @@
<li class="entry" data-collection-is-persisted="1">
<div>
{{ form_widget(entry) }}
{{ form_errors(entry) }}
</div>
</li>
{% else %}

View File

@@ -27,7 +27,7 @@ class SearchUserApiProvider implements SearchApiInterface
->setSelectPertinence("GREATEST(SIMILARITY(LOWER(UNACCENT(?)), u.usernamecanonical),
SIMILARITY(LOWER(UNACCENT(?)), u.emailcanonical))", [ $pattern, $pattern ])
->setFromClause("users AS u")
->setWhereClause("SIMILARITY(LOWER(UNACCENT(?)), u.usernamecanonical) > 0.15
->setWhereClauses("SIMILARITY(LOWER(UNACCENT(?)), u.usernamecanonical) > 0.15
OR
SIMILARITY(LOWER(UNACCENT(?)), u.emailcanonical) > 0.15
", [ $pattern, $pattern ]);

View File

@@ -12,8 +12,8 @@ class SearchApiQuery
private array $pertinenceParams = [];
private ?string $fromClause = null;
private array $fromClauseParams = [];
private ?string $whereClause = null;
private array $whereClauseParams = [];
private array $whereClauses = [];
private array $whereClausesParams = [];
public function setSelectKey(string $selectKey, array $params = []): self
{
@@ -47,16 +47,39 @@ class SearchApiQuery
return $this;
}
public function setWhereClause(string $whereClause, array $params = []): self
/**
* Set the where clause and replace all existing ones.
*
*/
public function setWhereClauses(string $whereClause, array $params = []): self
{
$this->whereClause = $whereClause;
$this->whereClauseParams = $params;
$this->whereClauses = [$whereClause];
$this->whereClausesParams = [$params];
return $this;
}
/**
* Add a where clause.
*
* This will add to previous where clauses with and `AND` join
*
* @param string $whereClause
* @param array $params
* @return $this
*/
public function andWhereClause(string $whereClause, array $params = []): self
{
$this->whereClauses[] = $whereClause;
$this->whereClausesParams[] = $params;
return $this;
}
public function buildQuery(): string
{
$where = \implode(' AND ', $this->whereClauses);
return \strtr("SELECT
'{key}' AS key,
{metadata} AS metadata,
@@ -68,7 +91,7 @@ class SearchApiQuery
'{metadata}' => $this->jsonbMetadata,
'{pertinence}' => $this->pertinence,
'{from}' => $this->fromClause,
'{where}' => $this->whereClause,
'{where}' => $where,
]);
}
@@ -79,7 +102,7 @@ class SearchApiQuery
$this->jsonbMetadataParams,
$this->pertinenceParams,
$this->fromClauseParams,
$this->whereClauseParams,
\array_merge([], ...$this->whereClausesParams),
);
}
}

View File

@@ -3,6 +3,7 @@
namespace Chill\MainBundle\Serializer\Normalizer;
use Chill\MainBundle\Entity\Address;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
@@ -33,6 +34,9 @@ class AddressNormalizer implements NormalizerAwareInterface, NormalizerInterface
$data['extra'] = $address->getExtra();
$data['validFrom'] = $address->getValidFrom();
$data['validTo'] = $address->getValidTo();
$data['addressReference'] = $this->normalizer->normalize($address->getAddressReference(), $format, [
AbstractNormalizer::GROUPS => ['read']
]);
return $data;
}

View File

@@ -0,0 +1,40 @@
<?php
namespace Search;
use Chill\MainBundle\Search\SearchApiQuery;
use PHPUnit\Framework\TestCase;
class SearchApiQueryTest extends TestCase
{
public function testMultipleWhereClauses()
{
$q = new SearchApiQuery();
$q->setSelectJsonbMetadata('boum')
->setSelectKey('bim')
->setSelectPertinence('1')
->setFromClause('badaboum')
->andWhereClause('foo', [ 'alpha' ])
->andWhereClause('bar', [ 'beta' ])
;
$query = $q->buildQuery();
$this->assertStringContainsString('foo AND bar', $query);
$this->assertEquals(['alpha', 'beta'], $q->buildParameters());
}
public function testWithoutWhereClause()
{
$q = new SearchApiQuery();
$q->setSelectJsonbMetadata('boum')
->setSelectKey('bim')
->setSelectPertinence('1')
->setFromClause('badaboum')
;
$this->assertTrue(\is_string($q->buildQuery()));
$this->assertEquals([], $q->buildParameters());
}
}

View File

@@ -60,6 +60,7 @@ module.exports = function(encore, entries)
encore.addEntry('mod_ckeditor5', __dirname + '/Resources/public/module/ckeditor5/index.js');
encore.addEntry('mod_disablebuttons', __dirname + '/Resources/public/module/disable-buttons/index.js');
encore.addEntry('mod_input_address', __dirname + '/Resources/public/vuejs/Address/mod_input_address_index.js');
// Vue entrypoints
encore.addEntry('vue_address', __dirname + '/Resources/public/vuejs/Address/index.js');
encore.addEntry('vue_onthefly', __dirname + '/Resources/public/vuejs/OnTheFly/index.js');

View File

@@ -1,4 +1,5 @@
services:
chill.main.form.type.translatable.string:
class: Chill\MainBundle\Form\Type\TranslatableStringFormType
arguments:
@@ -128,3 +129,11 @@ services:
tags:
- { name: form.type }
Chill\MainBundle\Form\Type\PickAddressType:
autoconfigure: true
autowire: true
Chill\MainBundle\Form\DataTransform\AddressToIdDataTransformer:
autoconfigure: true
autowire: true

View File

@@ -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');
}
}

View File

@@ -84,6 +84,8 @@ address more:
extra: ""
distribution: cedex
Create a new address: Créer une nouvelle adresse
Create an address: Créer une adresse
Update address: Modifier l'adresse
#serach
Your search is empty. Please provide search terms.: La recherche est vide. Merci de fournir des termes de recherche.
@@ -127,7 +129,7 @@ New center: Nouveau centre
Center: Centre
#admin section for permissions group
Permissions group list: Liste des groupes de permissions
Permissions group list: Groupes de permissions
Create a new permissions group: Créer un nouveau groupe de permissions
Permission group "%name%": Groupe de permissions "%name%"
Grant those permissions: Attribue ces permissions
@@ -144,7 +146,6 @@ The role '%role%' has been removed: Le rôle "%role%" a été enlevé de ce grou
The role '%role%' on circle '%scope%' has been removed: Le rôle "%role%" sur le cercle "%scope%" a été enlevé de ce groupe de permission
#admin section for users
user list: Liste des utilisateurs
User edit: Modification d'un utilisateur
User'status: Statut de l'utilisateur
Disabled, the user is not allowed to login: Désactivé, l'utilisateur n'est pas autorisé à se connecter
@@ -167,8 +168,12 @@ Back to the user edition: Retour au formulaire d'édition
Password successfully updated!: Mot de passe mis à jour
Flags: Drapeaux
# admin section for users jobs
User jobs: Métiers
#admin section for circles (old: scopes)
List circles: Liste des cercles
List circles: Cercles
New circle: Nouveau cercle
Circle: Cercle
Circle edit: Modification du cercle
@@ -279,6 +284,17 @@ crud:
success: Les données ont été enregistrées
view:
link_duplicate: Dupliquer
admin_user:
index:
title: Utilisateurs
add_new: Créer
admin_user_job:
index:
title: Métiers
add_new: Créer
title_new: Nouveau métier
title_edit: Modifier un métier
No entities: Aucun élément
CHILL_FOO_SEE: Voir un élément