merge firstname branch

This commit is contained in:
Julie Lenaerts 2022-03-24 11:13:07 +01:00
commit 688914906d
20 changed files with 216 additions and 67 deletions

View File

@ -52,7 +52,11 @@ and this project adheres to
* [phonenumber] Remove placeholder in phonenumber field (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/496)
* [person_resource] separate create page created to avoid confusion (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/504)
* [contact] add contact button color changed plus the pipe at the side removed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/506)
<<<<<<< HEAD
* [thirdparty] For contacts show current civility/profession in edit form + fix saving of edited information (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/491)
=======
* [thirdparty] add firstname field to thirdparty 'child' or 'contact' types (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/508)
>>>>>>> issue508_thirdparty_firstname
* [household] create-edit household composition placed in separate page to avoid confusion (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/505)
* [blur] Improved positioning of toggle icon (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/486)
* [parcours] List of parcours for a specific user so they can be reassigned in case of absence (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/509)

View File

@ -232,7 +232,9 @@ export default {
} else {
type = this.$refs.castNew.radioType;
data = this.$refs.castNew.castDataByType();
console.log(data)
data.civility = {type: 'chill_main_civility', id: data.civility.id};
data.profession = {type: 'third_party_profession', id: data.profession.id};
// console.log('onthefly data', data);
}
} else {
throw 'error with object type';

View File

@ -167,6 +167,8 @@ export default {
})
}
else if (payload.type === 'thirdparty') {
// console.log('data', payload.data)
body.firstname = payload.data.firstname;
body.name = payload.data.name;
body.email = payload.data.email;
body.telephone = payload.data.telephone;

View File

@ -24,11 +24,11 @@
<div class="form-floating mb-3">
<input
class="form-control form-control-lg"
id="lastname"
v-model="lastName"
:placeholder="$t('person.lastname')"
@change="checkErrors"
class="form-control form-control-lg"
id="lastname"
v-model="lastName"
:placeholder="$t('person.lastname')"
@change="checkErrors"
/>
<label for="lastname">{{ $t('person.lastname') }}</label>
</div>
@ -43,11 +43,11 @@
<div class="form-floating mb-3">
<input
class="form-control form-control-lg"
id="firstname"
v-model="firstName"
:placeholder="$t('person.firstname')"
@change="checkErrors"
class="form-control form-control-lg"
id="firstname"
v-model="firstName"
:placeholder="$t('person.firstname')"
@change="checkErrors"
/>
<label for="firstname">{{ $t('person.firstname') }}</label>
</div>
@ -62,10 +62,10 @@
<div v-for="(a, i) in config.altNames" :key="a.key" class="form-floating mb-3">
<input
class="form-control form-control-lg"
:id="a.key"
:value="personAltNamesLabels[i]"
@input="onAltNameInput"
class="form-control form-control-lg"
:id="a.key"
:value="personAltNamesLabels[i]"
@input="onAltNameInput"
/>
<label :for="a.key">{{ a.labels.fr }}</label>
</div>
@ -125,9 +125,9 @@
</div>
<div class="alert alert-warning" v-if="errors.length">
<ul>
<li v-for="(e, i) in errors" :key="i">{{ e }}</li>
</ul>
<ul>
<li v-for="(e, i) in errors" :key="i">{{ e }}</li>
</ul>
</div>
</div>
@ -238,13 +238,13 @@ export default {
checkErrors(e) {
this.errors = [];
if (!this.person.lastName) {
this.errors.push("Le nom ne doit pas être vide.");
this.errors.push("Le nom ne doit pas être vide.");
}
if (!this.person.firstName) {
this.errors.push("Le prénom ne doit pas être vide.");
this.errors.push("Le prénom ne doit pas être vide.");
}
if (!this.person.gender) {
this.errors.push("Le genre doit être renseigné");
this.errors.push("Le genre doit être renseigné");
}
},
loadData() {

View File

@ -46,6 +46,7 @@ class ChillThirdPartyExtension extends Extension implements PrependExtensionInte
$loader->load('services/fixtures.yaml');
$loader->load('services/serializer.yaml');
$loader->load('services/repository.yaml');
$loader->load('services/doctrineEventListener.yaml');
}
public function prepend(ContainerBuilder $container)

View File

@ -197,6 +197,12 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
*/
private ?string $email = null;
/**
* @ORM\Column(name="firstname", type="string", length=255, nullable=true)
* @Groups({"read", "write", "docgen:read", "docgen:read:3party:parent"})
*/
private ?string $firstname = null;
/**
* @var int
* @ORM\Column(name="id", type="integer")
@ -454,12 +460,12 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
return $this->email;
}
/**
* Get id.
*
* @return int
*/
public function getId()
public function getFirstname(): ?string
{
return $this->firstname;
}
public function getId(): ?int
{
return $this->id;
}
@ -469,12 +475,7 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
return $this->kind;
}
/**
* Get name.
*
* @return string
*/
public function getName()
public function getName(): string
{
return $this->name;
}
@ -766,6 +767,13 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
return $this;
}
public function setFirstname($firstname): self
{
$this->firstname = $firstname;
return $this;
}
public function setKind(?string $kind): ThirdParty
{
$this->kind = $kind;
@ -773,14 +781,7 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
return $this;
}
/**
* Set name.
*
* @param string $name
*
* @return ThirdParty
*/
public function setName($name)
public function setName($name): self
{
$this->name = $name;

View File

@ -0,0 +1,31 @@
<?php
/**
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Chill\ThirdPartyBundle\EventListener;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use const MB_CASE_TITLE;
class ThirdPartyEventListener
{
public function prePersistThirdParty(ThirdParty $thirdparty): void
{
if ($thirdparty->getKind() !== 'company') {
$firstnameCaps = mb_convert_case(mb_strtolower($thirdparty->getFirstname()), MB_CASE_TITLE, 'UTF-8');
$firstnameCaps = ucwords(strtolower($firstnameCaps), " \t\r\n\f\v'-");
$thirdparty->setFirstName($firstnameCaps);
$lastnameCaps = mb_strtoupper($thirdparty->getName(), 'UTF-8');
$thirdparty->setName($lastnameCaps);
}
}
}

View File

@ -102,6 +102,10 @@ class ThirdPartyType extends AbstractType
// Contact Person ThirdParty (child)
if (ThirdParty::KIND_CONTACT === $options['kind'] || ThirdParty::KIND_CHILD === $options['kind']) {
$builder
->add('firstname', TextType::class, [
'label' => 'firstname',
'required' => false,
])
->add('civility', PickCivilityType::class, [
'label' => 'thirdparty.Civility',
'placeholder' => 'thirdparty.choose civility',

View File

@ -66,14 +66,14 @@
<div v-if="thirdparty.kind === 'child' || thirdparty.kind === 'contact'">
<div id="child-info">
<div class="input-group mb-3">
<div class="input-group mb-3 input-section">
<select class="form-select form-select-lg" id="civility"
v-model="thirdparty.civility">
<option selected disabled :value="null" >{{ $t('thirdparty.civility') }}</option>
<option v-for="civility in civilities" :key="civility.id" :value="civility">{{ civility.name.fr }}</option>
</select>
</div>
<div class="input-group mb-3">
<div class="input-group mb-3 input-section">
<select class="form-select form-select-lg" id="profession"
v-model="thirdparty.profession">
<option selected disabled :value="null">{{ $t('thirdparty.profession') }}</option>
@ -81,18 +81,48 @@
</select>
</div>
</div>
<div class="child-info">
<div class="input-section">
<div class="form-floating mb-3">
<input class="form-control form-control-lg" id="firstname" v-model="thirdparty.firstname" v-bind:placeholder="$t('thirdparty.firstname')" />
<label for="firstname">{{ $t('thirdparty.firstname') }}</label>
</div>
<div v-if="queryItems">
<ul class="list-suggest add-items inline">
<li v-for="(qi, i) in queryItems" :key="i" @click="addQueryItem('firstName', qi)">
<span class="person-text">{{ qi }}</span>
</li>
</ul>
</div>
</div>
<div class="input-section">
<div class="form-floating mb-3">
<input class="form-control form-control-lg" id="name" v-model="thirdparty.name" v-bind:placeholder="$t('thirdparty.lastname')" />
<label for="name">{{ $t('thirdparty.lastname') }}</label>
</div>
<div v-if="queryItems">
<ul class="list-suggest add-items inline">
<li v-for="(qi, i) in queryItems" :key="i" @click="addQueryItem('name', qi)">
<span class="person-text">{{ qi }}</span>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="form-floating mb-3">
<input class="form-control form-control-lg" id="name" v-model="thirdparty.name" v-bind:placeholder="$t('thirdparty.name')" />
<label for="name">{{ $t('thirdparty.name') }}</label>
</div>
<div v-if="query">
<ul class="list-suggest add-items inline">
<li @click="addQuery(query)">
<span class="person-text">{{ query }}</span>
</li>
</ul>
<div v-if="thirdparty.kind === 'company'">
<div class="form-floating mb-3">
<input class="form-control form-control-lg" id="name" v-model="thirdparty.name" v-bind:placeholder="$t('thirdparty.name')" />
<label for="name">{{ $t('thirdparty.name') }}</label>
</div>
<div v-if="query">
<ul class="list-suggest add-items inline">
<li @click="addQuery(query)">
<span class="person-text">{{ query }}</span>
</li>
</ul>
</div>
</div>
<template
@ -158,6 +188,7 @@ export default {
type: 'thirdparty',
address: null,
kind: 'company',
firstname: '',
name: '',
telephone: '',
civility: null,
@ -212,6 +243,9 @@ export default {
//this.context = context; <--
return context;
},
queryItems() {
return this.query ? this.query.split(' ') : null;
},
},
methods: {
loadData(){
@ -260,6 +294,16 @@ export default {
console.log('switch address to edit mode', this.context);
}
},
addQueryItem(field, queryItem) {
switch (field) {
case 'name':
this.thirdparty.name = queryItem;
break;
case 'firstName':
this.thirdparty.firstname = queryItem;
break;
}
},
addQuery(query) {
this.thirdparty.name = query;
},
@ -305,10 +349,10 @@ dl {
margin-bottom: 1rem;
}
#child-info {
.child-info {
display: flex;
justify-content: space-between;
div {
.input-section {
width: 49%;
}
}

View File

@ -1,6 +1,8 @@
const thirdpartyMessages = {
fr: {
thirdparty: {
firstname: "Prénom",
lastname: "Nom",
name: "Dénomination",
email: "Courriel",
phonenumber: "Téléphone",

View File

@ -3,6 +3,10 @@
{{ form_row(form.civility) }}
{% endif %}
{% if form.firstname is defined %}
{{ form_row(form.firstname) }}
{% endif %}
{{ form_row(form.name) }}
{% if form.nameCompany is defined %}

View File

@ -7,6 +7,11 @@
{{ form_errors(form.civility) }}
{{ form_label(form.civility) }}
</div>
<div class="form-group col-md-5 mb-3">
{{ form_widget(form.firstname) }}
{{ form_errors(form.firstname) }}
{{ form_label(form.firstname) }}
</div>
<div class="form-group col-md-5 mb-3">
{{ form_widget(form.name) }}
{{ form_errors(form.name) }}

View File

@ -1,7 +1,8 @@
{% extends "@ChillMain/layout.html.twig" %}
{% set thirdParty = entity %}
{% set title_ = 'Show third party %name%'|trans({'%name%' : thirdParty.name }) %}
{% set name = thirdParty.firstname is not empty ? thirdParty.firstname ~ ' ' ~ thirdParty.name : thirdParty.name %}
{% set title_ = 'Show third party %name%'|trans({'%name%' : name }) %}
{% block title title_ %}
@ -25,7 +26,7 @@
<dt>{{ 'Name'|trans }}</dt>
<dd>
{% if thirdParty.isLeaf == true %}{{ thirdParty.civility }}{% endif %}
{{ thirdParty.name }}
{{ thirdParty.firstname ~ ' ' ~ thirdParty.name }}
</dd>
{% if thirdParty.kind == 'company' %}

View File

@ -43,6 +43,7 @@ class ThirdPartyNormalizer implements NormalizerAwareInterface, NormalizerInterf
{
return [
'type' => 'thirdparty',
'firstname' => $thirdParty->getFirstname(),
'name' => $thirdParty->getName(),
'text' => $this->thirdPartyRender->renderString($thirdParty, []),
'id' => $thirdParty->getId(),

View File

@ -77,7 +77,9 @@ class ThirdPartyRender extends AbstractChillEntityRender
$acronym = '';
}
return $civility . $entity->getName() . $acronym;
$firstname = empty($entity->getFirstname()) ? '' : $entity->getFirstname();
return $civility . $firstname . ' ' . $entity->getName() . $acronym;
}
public function supports($entity, array $options): bool

View File

@ -20,6 +20,8 @@ components:
type: string
enum:
- "thirdparty"
firstname:
type: string
name:
type: string
email:

View File

@ -0,0 +1,9 @@
services:
Chill\ThirdPartyBundle\EventListener\ThirdPartyEventListener:
autoconfigure: true
tags:
-
name: 'doctrine.orm.entity_listener'
event: 'prePersist'
entity: 'Chill\ThirdPartyBundle\Entity\ThirdParty'
method: 'prePersistThirdParty'

View File

@ -39,15 +39,17 @@ final class Version20211007165001 extends AbstractMigration
$this->addSql("
UPDATE chill_3party.third_party
SET canonicalized =
UNACCENT(
LOWER(
name ||
CASE WHEN COALESCE(name_company, '') <> '' THEN ' ' ELSE '' END ||
COALESCE(name_company, '') ||
CASE WHEN COALESCE(acronym, '') <> '' THEN ' ' ELSE '' END ||
COALESCE(acronym, '')
)
)
UNACCENT(
LOWER(
name ||
CASE WHEN COALESCE (firstname, '') <> '' THEN ' ' ELSE '' END ||
COALESCE(firstname, '') ||
CASE WHEN COALESCE(name_company, '') <> '' THEN ' ' ELSE '' END ||
COALESCE(name_company, '') ||
CASE WHEN COALESCE(acronym, '') <> '' THEN ' ' ELSE '' END ||
COALESCE(acronym, '')
)
)
");
$this->addSql("
CREATE OR REPLACE FUNCTION chill_3party.canonicalize() RETURNS TRIGGER

View File

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace Chill\Migrations\ThirdParty;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20220322095659 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add firstname to thirdparty';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE chill_3party.third_party ADD firstname VARCHAR(255) DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE chill_3party.third_party DROP firstname');
}
}

View File

@ -1,6 +1,7 @@
Third party: Tiers
Third parties: Tiers
third parties: tiers
firstname: Prénom
name: Nom
telephone: Téléphone
adress: Adresse