Merge branch 'master' of gitlab.com:Chill-Projet/chill-bundles

This commit is contained in:
Julie Lenaerts 2022-03-25 17:06:06 +01:00
commit 3babbe5e84
15 changed files with 197 additions and 74 deletions

View File

@ -11,6 +11,9 @@ and this project adheres to
## Unreleased ## Unreleased
<!-- write down unreleased development here --> <!-- write down unreleased development here -->
* [person] Accompanying course evaluation documents: disable the WOPI edit link if mimetype not supported and if no keyInfos
(https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/585)
* [activity] display error messages above the form in creating a new location (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/481) * [activity] display error messages above the form in creating a new location (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/481)
* [activity] show required field in activity edit/new by an asterix in the vuejs fields (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/494) * [activity] show required field in activity edit/new by an asterix in the vuejs fields (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/494)
* [ACL] fix allow to see the course, event if the scope'course does not contains the scope's user * [ACL] fix allow to see the course, event if the scope'course does not contains the scope's user

View File

@ -126,7 +126,7 @@ class ActivityType extends AbstractType
if ($activityType->isVisible('socialIssues') && $accompanyingPeriod) { if ($activityType->isVisible('socialIssues') && $accompanyingPeriod) {
$builder->add('socialIssues', HiddenType::class, [ $builder->add('socialIssues', HiddenType::class, [
'required' => $activityType->getSocialIssuesVisible() === 2 'required' => $activityType->getSocialIssuesVisible() === 2,
]); ]);
$builder->get('socialIssues') $builder->get('socialIssues')
->addModelTransformer(new CallbackTransformer( ->addModelTransformer(new CallbackTransformer(
@ -154,7 +154,7 @@ class ActivityType extends AbstractType
if ($activityType->isVisible('socialActions') && $accompanyingPeriod) { if ($activityType->isVisible('socialActions') && $accompanyingPeriod) {
$builder->add('socialActions', HiddenType::class, [ $builder->add('socialActions', HiddenType::class, [
'required' => $activityType->getSocialActionsVisible() === 2 'required' => $activityType->getSocialActionsVisible() === 2,
]); ]);
$builder->get('socialActions') $builder->get('socialActions')
->addModelTransformer(new CallbackTransformer( ->addModelTransformer(new CallbackTransformer(
@ -344,8 +344,8 @@ class ActivityType extends AbstractType
if ($activityType->isVisible('location')) { if ($activityType->isVisible('location')) {
$builder->add('location', HiddenType::class, [ $builder->add('location', HiddenType::class, [
'required' => $activityType->getLocationVisible() === 2 'required' => $activityType->getLocationVisible() === 2,
]) ])
->get('location') ->get('location')
->addModelTransformer(new CallbackTransformer( ->addModelTransformer(new CallbackTransformer(
static function (?Location $location): string { static function (?Location $location): string {

View File

@ -41,12 +41,14 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface
$period = $parameters['accompanyingCourse']; $period = $parameters['accompanyingCourse'];
if (AccompanyingPeriod::STEP_DRAFT !== $period->getStep()) { if (AccompanyingPeriod::STEP_DRAFT !== $period->getStep()) {
/*
$menu->addChild($this->translator->trans('Calendar'), [ $menu->addChild($this->translator->trans('Calendar'), [
'route' => 'chill_calendar_calendar_list', 'route' => 'chill_calendar_calendar_list',
'routeParameters' => [ 'routeParameters' => [
'accompanying_period_id' => $period->getId(), 'accompanying_period_id' => $period->getId(),
], ]) ], ])
->setExtras(['order' => 35]); ->setExtras(['order' => 35]);
*/
} }
} }

View File

@ -283,7 +283,7 @@ final class DocGeneratorTemplateController extends AbstractController
} }
$datas = $context->getData($template, $entity, $contextGenerationData); $datas = $context->getData($template, $entity, $contextGenerationData);
if ($isTest && $form['show_data']->getData()) { if ($isTest && isset($form) && $form['show_data']->getData()) {
// very ugly hack... // very ugly hack...
dd($datas); dd($datas);
} }

View File

@ -22,7 +22,7 @@ use libphonenumber\PhoneNumber;
*/ */
interface PhoneNumberHelperInterface interface PhoneNumberHelperInterface
{ {
public function format(PhoneNumber $phoneNumber): string; public function format(?PhoneNumber $phoneNumber = null): string;
/** /**
* Get type (mobile, landline, ...) for phone number. * Get type (mobile, landline, ...) for phone number.

View File

@ -78,8 +78,12 @@ final class PhonenumberHelper implements PhoneNumberHelperInterface
* *
* @throws NumberParseException * @throws NumberParseException
*/ */
public function format(PhoneNumber $phoneNumber): string public function format(?PhoneNumber $phoneNumber = null): string
{ {
if (null === $phoneNumber) {
return '';
}
return $this->phoneNumberUtil return $this->phoneNumberUtil
->formatOutOfCountryCallingNumber($phoneNumber, $this->config['default_carrier_code']); ->formatOutOfCountryCallingNumber($phoneNumber, $this->config['default_carrier_code']);
} }

View File

@ -59,4 +59,10 @@
{{ chill_pagination(paginator) }} {{ chill_pagination(paginator) }}
{% endblock %} <ul class="record_actions sticky-form-buttons">
<li>
<a href="{{ path('chill_crud_admin_user_new') }}" class="btn btn-create">{{ 'Create'|trans }}</a>
</li>
</ul>
{% endblock %}

View File

@ -1,12 +1,11 @@
<h2>
{{ 'workflow_'|trans }}
</h2>
<div class="item-row col"> <div class="item-row col">
<h2> {% include handler.template(entity_workflow) with handler.templateData(entity_workflow)|merge({
{{ 'workflow_'|trans }}
</h2>
{% include handler.templateTitle(entity_workflow) with handler.templateTitleData(entity_workflow)|merge({
'description': true, 'description': true,
'breadcrumb': true, 'breadcrumb': true,
'add_classes': 'ms-3 h3' 'add_classes': ''
}) %} }) %}
</div> </div>

View File

@ -232,7 +232,6 @@ class PersonResource implements TrackCreationInterface, TrackUpdateInterface
} }
if (null !== $this->person && $this->person === $this->personOwner) { if (null !== $this->person && $this->person === $this->personOwner) {
$context->buildViolation('You cannot associate a resource with the same person') $context->buildViolation('You cannot associate a resource with the same person')
->addViolation(); ->addViolation();
} }

View File

@ -96,7 +96,19 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface
$workflow = $this->registry->get($period, 'accompanying_period_lifecycle'); $workflow = $this->registry->get($period, 'accompanying_period_lifecycle');
if (null !== $period->getClosingDate()) { if ($this->security->isGranted(AccompanyingPeriodVoter::EDIT, $period)) {
if ($workflow->can($period, 'close')) {
$menu->addChild($this->translator->trans('Close Accompanying Course'), [
'route' => 'chill_person_accompanying_course_close',
'routeParameters' => [
'accompanying_period_id' => $period->getId(),
], ])
->setExtras(['order' => 99999]);
}
}
if (null !== $period->getClosingDate()
&& $this->security->isGranted(AccompanyingPeriodVoter::RE_OPEN_COURSE, $period)) {
$menu->addChild($this->translator->trans('Re-open accompanying course'), [ $menu->addChild($this->translator->trans('Re-open accompanying course'), [
'route' => 'chill_person_accompanying_course_reopen', 'route' => 'chill_person_accompanying_course_reopen',
'routeParameters' => [ 'routeParameters' => [
@ -104,15 +116,6 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface
], ]) ], ])
->setExtras(['order' => 99998]); ->setExtras(['order' => 99998]);
} }
if ($workflow->can($period, 'close')) {
$menu->addChild($this->translator->trans('Close Accompanying Course'), [
'route' => 'chill_person_accompanying_course_close',
'routeParameters' => [
'accompanying_period_id' => $period->getId(),
], ])
->setExtras(['order' => 99999]);
}
} }
public static function getMenuIds(): array public static function getMenuIds(): array

View File

@ -113,9 +113,8 @@
:storedObject="d.storedObject" :storedObject="d.storedObject"
> >
</add-async-upload-downloader> </add-async-upload-downloader>
</li> </li>
<li> <li v-if="canEditDocument(d)">
<a :href="buildEditLink(d.storedObject)" class="btn btn-wopilink"></a> <a :href="buildEditLink(d.storedObject)" class="btn btn-wopilink"></a>
</li> </li>
<li v-if="d.workflows.length === 0"> <li v-if="d.workflows.length === 0">
@ -220,7 +219,79 @@ export default {
maxFiles: 1, maxFiles: 1,
maxPostSize: 15000000, maxPostSize: 15000000,
required: false, required: false,
} },
mime: [
// TODO temporary hardcoded. to be replaced by twig extension or a collabora server query
'application/clarisworks',
'application/coreldraw',
'application/macwriteii',
'application/msword',
'application/vnd.lotus-1-2-3',
'application/vnd.ms-excel',
'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
'application/vnd.ms-excel.sheet.macroEnabled.12',
'application/vnd.ms-excel.template.macroEnabled.12',
'application/vnd.ms-powerpoint',
'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
'application/vnd.ms-powerpoint.template.macroEnabled.12',
'application/vnd.ms-visio.drawing',
'application/vnd.ms-word.document.macroEnabled.12',
'application/vnd.ms-word.template.macroEnabled.12',
'application/vnd.ms-works',
'application/vnd.oasis.opendocument.chart',
'application/vnd.oasis.opendocument.formula',
'application/vnd.oasis.opendocument.graphics',
'application/vnd.oasis.opendocument.graphics-flat-xml',
'application/vnd.oasis.opendocument.graphics-template',
'application/vnd.oasis.opendocument.presentation',
'application/vnd.oasis.opendocument.presentation-flat-xml',
'application/vnd.oasis.opendocument.presentation-template',
'application/vnd.oasis.opendocument.spreadsheet',
'application/vnd.oasis.opendocument.spreadsheet-flat-xml',
'application/vnd.oasis.opendocument.spreadsheet-template',
'application/vnd.oasis.opendocument.text',
'application/vnd.oasis.opendocument.text-flat-xml',
'application/vnd.oasis.opendocument.text-master',
'application/vnd.oasis.opendocument.text-master-template',
'application/vnd.oasis.opendocument.text-template',
'application/vnd.oasis.opendocument.text-web',
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
'application/vnd.openxmlformats-officedocument.presentationml.template',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
'application/vnd.sun.xml.calc',
'application/vnd.sun.xml.calc.template',
'application/vnd.sun.xml.chart',
'application/vnd.sun.xml.draw',
'application/vnd.sun.xml.draw.template',
'application/vnd.sun.xml.impress',
'application/vnd.sun.xml.impress.template',
'application/vnd.sun.xml.math',
'application/vnd.sun.xml.writer',
'application/vnd.sun.xml.writer.global',
'application/vnd.sun.xml.writer.template',
'application/vnd.visio',
'application/vnd.visio2013',
'application/vnd.wordperfect',
'application/x-abiword',
'application/x-aportisdoc',
'application/x-dbase',
'application/x-dif-document',
'application/x-fictionbook+xml',
'application/x-gnumeric',
'application/x-hwp',
'application/x-iwork-keynote-sffkey',
'application/x-iwork-numbers-sffnumbers',
'application/x-iwork-pages-sffpages',
'application/x-mspublisher',
'application/x-mswrite',
'application/x-pagemaker',
'application/x-sony-bbeb',
'application/x-t602',
]
} }
}, },
computed: { computed: {
@ -268,6 +339,10 @@ export default {
}, },
methods: { methods: {
ISOToDatetime, ISOToDatetime,
canEditDocument(document) {
return 'storedObject' in document ?
this.mime.includes(document.storedObject.type) && document.storedObject.keyInfos.length === 0 : false;
},
listAllStatus() { listAllStatus() {
console.log('load all status'); console.log('load all status');
let url = `/api/`; let url = `/api/`;
@ -340,4 +415,4 @@ export default {
font-weight: bold; font-weight: bold;
font-size: 1rem; font-size: 1rem;
} }
</style> </style>

View File

@ -34,12 +34,23 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH
self::FULL, self::FULL,
self::TOGGLE_CONFIDENTIAL_ALL, self::TOGGLE_CONFIDENTIAL_ALL,
self::TOGGLE_INTENSITY, self::TOGGLE_INTENSITY,
self::RE_OPEN_COURSE,
]; ];
public const CREATE = 'CHILL_PERSON_ACCOMPANYING_PERIOD_CREATE'; public const CREATE = 'CHILL_PERSON_ACCOMPANYING_PERIOD_CREATE';
/**
* role to DELETE the course.
*
* Will be true only for the creator, and if the course is still at DRAFT step.
*/
public const DELETE = 'CHILL_PERSON_ACCOMPANYING_PERIOD_DELETE'; public const DELETE = 'CHILL_PERSON_ACCOMPANYING_PERIOD_DELETE';
/**
* role to EDIT the course.
*
* If the course is closed, it will be always false.
*/
public const EDIT = 'CHILL_PERSON_ACCOMPANYING_PERIOD_UPDATE'; public const EDIT = 'CHILL_PERSON_ACCOMPANYING_PERIOD_UPDATE';
/** /**
@ -47,6 +58,14 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH
*/ */
public const FULL = 'CHILL_PERSON_ACCOMPANYING_PERIOD_FULL'; public const FULL = 'CHILL_PERSON_ACCOMPANYING_PERIOD_FULL';
/**
* Reopen a closed course.
*
* This forward to the EDIT role, without taking into account that the course
* is closed
*/
public const RE_OPEN_COURSE = 'CHILL_PERSON_ACCOMPANYING_PERIOD_REOPEN';
public const SEE = 'CHILL_PERSON_ACCOMPANYING_PERIOD_SEE'; public const SEE = 'CHILL_PERSON_ACCOMPANYING_PERIOD_SEE';
/** /**
@ -116,6 +135,10 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH
if (in_array($attribute, [self::EDIT, self::DELETE], true)) { if (in_array($attribute, [self::EDIT, self::DELETE], true)) {
return false; return false;
} }
if (self::RE_OPEN_COURSE === $attribute) {
return $this->voterHelper->voteOnAttribute(self::EDIT, $subject, $token);
}
} }
if (AccompanyingPeriod::STEP_DRAFT === $subject->getStep()) { if (AccompanyingPeriod::STEP_DRAFT === $subject->getStep()) {
@ -131,8 +154,8 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH
} }
if (in_array($attribute, [ if (in_array($attribute, [
self::SEE, self::SEE_DETAILS, self::EDIT self::SEE, self::SEE_DETAILS, self::EDIT,
])) { ], true)) {
if ($subject->getUser() === $token->getUser()) { if ($subject->getUser() === $token->getUser()) {
return true; return true;
} }

View File

@ -12,6 +12,7 @@ declare(strict_types=1);
namespace Chill\TaskBundle\Menu; namespace Chill\TaskBundle\Menu;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface; use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\TaskBundle\Security\Authorization\TaskVoter; use Chill\TaskBundle\Security\Authorization\TaskVoter;
use Knp\Menu\MenuItem; use Knp\Menu\MenuItem;
use LogicException; use LogicException;
@ -40,9 +41,11 @@ class MenuBuilder implements LocalMenuBuilderInterface
public function buildAccompanyingCourseMenu($menu, $parameters) public function buildAccompanyingCourseMenu($menu, $parameters)
{ {
/** @var AccompanyingPeriod $course */
$course = $parameters['accompanyingCourse']; $course = $parameters['accompanyingCourse'];
if ($this->authorizationChecker->isGranted(TaskVoter::SHOW, $course)) { if ($this->authorizationChecker->isGranted(TaskVoter::SHOW, $course)
&& AccompanyingPeriod::STEP_DRAFT !== $course->getStep()) {
$menu->addChild( $menu->addChild(
$this->translator->trans('Tasks'), $this->translator->trans('Tasks'),
[ [

View File

@ -198,7 +198,7 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
private ?string $email = null; private ?string $email = null;
/** /**
* @ORM\Column(name="firstname", type="text", options={"default":""}) * @ORM\Column(name="firstname", type="text", options={"default": ""})
* @Groups({"read", "write", "docgen:read", "docgen:read:3party:parent"}) * @Groups({"read", "write", "docgen:read", "docgen:read:3party:parent"})
*/ */
private string $firstname = ''; private string $firstname = '';

View File

@ -1,5 +1,12 @@
<?php <?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); declare(strict_types=1);
namespace Chill\Migrations\ThirdParty; namespace Chill\Migrations\ThirdParty;
@ -9,6 +16,45 @@ use Doctrine\Migrations\AbstractMigration;
final class Version20220324175549 extends AbstractMigration final class Version20220324175549 extends AbstractMigration
{ {
public function down(Schema $schema): void
{
$this->addSql("
CREATE OR REPLACE FUNCTION chill_3party.canonicalize() RETURNS TRIGGER
LANGUAGE plpgsql
AS
$$
BEGIN
NEW.canonicalized =
UNACCENT(
LOWER(
NEW.name ||
CASE WHEN COALESCE(NEW.name_company, '') <> '' THEN ' ' ELSE '' END ||
COALESCE(NEW.name_company, '') ||
CASE WHEN COALESCE(NEW.acronym, '') <> '' THEN ' ' ELSE '' END ||
COALESCE(NEW.acronym, '')
)
)
;
return NEW;
END
$$
");
$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, '')
)
)
");
}
public function getDescription(): string public function getDescription(): string
{ {
return 'indexing of firstname on third parties'; return 'indexing of firstname on third parties';
@ -55,45 +101,5 @@ final class Version20220324175549 extends AbstractMigration
END END
$$ $$
"); ");
}
public function down(Schema $schema): void
{
$this->addSql("
CREATE OR REPLACE FUNCTION chill_3party.canonicalize() RETURNS TRIGGER
LANGUAGE plpgsql
AS
$$
BEGIN
NEW.canonicalized =
UNACCENT(
LOWER(
NEW.name ||
CASE WHEN COALESCE(NEW.name_company, '') <> '' THEN ' ' ELSE '' END ||
COALESCE(NEW.name_company, '') ||
CASE WHEN COALESCE(NEW.acronym, '') <> '' THEN ' ' ELSE '' END ||
COALESCE(NEW.acronym, '')
)
)
;
return NEW;
END
$$
");
$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, '')
)
)
");
} }
} }