mirror of
				https://gitlab.com/Chill-Projet/chill-bundles.git
				synced 2025-11-04 03:08:25 +00:00 
			
		
		
		
	Compare commits
	
		
			51 Commits
		
	
	
		
			issue719_f
			...
			71-adapt-r
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 2dcc65d172 | |||
| 2d6a0d14eb | |||
| fcb057c55b | |||
| 
						
						
							
						
						96ddc73e45
	
				 | 
					
					
						|||
| 
						
						
							
						
						4eb7d10e45
	
				 | 
					
					
						|||
| efa475df0f | |||
| 
						
						
							
						
						a8977729fe
	
				 | 
					
					
						|||
| 
						
						
							
						
						ecac409586
	
				 | 
					
					
						|||
| 
						
						
							
						
						df2480c47c
	
				 | 
					
					
						|||
| c729a14304 | |||
| 06b7e84270 | |||
| 
						
						
							
						
						1cc80c8e6a
	
				 | 
					
					
						|||
| 
						
						
							
						
						c3558beee1
	
				 | 
					
					
						|||
| 
						
						
							
						
						44ecad2bca
	
				 | 
					
					
						|||
| 
						
						
							
						
						d1bdf41c4c
	
				 | 
					
					
						|||
| 4a30f310b8 | |||
| 896b4cdfe3 | |||
| a272dabcaf | |||
| 3901fe2d32 | |||
| 
						
						
							
						
						78858e84f2
	
				 | 
					
					
						|||
| cc98f64be5 | |||
| 
						
						
							
						
						6e812b54e1
	
				 | 
					
					
						|||
| 
						
						
							
						
						83e0a50b57
	
				 | 
					
					
						|||
| 
						
						
							
						
						3aac4d5d35
	
				 | 
					
					
						|||
| 
						
						
							
						
						23cee274a5
	
				 | 
					
					
						|||
| aacb54037b | |||
| 57cb96320c | |||
| 5a2d80cb4d | |||
| 2e822a9486 | |||
| f376b1af49 | |||
| dd621186e8 | |||
| 1b15abe635 | |||
| 1965fc55f4 | |||
| a9290eb3fe | |||
| 
						
						
							
						
						e78eb8789d
	
				 | 
					
					
						|||
| 9911112e08 | |||
| 
						
						
							
						
						c0675aee9b
	
				 | 
					
					
						|||
| 
						
						
							
						
						03ee04978c
	
				 | 
					
					
						|||
| 15d68df8c6 | |||
| 
						
						
							
						
						1b2c0ecc87
	
				 | 
					
					
						|||
| 
						
						
							
						
						f15017ebd7
	
				 | 
					
					
						|||
| 
						
						
							
						
						9a56a1b115
	
				 | 
					
					
						|||
| 
						
						
							
						
						11e7f2179c
	
				 | 
					
					
						|||
| 
						
						
							
						
						e982e81900
	
				 | 
					
					
						|||
| 
						
						
							
						
						e50b02a8c7
	
				 | 
					
					
						|||
| 
						
						
							
						
						bea839663f
	
				 | 
					
					
						|||
| 
						
						
							
						
						ac4c821290
	
				 | 
					
					
						|||
| c953da3fd0 | |||
| 
						
						
							
						
						f5d17eb38c
	
				 | 
					
					
						|||
| f07ea3259e | |||
| 1f4438690e | 
@@ -257,12 +257,10 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac
 | 
			
		||||
    /**
 | 
			
		||||
     * Add a social issue.
 | 
			
		||||
     *
 | 
			
		||||
     * Note: the social issue consistency (the fact that only yougest social issues
 | 
			
		||||
     * Note: the social issue consistency (the fact that only youngest social issues
 | 
			
		||||
     * are kept) is processed by an entity listener:
 | 
			
		||||
     *
 | 
			
		||||
     * @see{\Chill\PersonBundle\AccompanyingPeriod\SocialIssueConsistency\AccompanyingPeriodSocialIssueConsistencyEntityListener}
 | 
			
		||||
     *
 | 
			
		||||
     * @return $this
 | 
			
		||||
     */
 | 
			
		||||
    public function addSocialIssue(SocialIssue $socialIssue): self
 | 
			
		||||
    {
 | 
			
		||||
@@ -270,6 +268,10 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac
 | 
			
		||||
            $this->socialIssues[] = $socialIssue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($this->getAccompanyingPeriod() !== null) {
 | 
			
		||||
            $this->getAccompanyingPeriod()->addSocialIssue($socialIssue);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -550,6 +552,10 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac
 | 
			
		||||
    {
 | 
			
		||||
        $this->accompanyingPeriod = $accompanyingPeriod;
 | 
			
		||||
 | 
			
		||||
        foreach ($this->getSocialIssues() as $issue) {
 | 
			
		||||
            $this->accompanyingPeriod->addSocialIssue($issue);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -50,7 +50,7 @@ class LocationFilter implements FilterInterface
 | 
			
		||||
    {
 | 
			
		||||
        $builder->add('accepted_location', PickUserLocationType::class, [
 | 
			
		||||
            'multiple' => true,
 | 
			
		||||
            'label' => 'pick location'
 | 
			
		||||
            'label' => 'pick location',
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -88,3 +88,11 @@ div.flex-bloc.concerned-groups {
 | 
			
		||||
      font-size: 120%;
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// DOCUMENT LIST IN ACTIVITY ITEM
 | 
			
		||||
li.document-list-item {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    justify-content: space-between;
 | 
			
		||||
    margin-bottom: 0.3rem;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -68,7 +68,7 @@
 | 
			
		||||
                    <div class="wl-col title"><h3>{{ 'Referrer'|trans }}</h3></div>
 | 
			
		||||
                    <div class="wl-col list">
 | 
			
		||||
                        <p class="wl-item">
 | 
			
		||||
                            {{ activity.user|chill_entity_render_box }}
 | 
			
		||||
                            <span class="badge-user">{{ activity.user|chill_entity_render_box }}</span>
 | 
			
		||||
                        </p>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
@@ -137,19 +137,42 @@
 | 
			
		||||
                        {{ activity.comment|chill_entity_render_box({
 | 
			
		||||
                            'disable_markdown': false,
 | 
			
		||||
                            'limit_lines': 3,
 | 
			
		||||
                            'metadata': false
 | 
			
		||||
                            'metadata': false,
 | 
			
		||||
                        }) }}
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            {% endif %}
 | 
			
		||||
 | 
			
		||||
            {#  Only if ACL SEE_DETAILS AND/OR only on template SHOW ??
 | 
			
		||||
                durationTime
 | 
			
		||||
                travelTime
 | 
			
		||||
                comment
 | 
			
		||||
                documents
 | 
			
		||||
                attendee
 | 
			
		||||
            #}
 | 
			
		||||
            {% if is_granted('CHILL_ACTIVITY_SEE_DETAILS', activity) and activity.privateComment.hasCommentForUser(app.user) %}
 | 
			
		||||
                <div class="wl-row">
 | 
			
		||||
                    <div class="wl-col title">
 | 
			
		||||
                        <h3>{{ 'Private comment'|trans }}</h3>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="wl-col list">
 | 
			
		||||
                        <section class="chill-entity entity-comment-embeddable">
 | 
			
		||||
                            <blockquote class="chill-user-quote private-quote">
 | 
			
		||||
                                {{ activity.privateComment.comments[app.user.id]|chill_markdown_to_html }}
 | 
			
		||||
                            </blockquote>
 | 
			
		||||
                        </section>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            {% endif %}
 | 
			
		||||
 | 
			
		||||
            {% if is_granted('CHILL_ACTIVITY_SEE_DETAILS', activity) and activity.documents|length > 0 %}
 | 
			
		||||
                <div class="wl-row">
 | 
			
		||||
                    <div class="wl-col title">
 | 
			
		||||
                        <h3>{{ 'Documents'|trans }}</h3>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="wl-col list">
 | 
			
		||||
                        <ul>
 | 
			
		||||
                            {% for d in activity.documents %}
 | 
			
		||||
                                <li class="document-list-item">{{ d.title|chill_print_or_message('document.Any title') }} {{ d|chill_document_button_group(d.title, is_granted('CHILL_ACTIVITY_UPDATE', activity), {small: true}) }}</li>
 | 
			
		||||
                            {% endfor %}
 | 
			
		||||
                        </ul>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            {% endif %}
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,11 +8,13 @@
 | 
			
		||||
{% block js %}
 | 
			
		||||
    {{ parent() }}
 | 
			
		||||
    {{ encore_entry_script_tags('mod_notification_toggle_read_status') }}
 | 
			
		||||
    {{ encore_entry_script_tags('mod_document_action_buttons_group') }}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block css %}
 | 
			
		||||
    {{ parent() }}
 | 
			
		||||
    {{ encore_entry_link_tags('mod_notification_toggle_read_status') }}
 | 
			
		||||
    {{ encore_entry_link_tags('mod_document_action_buttons_group') }}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
 
 | 
			
		||||
@@ -23,11 +23,13 @@
 | 
			
		||||
{% block js %}
 | 
			
		||||
    {{ parent() }}
 | 
			
		||||
    {{ encore_entry_script_tags('mod_notification_toggle_read_status') }}
 | 
			
		||||
    {{ encore_entry_script_tags('mod_document_action_buttons_group') }}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block css %}
 | 
			
		||||
    {{ parent() }}
 | 
			
		||||
    {{ encore_entry_link_tags('mod_notification_toggle_read_status') }}
 | 
			
		||||
    {{ encore_entry_link_tags('mod_document_action_buttons_group') }}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,7 @@
 | 
			
		||||
                        {% if activity.user and t.userVisible %}
 | 
			
		||||
                            <li>
 | 
			
		||||
                                <span class="item-key">{{ 'Referrer'|trans ~ ': ' }}</span>
 | 
			
		||||
                                <b>{{ activity.user|chill_entity_render_box}}</b>
 | 
			
		||||
                                <span class="badge-user">{{ activity.user|chill_entity_render_box }}</span>
 | 
			
		||||
                            </li>
 | 
			
		||||
                        {% endif %}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,9 @@
 | 
			
		||||
        <div class="item-row separator">
 | 
			
		||||
            <dl class="chill_view_data">
 | 
			
		||||
                <dt class="inline">{{ 'Referrer'|trans|capitalize }}</dt>
 | 
			
		||||
                <dd>{{ entity.user|chill_entity_render_box }}</dd>
 | 
			
		||||
                <dd>
 | 
			
		||||
                    <span class="badge-user">{{ entity.user|chill_entity_render_box }}</span>
 | 
			
		||||
                </dd>
 | 
			
		||||
 | 
			
		||||
                {%- if entity.scope -%}
 | 
			
		||||
                    <dt class="inline">{{ 'Scope'|trans }}</dt>
 | 
			
		||||
@@ -168,7 +170,7 @@
 | 
			
		||||
                    {% if entity.documents|length > 0 %}
 | 
			
		||||
                        <ul>
 | 
			
		||||
                            {% for d in entity.documents %}
 | 
			
		||||
                                <li>{{ d.title }} {{ d|chill_document_button_group() }}</li>
 | 
			
		||||
                                <li class="document-list-item">{{ d.title|chill_print_or_message('document.Any title') }} {{ d|chill_document_button_group(d.title, is_granted('CHILL_ACTIVITY_UPDATE', entity), {small: true}) }}</li>
 | 
			
		||||
                            {% endfor %}
 | 
			
		||||
                        </ul>
 | 
			
		||||
                    {% else %}
 | 
			
		||||
 
 | 
			
		||||
@@ -152,7 +152,7 @@ class ActivityContext implements
 | 
			
		||||
        $options = $template->getOptions();
 | 
			
		||||
 | 
			
		||||
        $data = [];
 | 
			
		||||
        $data = array_merge($data, $this->baseContextData->getData());
 | 
			
		||||
        $data = array_merge($data, $this->baseContextData->getData($contextGenerationData['creator'] ?? null));
 | 
			
		||||
        $data['activity'] = $this->normalizer->normalize($entity, 'docgen', ['docgen:expects' => Activity::class, 'groups' => 'docgen:read']);
 | 
			
		||||
 | 
			
		||||
        $data['course'] = $this->normalizer->normalize($entity->getAccompanyingPeriod(), 'docgen', ['docgen:expects' => AccompanyingPeriod::class, 'groups' => 'docgen:read']);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,18 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\AsideActivityBundle\Export\Export;
 | 
			
		||||
 | 
			
		||||
use Chill\AsideActivityBundle\Entity\AsideActivity;
 | 
			
		||||
use Chill\AsideActivityBundle\Export\Declarations;
 | 
			
		||||
use Chill\AsideActivityBundle\Form\AsideActivityCategoryType;
 | 
			
		||||
use Chill\AsideActivityBundle\Repository\AsideActivityCategoryRepository;
 | 
			
		||||
use Chill\AsideActivityBundle\Security\AsideActivityVoter;
 | 
			
		||||
use Chill\AsideActivityBundle\Templating\Entity\CategoryRender;
 | 
			
		||||
@@ -16,32 +24,32 @@ use Chill\MainBundle\Export\Helper\UserHelper;
 | 
			
		||||
use Chill\MainBundle\Export\ListInterface;
 | 
			
		||||
use Chill\MainBundle\Repository\CenterRepositoryInterface;
 | 
			
		||||
use Chill\MainBundle\Repository\ScopeRepositoryInterface;
 | 
			
		||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
 | 
			
		||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
 | 
			
		||||
use Closure;
 | 
			
		||||
use DateTimeInterface;
 | 
			
		||||
use Doctrine\ORM\AbstractQuery;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
use LogicException;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
final class ListAsideActivity implements ListInterface, GroupedExportInterface
 | 
			
		||||
{
 | 
			
		||||
    private EntityManagerInterface $em;
 | 
			
		||||
 | 
			
		||||
    private UserHelper $userHelper;
 | 
			
		||||
 | 
			
		||||
    private DateTimeHelper $dateTimeHelper;
 | 
			
		||||
 | 
			
		||||
    private ScopeRepositoryInterface $scopeRepository;
 | 
			
		||||
 | 
			
		||||
    private CenterRepositoryInterface $centerRepository;
 | 
			
		||||
 | 
			
		||||
    private AsideActivityCategoryRepository $asideActivityCategoryRepository;
 | 
			
		||||
 | 
			
		||||
    private CategoryRender $categoryRender;
 | 
			
		||||
 | 
			
		||||
    private CenterRepositoryInterface $centerRepository;
 | 
			
		||||
 | 
			
		||||
    private DateTimeHelper $dateTimeHelper;
 | 
			
		||||
 | 
			
		||||
    private EntityManagerInterface $em;
 | 
			
		||||
 | 
			
		||||
    private ScopeRepositoryInterface $scopeRepository;
 | 
			
		||||
 | 
			
		||||
    private TranslatableStringHelperInterface $translatableStringHelper;
 | 
			
		||||
 | 
			
		||||
    private UserHelper $userHelper;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        EntityManagerInterface $em,
 | 
			
		||||
        DateTimeHelper $dateTimeHelper,
 | 
			
		||||
@@ -76,11 +84,6 @@ final class ListAsideActivity implements ListInterface, GroupedExportInterface
 | 
			
		||||
        return 'export.aside_activity.List of aside activities';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getTitle()
 | 
			
		||||
    {
 | 
			
		||||
        return 'export.aside_activity.List of aside activities';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getGroup(): string
 | 
			
		||||
    {
 | 
			
		||||
        return 'export.Exports of aside activities';
 | 
			
		||||
@@ -91,15 +94,16 @@ final class ListAsideActivity implements ListInterface, GroupedExportInterface
 | 
			
		||||
        switch ($key) {
 | 
			
		||||
            case 'id':
 | 
			
		||||
            case 'note':
 | 
			
		||||
                return function ($value) use ($key) {
 | 
			
		||||
                return static function ($value) use ($key) {
 | 
			
		||||
                    if ('_header' === $value) {
 | 
			
		||||
                        return 'export.aside_activity.' . $key;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    return $value ?? '';
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
            case 'duration':
 | 
			
		||||
                return function ($value) use ($key) {
 | 
			
		||||
                return static function ($value) use ($key) {
 | 
			
		||||
                    if ('_header' === $value) {
 | 
			
		||||
                        return 'export.aside_activity.' . $key;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -108,7 +112,7 @@ final class ListAsideActivity implements ListInterface, GroupedExportInterface
 | 
			
		||||
                        return '';
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if ($value instanceof \DateTimeInterface) {
 | 
			
		||||
                    if ($value instanceof DateTimeInterface) {
 | 
			
		||||
                        return $value->format('H:i:s');
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
@@ -118,7 +122,7 @@ final class ListAsideActivity implements ListInterface, GroupedExportInterface
 | 
			
		||||
            case 'createdAt':
 | 
			
		||||
            case 'updatedAt':
 | 
			
		||||
            case 'date':
 | 
			
		||||
                return $this->dateTimeHelper->getLabel('export.aside_activity.'.$key);
 | 
			
		||||
                return $this->dateTimeHelper->getLabel('export.aside_activity.' . $key);
 | 
			
		||||
 | 
			
		||||
            case 'agent_id':
 | 
			
		||||
            case 'creator_id':
 | 
			
		||||
@@ -165,7 +169,7 @@ final class ListAsideActivity implements ListInterface, GroupedExportInterface
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                throw new \LogicException('this key is not supported : ' . $key);
 | 
			
		||||
                throw new LogicException('this key is not supported : ' . $key);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -182,7 +186,7 @@ final class ListAsideActivity implements ListInterface, GroupedExportInterface
 | 
			
		||||
            'aside_activity_type',
 | 
			
		||||
            'date',
 | 
			
		||||
            'duration',
 | 
			
		||||
            'note'
 | 
			
		||||
            'note',
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -195,6 +199,11 @@ final class ListAsideActivity implements ListInterface, GroupedExportInterface
 | 
			
		||||
        return $query->getQuery()->getResult(AbstractQuery::HYDRATE_ARRAY);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getTitle()
 | 
			
		||||
    {
 | 
			
		||||
        return 'export.aside_activity.List of aside activities';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getType(): string
 | 
			
		||||
    {
 | 
			
		||||
        return Declarations::ASIDE_ACTIVITY_TYPE;
 | 
			
		||||
@@ -204,8 +213,7 @@ final class ListAsideActivity implements ListInterface, GroupedExportInterface
 | 
			
		||||
    {
 | 
			
		||||
        $qb = $this->em->createQueryBuilder()
 | 
			
		||||
            ->from(AsideActivity::class, 'aside')
 | 
			
		||||
            ->leftJoin('aside.agent', 'agent')
 | 
			
		||||
        ;
 | 
			
		||||
            ->leftJoin('aside.agent', 'agent');
 | 
			
		||||
 | 
			
		||||
        $qb
 | 
			
		||||
            ->addSelect('aside.id AS id')
 | 
			
		||||
@@ -218,8 +226,7 @@ final class ListAsideActivity implements ListInterface, GroupedExportInterface
 | 
			
		||||
            ->addSelect('IDENTITY(aside.type) AS aside_activity_type')
 | 
			
		||||
            ->addSelect('aside.date')
 | 
			
		||||
            ->addSelect('aside.duration')
 | 
			
		||||
            ->addSelect('aside.note')
 | 
			
		||||
        ;
 | 
			
		||||
            ->addSelect('aside.note');
 | 
			
		||||
 | 
			
		||||
        return $qb;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,6 @@ use Chill\MainBundle\Form\Type\Export\FilterType;
 | 
			
		||||
use Chill\MainBundle\Form\Type\PickRollingDateType;
 | 
			
		||||
use Chill\MainBundle\Service\RollingDate\RollingDate;
 | 
			
		||||
use Chill\MainBundle\Service\RollingDate\RollingDateConverterInterface;
 | 
			
		||||
use Doctrine\ORM\Query\Expr\Andx;
 | 
			
		||||
use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
use Symfony\Component\Form\FormError;
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,6 @@ use Chill\AsideActivityBundle\Export\Declarations;
 | 
			
		||||
use Chill\MainBundle\Export\FilterInterface;
 | 
			
		||||
use Chill\MainBundle\Form\Type\PickUserDynamicType;
 | 
			
		||||
use Chill\MainBundle\Templating\Entity\UserRender;
 | 
			
		||||
use Doctrine\ORM\Query\Expr\Andx;
 | 
			
		||||
use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
use Symfony\Component\Form\FormBuilderInterface;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ class ChargeKindType extends AbstractType
 | 
			
		||||
            ])
 | 
			
		||||
            ->add('kind', TextType::class, [
 | 
			
		||||
                'label' => 'budget.admin.form.Charge_kind_key',
 | 
			
		||||
                'help' => 'budget.admin.form.This kind must contains only alphabeticals characters, and dashes. This string is in use during document generation. Changes may have side effect on document'
 | 
			
		||||
                'help' => 'budget.admin.form.This kind must contains only alphabeticals characters, and dashes. This string is in use during document generation. Changes may have side effect on document',
 | 
			
		||||
            ])
 | 
			
		||||
            ->add('ordering', NumberType::class)
 | 
			
		||||
            ->add('isActive', CheckboxType::class, [
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ class ResourceKindType extends AbstractType
 | 
			
		||||
            ])
 | 
			
		||||
            ->add('kind', TextType::class, [
 | 
			
		||||
                'label' => 'budget.admin.form.Resource_kind_key',
 | 
			
		||||
                'help' => 'budget.admin.form.This kind must contains only alphabeticals characters, and dashes. This string is in use during document generation. Changes may have side effect on document'
 | 
			
		||||
                'help' => 'budget.admin.form.This kind must contains only alphabeticals characters, and dashes. This string is in use during document generation. Changes may have side effect on document',
 | 
			
		||||
            ])
 | 
			
		||||
            ->add('ordering', NumberType::class)
 | 
			
		||||
            ->add('isActive', CheckboxType::class, [
 | 
			
		||||
 
 | 
			
		||||
@@ -49,8 +49,7 @@ final class ChargeKindRepository implements ChargeKindRepositoryInterface
 | 
			
		||||
            ->where($qb->expr()->eq('c.isActive', 'true'))
 | 
			
		||||
            ->orderBy('c.ordering', 'ASC')
 | 
			
		||||
            ->getQuery()
 | 
			
		||||
            ->getResult()
 | 
			
		||||
        ;
 | 
			
		||||
            ->getResult();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -28,8 +28,6 @@ interface ChargeKindRepositoryInterface extends ObjectRepository
 | 
			
		||||
     */
 | 
			
		||||
    public function findAllActive(): array;
 | 
			
		||||
 | 
			
		||||
    public function findOneByKind(string $kind): ?ChargeKind;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return ChargeType[]
 | 
			
		||||
     */
 | 
			
		||||
@@ -45,5 +43,7 @@ interface ChargeKindRepositoryInterface extends ObjectRepository
 | 
			
		||||
 | 
			
		||||
    public function findOneBy(array $criteria): ?ChargeKind;
 | 
			
		||||
 | 
			
		||||
    public function findOneByKind(string $kind): ?ChargeKind;
 | 
			
		||||
 | 
			
		||||
    public function getClassName(): string;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -49,8 +49,7 @@ final class ResourceKindRepository implements ResourceKindRepositoryInterface
 | 
			
		||||
            ->where($qb->expr()->eq('r.isActive', 'true'))
 | 
			
		||||
            ->orderBy('r.ordering', 'ASC')
 | 
			
		||||
            ->getQuery()
 | 
			
		||||
            ->getResult()
 | 
			
		||||
        ;
 | 
			
		||||
            ->getResult();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,7 @@ class ResourceRepository extends EntityRepository
 | 
			
		||||
            //->andWhere('c.startDate < :date')
 | 
			
		||||
            // TODO: there is a misconception here, the end date must be lower or null. startDate are never null
 | 
			
		||||
            //->andWhere('c.startDate < :date OR c.startDate IS NULL');
 | 
			
		||||
        ;
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
        if (null !== $sort) {
 | 
			
		||||
            $qb->orderBy($sort);
 | 
			
		||||
 
 | 
			
		||||
@@ -13,9 +13,7 @@ namespace Chill\BudgetBundle\Service\Summary;
 | 
			
		||||
 | 
			
		||||
use Chill\BudgetBundle\Entity\ChargeKind;
 | 
			
		||||
use Chill\BudgetBundle\Entity\ResourceKind;
 | 
			
		||||
use Chill\BudgetBundle\Repository\ChargeKindRepository;
 | 
			
		||||
use Chill\BudgetBundle\Repository\ChargeKindRepositoryInterface;
 | 
			
		||||
use Chill\BudgetBundle\Repository\ResourceKindRepository;
 | 
			
		||||
use Chill\BudgetBundle\Repository\ResourceKindRepositoryInterface;
 | 
			
		||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
 | 
			
		||||
use Chill\PersonBundle\Entity\Household\Household;
 | 
			
		||||
 
 | 
			
		||||
@@ -20,12 +20,15 @@ use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
 | 
			
		||||
use Chill\PersonBundle\Entity\Household\Household;
 | 
			
		||||
use Chill\PersonBundle\Entity\Household\HouseholdMember;
 | 
			
		||||
use Chill\PersonBundle\Entity\Person;
 | 
			
		||||
use DateTimeImmutable;
 | 
			
		||||
use Doctrine\ORM\AbstractQuery;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\Query;
 | 
			
		||||
use PHPUnit\Framework\TestCase;
 | 
			
		||||
use Prophecy\Argument;
 | 
			
		||||
use Prophecy\PhpUnit\ProphecyTrait;
 | 
			
		||||
use ReflectionClass;
 | 
			
		||||
use RuntimeException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
@@ -47,10 +50,9 @@ final class SummaryBudgetTest extends TestCase
 | 
			
		||||
            ],
 | 
			
		||||
        ]);
 | 
			
		||||
        $queryCharges->setParameters(Argument::type('array'))
 | 
			
		||||
            ->will(function ($args, $query) {
 | 
			
		||||
            ->will(static function ($args, $query) {
 | 
			
		||||
                return $query;
 | 
			
		||||
            })
 | 
			
		||||
        ;
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        $queryResources = $this->prophesize(AbstractQuery::class);
 | 
			
		||||
        $queryResources->getResult()->willReturn([
 | 
			
		||||
@@ -61,23 +63,23 @@ final class SummaryBudgetTest extends TestCase
 | 
			
		||||
            ],
 | 
			
		||||
        ]);
 | 
			
		||||
        $queryResources->setParameters(Argument::type('array'))
 | 
			
		||||
            ->will(function ($args, $query) {
 | 
			
		||||
            ->will(static function ($args, $query) {
 | 
			
		||||
                return $query;
 | 
			
		||||
            })
 | 
			
		||||
        ;
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        $em = $this->prophesize(EntityManagerInterface::class);
 | 
			
		||||
        $em->createNativeQuery(Argument::type('string'), Argument::type(Query\ResultSetMapping::class))
 | 
			
		||||
            ->will(function ($args) use ($queryResources, $queryCharges) {
 | 
			
		||||
            ->will(static function ($args) use ($queryResources, $queryCharges) {
 | 
			
		||||
                if (false !== strpos($args[0], 'chill_budget.resource')) {
 | 
			
		||||
                    return $queryResources->reveal();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (false !== strpos($args[0], 'chill_budget.charge')) {
 | 
			
		||||
                    return $queryCharges->reveal();
 | 
			
		||||
                }
 | 
			
		||||
                throw new \RuntimeException('this query does not have a stub counterpart: '.$args[0]);
 | 
			
		||||
            })
 | 
			
		||||
        ;
 | 
			
		||||
 | 
			
		||||
                throw new RuntimeException('this query does not have a stub counterpart: ' . $args[0]);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        $chargeRepository = $this->prophesize(ChargeKindRepositoryInterface::class);
 | 
			
		||||
        $chargeRepository->findAll()->willReturn([
 | 
			
		||||
@@ -98,24 +100,23 @@ final class SummaryBudgetTest extends TestCase
 | 
			
		||||
        $resourceRepository->findOneByKind('misc')->willReturn($misc);
 | 
			
		||||
 | 
			
		||||
        $translatableStringHelper = $this->prophesize(TranslatableStringHelperInterface::class);
 | 
			
		||||
        $translatableStringHelper->localize(Argument::type('array'))->will(function ($arg) {
 | 
			
		||||
        $translatableStringHelper->localize(Argument::type('array'))->will(static function ($arg) {
 | 
			
		||||
            return $arg[0]['fr'];
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        $person = new Person();
 | 
			
		||||
        $personReflection = new \ReflectionClass($person);
 | 
			
		||||
        $personReflection = new ReflectionClass($person);
 | 
			
		||||
        $personIdReflection = $personReflection->getProperty('id');
 | 
			
		||||
        $personIdReflection->setAccessible(true);
 | 
			
		||||
        $personIdReflection->setValue($person, 1);
 | 
			
		||||
 | 
			
		||||
        $household = new Household();
 | 
			
		||||
        $householdReflection = new \ReflectionClass($household);
 | 
			
		||||
        $householdReflection = new ReflectionClass($household);
 | 
			
		||||
        $householdId = $householdReflection->getProperty('id');
 | 
			
		||||
        $householdId->setAccessible(true);
 | 
			
		||||
        $householdId->setValue($household, 1);
 | 
			
		||||
        $householdMember = (new HouseholdMember())->setPerson($person)
 | 
			
		||||
            ->setStartDate(new \DateTimeImmutable('1 month ago'))
 | 
			
		||||
        ;
 | 
			
		||||
            ->setStartDate(new DateTimeImmutable('1 month ago'));
 | 
			
		||||
        $household->addMember($householdMember);
 | 
			
		||||
 | 
			
		||||
        $summaryBudget = new SummaryBudget(
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,13 @@
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\Migrations\Budget;
 | 
			
		||||
 | 
			
		||||
use Doctrine\DBAL\Schema\Schema;
 | 
			
		||||
@@ -9,6 +16,12 @@ use Doctrine\Migrations\AbstractMigration;
 | 
			
		||||
 | 
			
		||||
final class Version20230209161546 extends AbstractMigration
 | 
			
		||||
{
 | 
			
		||||
    public function down(Schema $schema): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->addSql('DROP INDEX resource_kind_unique_type_idx');
 | 
			
		||||
        $this->addSql('DROP INDEX charge_kind_unique_type_idx');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getDescription(): string
 | 
			
		||||
    {
 | 
			
		||||
        return 'Budget: add unique constraint on kind for charge_kind and resource_kind';
 | 
			
		||||
@@ -21,10 +34,4 @@ final class Version20230209161546 extends AbstractMigration
 | 
			
		||||
        $this->addSql('CREATE UNIQUE INDEX resource_kind_unique_type_idx ON chill_budget.resource_type (kind);');
 | 
			
		||||
        $this->addSql('CREATE UNIQUE INDEX charge_kind_unique_type_idx ON chill_budget.charge_type (kind);');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function down(Schema $schema): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->addSql('DROP INDEX resource_kind_unique_type_idx');
 | 
			
		||||
        $this->addSql('DROP INDEX charge_kind_unique_type_idx');
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,8 @@ Budget: Budget
 | 
			
		||||
Resource: Inkomsten
 | 
			
		||||
Charge: Onkosten
 | 
			
		||||
Budget for %name%: Budget van %name%
 | 
			
		||||
Budget for household %household%: Budget van gezin
 | 
			
		||||
Current budget household members: Actuele budget van gezinsleden
 | 
			
		||||
Budget for household %household%: Budget van huishouden
 | 
			
		||||
Current budget household members: Actuele budget van leden huishouden
 | 
			
		||||
Show budget of %name%: Toon budget van %name%
 | 
			
		||||
See complete budget: Toon volledige budget
 | 
			
		||||
Hide budget: Verbergen
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,7 @@ use Chill\MainBundle\Entity\User;
 | 
			
		||||
use DateTimeImmutable;
 | 
			
		||||
use LogicException;
 | 
			
		||||
use Psr\Log\LoggerInterface;
 | 
			
		||||
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
 | 
			
		||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
 | 
			
		||||
use function array_key_exists;
 | 
			
		||||
 | 
			
		||||
@@ -74,9 +75,18 @@ class MapCalendarToUser
 | 
			
		||||
 | 
			
		||||
    public function getDefaultUserCalendar(string $idOrUserPrincipalName): ?array
 | 
			
		||||
    {
 | 
			
		||||
        $value = $this->machineHttpClient->request('GET', "users/{$idOrUserPrincipalName}/calendars", [
 | 
			
		||||
            'query' => ['$filter' => 'isDefaultCalendar eq true'],
 | 
			
		||||
        ])->toArray()['value'];
 | 
			
		||||
        try {
 | 
			
		||||
            $value = $this->machineHttpClient->request('GET', "users/{$idOrUserPrincipalName}/calendars", [
 | 
			
		||||
                'query' => ['$filter' => 'isDefaultCalendar eq true'],
 | 
			
		||||
            ])->toArray()['value'];
 | 
			
		||||
        } catch (ClientExceptionInterface $e) {
 | 
			
		||||
            $this->logger->error('[MapCalendarToUser] Error while listing calendars for a user', [
 | 
			
		||||
                'http_status_code' => $e->getResponse()->getStatusCode(),
 | 
			
		||||
                'id_user' => $idOrUserPrincipalName,
 | 
			
		||||
            ]);
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $value[0] ?? null;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,7 @@ use Psr\Log\LoggerInterface;
 | 
			
		||||
use Symfony\Component\HttpFoundation\RedirectResponse;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Response;
 | 
			
		||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
 | 
			
		||||
use Symfony\Component\Security\Core\Security;
 | 
			
		||||
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
 | 
			
		||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
 | 
			
		||||
use Symfony\Contracts\Translation\TranslatorInterface;
 | 
			
		||||
@@ -64,6 +65,8 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
 | 
			
		||||
 | 
			
		||||
    private OnBehalfOfUserHttpClient $userHttpClient;
 | 
			
		||||
 | 
			
		||||
    private Security $security;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        CalendarRepository $calendarRepository,
 | 
			
		||||
        CalendarRangeRepository $calendarRangeRepository,
 | 
			
		||||
@@ -74,7 +77,8 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
 | 
			
		||||
        OnBehalfOfUserHttpClient $userHttpClient,
 | 
			
		||||
        RemoteEventConverter $remoteEventConverter,
 | 
			
		||||
        TranslatorInterface $translator,
 | 
			
		||||
        UrlGeneratorInterface $urlGenerator
 | 
			
		||||
        UrlGeneratorInterface $urlGenerator,
 | 
			
		||||
        Security $security
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->calendarRepository = $calendarRepository;
 | 
			
		||||
        $this->calendarRangeRepository = $calendarRangeRepository;
 | 
			
		||||
@@ -86,6 +90,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
 | 
			
		||||
        $this->translator = $translator;
 | 
			
		||||
        $this->urlGenerator = $urlGenerator;
 | 
			
		||||
        $this->userHttpClient = $userHttpClient;
 | 
			
		||||
        $this->security = $security;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function countEventsForUser(User $user, DateTimeImmutable $startDate, DateTimeImmutable $endDate): int
 | 
			
		||||
@@ -133,6 +138,24 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
 | 
			
		||||
 | 
			
		||||
    public function isReady(): bool
 | 
			
		||||
    {
 | 
			
		||||
        $user = $this->security->getUser();
 | 
			
		||||
 | 
			
		||||
        if (!$user instanceof User) {
 | 
			
		||||
            // this is not a user from chill. This is not the role of this class to
 | 
			
		||||
            // restrict access, so we will just say that we do not have to do anything more
 | 
			
		||||
            // here...
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (null === $this->mapCalendarToUser->getUserId($user)) {
 | 
			
		||||
            // this user is not mapped with remote calendar. The user will have to wait for
 | 
			
		||||
            // the next calendar subscription iteration
 | 
			
		||||
            $this->logger->debug('mark user ready for msgraph calendar as he does not have any mapping', [
 | 
			
		||||
                'userId' => $user->getId(),
 | 
			
		||||
            ]);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this->tokenStorage->hasToken();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -156,7 +156,7 @@ final class CalendarContext implements CalendarContextInterface
 | 
			
		||||
        $options = $this->getOptions($template);
 | 
			
		||||
 | 
			
		||||
        $data = array_merge(
 | 
			
		||||
            $this->baseContextData->getData(),
 | 
			
		||||
            $this->baseContextData->getData($contextGenerationData['creator'] ?? null),
 | 
			
		||||
            [
 | 
			
		||||
                'calendar' => $this->normalizer->normalize($entity, 'docgen', ['docgen:expects' => Calendar::class, 'groups' => ['docgen:read']]),
 | 
			
		||||
            ]
 | 
			
		||||
 
 | 
			
		||||
@@ -205,7 +205,7 @@ final class CalendarContextTest extends TestCase
 | 
			
		||||
        ?NormalizerInterface $normalizer = null
 | 
			
		||||
    ): CalendarContext {
 | 
			
		||||
        $baseContext = $this->prophesize(BaseContextData::class);
 | 
			
		||||
        $baseContext->getData()->willReturn(['base_context' => 'data']);
 | 
			
		||||
        $baseContext->getData(null)->willReturn(['base_context' => 'data']);
 | 
			
		||||
 | 
			
		||||
        $personRender = $this->prophesize(PersonRender::class);
 | 
			
		||||
        $personRender->renderString(Argument::type(Person::class), [])->willReturn('person name');
 | 
			
		||||
 
 | 
			
		||||
@@ -39,6 +39,7 @@ use Symfony\Component\Routing\Annotation\Route;
 | 
			
		||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
 | 
			
		||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
 | 
			
		||||
use function strlen;
 | 
			
		||||
use const JSON_PRETTY_PRINT;
 | 
			
		||||
 | 
			
		||||
final class DocGeneratorTemplateController extends AbstractController
 | 
			
		||||
{
 | 
			
		||||
@@ -255,7 +256,7 @@ final class DocGeneratorTemplateController extends AbstractController
 | 
			
		||||
        // if is test, render the data or generate the doc
 | 
			
		||||
        if ($isTest && isset($form) && $form['show_data']->getData()) {
 | 
			
		||||
            return $this->render('@ChillDocGenerator/Generator/debug_value.html.twig', [
 | 
			
		||||
                'datas' => json_encode($context->getData($template, $entity, $contextGenerationData), JSON_PRETTY_PRINT)
 | 
			
		||||
                'datas' => json_encode($context->getData($template, $entity, $contextGenerationData), JSON_PRETTY_PRINT),
 | 
			
		||||
            ]);
 | 
			
		||||
        } elseif ($isTest) {
 | 
			
		||||
            $generated = $this->generator->generateDocFromTemplate(
 | 
			
		||||
 
 | 
			
		||||
@@ -21,18 +21,14 @@ class BaseContextData
 | 
			
		||||
{
 | 
			
		||||
    private NormalizerInterface $normalizer;
 | 
			
		||||
 | 
			
		||||
    private Security $security;
 | 
			
		||||
 | 
			
		||||
    public function __construct(Security $security, NormalizerInterface $normalizer)
 | 
			
		||||
    public function __construct(NormalizerInterface $normalizer)
 | 
			
		||||
    {
 | 
			
		||||
        $this->security = $security;
 | 
			
		||||
        $this->normalizer = $normalizer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getData(): array
 | 
			
		||||
    public function getData(?User $user = null): array
 | 
			
		||||
    {
 | 
			
		||||
        $data = [];
 | 
			
		||||
        $user = $this->security->getUser();
 | 
			
		||||
 | 
			
		||||
        $data['creator'] = $this->normalizer->normalize(
 | 
			
		||||
            $user instanceof User ? $user : null,
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,7 @@ use Chill\DocGeneratorBundle\GeneratorDriver\DriverInterface;
 | 
			
		||||
use Chill\DocGeneratorBundle\GeneratorDriver\Exception\TemplateException;
 | 
			
		||||
use Chill\DocStoreBundle\Entity\StoredObject;
 | 
			
		||||
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
 | 
			
		||||
use Chill\MainBundle\Entity\User;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Psr\Log\LoggerInterface;
 | 
			
		||||
use Symfony\Component\HttpFoundation\File\File;
 | 
			
		||||
@@ -55,7 +56,8 @@ class Generator implements GeneratorInterface
 | 
			
		||||
        array                $contextGenerationDataNormalized,
 | 
			
		||||
        ?StoredObject        $destinationStoredObject = null,
 | 
			
		||||
        bool                 $isTest = false,
 | 
			
		||||
        ?File                $testFile = null
 | 
			
		||||
        ?File                $testFile = null,
 | 
			
		||||
        ?User                $creator = null
 | 
			
		||||
    ): ?string {
 | 
			
		||||
        if ($destinationStoredObject instanceof StoredObject && StoredObject::STATUS_PENDING !== $destinationStoredObject->getStatus()) {
 | 
			
		||||
            $this->logger->info(self::LOG_PREFIX.'Aborting generation of an already generated document');
 | 
			
		||||
@@ -80,6 +82,7 @@ class Generator implements GeneratorInterface
 | 
			
		||||
 | 
			
		||||
        $contextGenerationDataNormalized = array_merge(
 | 
			
		||||
            $contextGenerationDataNormalized,
 | 
			
		||||
                ['creator' => $creator],
 | 
			
		||||
                $context instanceof DocGeneratorContextWithPublicFormInterface ?
 | 
			
		||||
                    $context->contextGenerationDataDenormalize($template, $entity, $contextGenerationDataNormalized)
 | 
			
		||||
                    : []
 | 
			
		||||
 
 | 
			
		||||
@@ -1,19 +1,34 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\DocGeneratorBundle\Service\Generator;
 | 
			
		||||
 | 
			
		||||
class GeneratorException extends \RuntimeException
 | 
			
		||||
use RuntimeException;
 | 
			
		||||
use Throwable;
 | 
			
		||||
 | 
			
		||||
class GeneratorException extends RuntimeException
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @var list<string>
 | 
			
		||||
     */
 | 
			
		||||
    private array $errors;
 | 
			
		||||
 | 
			
		||||
    public function __construct(array $errors = [], \Throwable $previous = null)
 | 
			
		||||
    public function __construct(array $errors = [], ?Throwable $previous = null)
 | 
			
		||||
    {
 | 
			
		||||
        $this->errors = $errors;
 | 
			
		||||
        parent::__construct("Could not generate the document", 15252,
 | 
			
		||||
            $previous);
 | 
			
		||||
        parent::__construct(
 | 
			
		||||
            'Could not generate the document',
 | 
			
		||||
            15252,
 | 
			
		||||
            $previous
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ namespace Chill\DocGeneratorBundle\Service\Generator;
 | 
			
		||||
 | 
			
		||||
use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate;
 | 
			
		||||
use Chill\DocStoreBundle\Entity\StoredObject;
 | 
			
		||||
use Chill\MainBundle\Entity\User;
 | 
			
		||||
use Symfony\Component\HttpFoundation\File\File;
 | 
			
		||||
 | 
			
		||||
interface GeneratorInterface
 | 
			
		||||
@@ -22,6 +23,7 @@ interface GeneratorInterface
 | 
			
		||||
        array                $contextGenerationDataNormalized,
 | 
			
		||||
        ?StoredObject        $destinationStoredObject = null,
 | 
			
		||||
        bool                 $isTest = false,
 | 
			
		||||
        ?File                $testFile = null
 | 
			
		||||
        ?File                $testFile = null,
 | 
			
		||||
        ?User                $creator = null
 | 
			
		||||
    ): ?string;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,22 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\DocGeneratorBundle\Service\Generator;
 | 
			
		||||
 | 
			
		||||
class ObjectReadyException extends \RuntimeException
 | 
			
		||||
use RuntimeException;
 | 
			
		||||
 | 
			
		||||
class ObjectReadyException extends RuntimeException
 | 
			
		||||
{
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct("object is already ready", 6698856);
 | 
			
		||||
        parent::__construct('object is already ready', 6698856);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,26 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\DocGeneratorBundle\Service\Generator;
 | 
			
		||||
 | 
			
		||||
class RelatedEntityNotFoundException extends \RuntimeException
 | 
			
		||||
use RuntimeException;
 | 
			
		||||
 | 
			
		||||
class RelatedEntityNotFoundException extends RuntimeException
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(string $relatedEntityClass, int $relatedEntityId, Throwable $previous = null)
 | 
			
		||||
    public function __construct(string $relatedEntityClass, int $relatedEntityId, ?Throwable $previous = null)
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct(
 | 
			
		||||
            sprintf("Related entity not found: %s, %s", $relatedEntityClass, $relatedEntityId),
 | 
			
		||||
            sprintf('Related entity not found: %s, %s', $relatedEntityClass, $relatedEntityId),
 | 
			
		||||
            99876652,
 | 
			
		||||
            $previous);
 | 
			
		||||
            $previous
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,9 @@ use Chill\DocGeneratorBundle\Repository\DocGeneratorTemplateRepository;
 | 
			
		||||
use Chill\DocGeneratorBundle\Service\Generator\Generator;
 | 
			
		||||
use Chill\DocStoreBundle\Entity\StoredObject;
 | 
			
		||||
use Chill\DocStoreBundle\Repository\StoredObjectRepository;
 | 
			
		||||
use Chill\MainBundle\Repository\UserRepositoryInterface;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Psr\Log\LoggerInterface;
 | 
			
		||||
use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException;
 | 
			
		||||
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
 | 
			
		||||
 | 
			
		||||
@@ -23,18 +25,28 @@ class RequestGenerationHandler implements MessageHandlerInterface
 | 
			
		||||
 | 
			
		||||
    private Generator $generator;
 | 
			
		||||
 | 
			
		||||
    private LoggerInterface $logger;
 | 
			
		||||
 | 
			
		||||
    private UserRepositoryInterface $userRepository;
 | 
			
		||||
 | 
			
		||||
    public const AUTHORIZED_TRIALS = 5;
 | 
			
		||||
 | 
			
		||||
    private const LOG_PREFIX = '[docgen message handler] ';
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        DocGeneratorTemplateRepository $docGeneratorTemplateRepository,
 | 
			
		||||
        EntityManagerInterface $entityManager,
 | 
			
		||||
        Generator $generator,
 | 
			
		||||
        StoredObjectRepository $storedObjectRepository
 | 
			
		||||
        LoggerInterface $logger,
 | 
			
		||||
        StoredObjectRepository $storedObjectRepository,
 | 
			
		||||
        UserRepositoryInterface $userRepository
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->docGeneratorTemplateRepository = $docGeneratorTemplateRepository;
 | 
			
		||||
        $this->entityManager = $entityManager;
 | 
			
		||||
        $this->generator = $generator;
 | 
			
		||||
        $this->logger = $logger;
 | 
			
		||||
        $this->storedObjectRepository = $storedObjectRepository;
 | 
			
		||||
        $this->userRepository = $userRepository;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function __invoke(RequestGenerationMessage $message)
 | 
			
		||||
@@ -51,6 +63,8 @@ class RequestGenerationHandler implements MessageHandlerInterface
 | 
			
		||||
            throw new UnrecoverableMessageHandlingException('maximum number of retry reached');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $creator = $this->userRepository->find($message->getCreatorId());
 | 
			
		||||
 | 
			
		||||
        $destinationStoredObject->addGenerationTrial();
 | 
			
		||||
        $this->entityManager->createQuery('UPDATE '.StoredObject::class.' s SET s.generationTrialsCounter = s.generationTrialsCounter + 1 WHERE s.id = :id')
 | 
			
		||||
            ->setParameter('id', $destinationStoredObject->getId())
 | 
			
		||||
@@ -60,7 +74,16 @@ class RequestGenerationHandler implements MessageHandlerInterface
 | 
			
		||||
            $template,
 | 
			
		||||
            $message->getEntityId(),
 | 
			
		||||
            $message->getContextGenerationData(),
 | 
			
		||||
            $destinationStoredObject
 | 
			
		||||
            $destinationStoredObject,
 | 
			
		||||
            false,
 | 
			
		||||
            null,
 | 
			
		||||
            $creator
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $this->logger->info(self::LOG_PREFIX.'Request generation finished', [
 | 
			
		||||
            'template_id' => $message->getTemplateId(),
 | 
			
		||||
            'destination_stored_object' => $message->getDestinationStoredObjectId(),
 | 
			
		||||
            'duration_int' => (new \DateTimeImmutable('now'))->getTimestamp() - $message->getCreatedAt()->getTimestamp(),
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,8 @@ class RequestGenerationMessage
 | 
			
		||||
 | 
			
		||||
   private array $contextGenerationData;
 | 
			
		||||
 | 
			
		||||
   private \DateTimeImmutable $createdAt;
 | 
			
		||||
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        User $creator,
 | 
			
		||||
        DocGeneratorTemplate $template,
 | 
			
		||||
@@ -30,6 +32,7 @@ class RequestGenerationMessage
 | 
			
		||||
        $this->entityId = $entityId;
 | 
			
		||||
        $this->destinationStoredObjectId = $destinationStoredObject->getId();
 | 
			
		||||
        $this->contextGenerationData = $contextGenerationData;
 | 
			
		||||
        $this->createdAt = new \DateTimeImmutable('now');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getCreatorId(): int
 | 
			
		||||
@@ -56,4 +59,9 @@ class RequestGenerationMessage
 | 
			
		||||
    {
 | 
			
		||||
        return $this->contextGenerationData;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getCreatedAt(): \DateTimeImmutable
 | 
			
		||||
    {
 | 
			
		||||
        return $this->createdAt;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div v-if="'ready' === props.storedObject.status" class="dropdown">
 | 
			
		||||
  <div v-if="'ready' === props.storedObject.status" class="btn-group">
 | 
			
		||||
    <button :class="Object.assign({'btn': true, 'btn-outline-primary': true, 'dropdown-toggle': true, 'btn-sm': props.small})" type="button" data-bs-toggle="dropdown" aria-expanded="false">
 | 
			
		||||
      Actions
 | 
			
		||||
    </button>
 | 
			
		||||
 
 | 
			
		||||
@@ -38,13 +38,11 @@ async function download_and_open(event: Event): Promise<void> {
 | 
			
		||||
    button.href = window.URL.createObjectURL(raw);
 | 
			
		||||
    button.type = props.storedObject.type;
 | 
			
		||||
 | 
			
		||||
    if (props.filename !== undefined) {
 | 
			
		||||
      button.download = props.filename || 'document';
 | 
			
		||||
    button.download = props.filename || 'document';
 | 
			
		||||
 | 
			
		||||
      const ext = mime.getExtension(props.storedObject.type);
 | 
			
		||||
      if (null !== ext) {
 | 
			
		||||
        button.download = button.download + '.' + ext;
 | 
			
		||||
      }
 | 
			
		||||
    const ext = mime.getExtension(props.storedObject.type);
 | 
			
		||||
    if (null !== ext) {
 | 
			
		||||
      button.download = button.download + '.' + ext;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,9 @@ The document is successfully registered: Le document est enregistré
 | 
			
		||||
The document is successfully updated: Le document est mis à jour
 | 
			
		||||
Any description: Aucune description
 | 
			
		||||
 | 
			
		||||
document:
 | 
			
		||||
    Any title: Aucun titre
 | 
			
		||||
 | 
			
		||||
# delete
 | 
			
		||||
Delete document ?: Supprimer le document ?
 | 
			
		||||
Are you sure you want to remove this document ?: Êtes-vous sûr·e de vouloir supprimer ce document ?
 | 
			
		||||
@@ -73,4 +76,4 @@ CHILL_ACCOMPANYING_COURSE_DOCUMENT_CREATE: Créer un document
 | 
			
		||||
CHILL_ACCOMPANYING_COURSE_DOCUMENT_DELETE: Supprimer un document
 | 
			
		||||
CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE: Voir les documents
 | 
			
		||||
CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE_DETAILS: Voir les détails d'un document
 | 
			
		||||
CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE: Modifier un document
 | 
			
		||||
CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE: Modifier un document
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@ class LocationController extends CRUDController
 | 
			
		||||
 | 
			
		||||
    protected function customizeQuery(string $action, Request $request, $query): void
 | 
			
		||||
    {
 | 
			
		||||
        $query->where('e.availableForUsers = "TRUE"');
 | 
			
		||||
        $query->where('e.availableForUsers = TRUE');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator)
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,6 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Chill\MainBundle\Export;
 | 
			
		||||
 | 
			
		||||
use Closure;
 | 
			
		||||
use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@ declare(strict_types=1);
 | 
			
		||||
namespace Chill\MainBundle\Export\Helper;
 | 
			
		||||
 | 
			
		||||
use DateTime;
 | 
			
		||||
use DateTimeInterface;
 | 
			
		||||
use Exception;
 | 
			
		||||
use Symfony\Contracts\Translation\TranslatorInterface;
 | 
			
		||||
 | 
			
		||||
@@ -35,7 +36,7 @@ class DateTimeHelper
 | 
			
		||||
                return '';
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ($value instanceof \DateTimeInterface) {
 | 
			
		||||
            if ($value instanceof DateTimeInterface) {
 | 
			
		||||
                return $value;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@ use Chill\MainBundle\Repository\RegroupmentRepository;
 | 
			
		||||
use Exception;
 | 
			
		||||
use Symfony\Component\Form\DataMapperInterface;
 | 
			
		||||
use Symfony\Component\Form\FormInterface;
 | 
			
		||||
use function array_key_exists;
 | 
			
		||||
use function count;
 | 
			
		||||
 | 
			
		||||
class ExportPickCenterDataMapper implements DataMapperInterface
 | 
			
		||||
@@ -29,7 +30,7 @@ class ExportPickCenterDataMapper implements DataMapperInterface
 | 
			
		||||
     *
 | 
			
		||||
     * @throws Exception
 | 
			
		||||
     *
 | 
			
		||||
     * @return mixed
 | 
			
		||||
     * @return void
 | 
			
		||||
     */
 | 
			
		||||
    public function mapDataToForms($data, $forms)
 | 
			
		||||
    {
 | 
			
		||||
@@ -72,10 +73,12 @@ class ExportPickCenterDataMapper implements DataMapperInterface
 | 
			
		||||
            $centers[spl_object_hash($center)] = $center;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        foreach ($forms['regroupment']->getData() as $regroupment) {
 | 
			
		||||
            /** @var Regroupment $regroupment */
 | 
			
		||||
            foreach ($regroupment->getCenters() as $center) {
 | 
			
		||||
                $centers[spl_object_hash($center)] = $center;
 | 
			
		||||
        if (array_key_exists('regroupment', $forms)) {
 | 
			
		||||
            foreach ($forms['regroupment']->getData() as $regroupment) {
 | 
			
		||||
                /** @var Regroupment $regroupment */
 | 
			
		||||
                foreach ($regroupment->getCenters() as $center) {
 | 
			
		||||
                    $centers[spl_object_hash($center)] = $center;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -233,7 +233,7 @@ export default {
 | 
			
		||||
                     // console.log('data original', data);
 | 
			
		||||
                     data.parent = {type: "thirdparty", id: this.parent.id};
 | 
			
		||||
                     data.civility = data.civility !== null ? {type: 'chill_main_civility', id: data.civility.id} : null;
 | 
			
		||||
                     data.profession = data.profession !== null ? {type: 'third_party_profession', id:  data.profession.id} : null;
 | 
			
		||||
                     data.profession = data.profession !== '' ? data.profession : '';
 | 
			
		||||
                  } else {
 | 
			
		||||
                     type = this.$refs.castNew.radioType;
 | 
			
		||||
                     data = this.$refs.castNew.castDataByType();
 | 
			
		||||
@@ -241,8 +241,8 @@ export default {
 | 
			
		||||
                     if (typeof data.civility !== 'undefined' && null !== data.civility) {
 | 
			
		||||
                        data.civility = data.civility !== null ? {type: 'chill_main_civility', id: data.civility.id} : null;
 | 
			
		||||
                     }
 | 
			
		||||
                     if (typeof data.profession !== 'undefined' && null !== data.profession) {
 | 
			
		||||
                        data.profession = data.profession !== null ? {type: 'third_party_profession', id: data.profession.id} : null;
 | 
			
		||||
                     if (typeof data.profession !== 'undefined' && '' !== data.profession) {
 | 
			
		||||
                        data.profession = data.profession !== '' ? data.profession : '';
 | 
			
		||||
                     }
 | 
			
		||||
                     // console.log('onthefly data', data);
 | 
			
		||||
                  }
 | 
			
		||||
 
 | 
			
		||||
@@ -72,7 +72,7 @@
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="item-row column">
 | 
			
		||||
                    <table class="obj-res-eval my-3">
 | 
			
		||||
                    <table class="obj-res-eval smallfont my-3">
 | 
			
		||||
                        <thead>
 | 
			
		||||
                        <tr><th class="obj"><h4 class="title_label">Objectif - motif - dispositif</h4></th>
 | 
			
		||||
                            <th class="res"><h4 class="title_label">Résultats - orientations</h4></th>
 | 
			
		||||
 
 | 
			
		||||
@@ -253,8 +253,8 @@ No options availables. Your report is fully configured.: Geen beschikbare opties
 | 
			
		||||
Ungrouped exports: Overige expor
 | 
			
		||||
 | 
			
		||||
#export download
 | 
			
		||||
Download export: Téléchargement du rapport
 | 
			
		||||
Waiting for your report: En attente de votre rapport
 | 
			
		||||
Download export: Downloaden van rapport
 | 
			
		||||
Waiting for your report: Wachten op je rapport
 | 
			
		||||
Download your report: Télécharger votre rapport
 | 
			
		||||
Problem during download: Problème durant le téléchargement
 | 
			
		||||
# sans valeur
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,6 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Chill\PersonBundle\Export\Filter\AccompanyingCourseFilters;
 | 
			
		||||
 | 
			
		||||
use Chill\MainBundle\Entity\User;
 | 
			
		||||
use Chill\MainBundle\Entity\UserJob;
 | 
			
		||||
use Chill\MainBundle\Export\FilterInterface;
 | 
			
		||||
use Chill\MainBundle\Form\Type\PickRollingDateType;
 | 
			
		||||
 
 | 
			
		||||
@@ -20,9 +20,6 @@ div.accompanying-course-work {
 | 
			
		||||
                margin: 0;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        td {
 | 
			
		||||
            font-size: 85%;
 | 
			
		||||
        }
 | 
			
		||||
        td.obj,
 | 
			
		||||
        td.res {
 | 
			
		||||
            width: 50%;
 | 
			
		||||
@@ -37,6 +34,10 @@ div.accompanying-course-work {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .smallfont table.obj-res-eval {
 | 
			
		||||
        font-size: 85%;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ul {
 | 
			
		||||
        &.goal_title,
 | 
			
		||||
        &.result_list,
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,29 @@
 | 
			
		||||
  <div class="vue-component">
 | 
			
		||||
    <h2><a id="section-80"></a>{{ $t('referrer.title') }}</h2>
 | 
			
		||||
 | 
			
		||||
    <teleport to="body">
 | 
			
		||||
      <modal v-if="modal.showModal"
 | 
			
		||||
             :modalDialogClass="modal.modalDialogClass"
 | 
			
		||||
             @close="cancelChange">
 | 
			
		||||
        <template v-slot:header>
 | 
			
		||||
          <h3 class="modal-title">{{ $t('confirm.title') }}</h3>
 | 
			
		||||
        </template>
 | 
			
		||||
 | 
			
		||||
        <template v-slot:body-head>
 | 
			
		||||
          <div class="modal-body">
 | 
			
		||||
            <p v-html="$t('confirm.sure_referrer', { referrer: this.value.text })"></p>
 | 
			
		||||
          </div>
 | 
			
		||||
        </template>
 | 
			
		||||
 | 
			
		||||
        <template v-slot:footer>
 | 
			
		||||
          <button class="btn btn-save"
 | 
			
		||||
                  @click.prevent="this.confirmReferrer">
 | 
			
		||||
            {{ $t('confirm.ok_referrer')}}
 | 
			
		||||
          </button>
 | 
			
		||||
        </template>
 | 
			
		||||
      </modal>
 | 
			
		||||
    </teleport>
 | 
			
		||||
 | 
			
		||||
    <div>
 | 
			
		||||
 | 
			
		||||
      <label class="col-form-label" for="selectJob">
 | 
			
		||||
@@ -35,6 +58,8 @@
 | 
			
		||||
          :searchable="true"
 | 
			
		||||
          :placeholder="$t('referrer.placeholder')"
 | 
			
		||||
          v-model="value"
 | 
			
		||||
          @select="updateReferrer"
 | 
			
		||||
          @remove="removeReferrer"
 | 
			
		||||
          :options="users"
 | 
			
		||||
          :select-label="$t('multiselect.select_label')"
 | 
			
		||||
          :deselect-label="$t('multiselect.deselect_label')"
 | 
			
		||||
@@ -78,16 +103,24 @@ import VueMultiselect from 'vue-multiselect';
 | 
			
		||||
import {makeFetch} from 'ChillMainAssets/lib/api/apiMethods';
 | 
			
		||||
import {mapState, mapGetters} from 'vuex';
 | 
			
		||||
import UserRenderBoxBadge from "ChillMainAssets/vuejs/_components/Entity/UserRenderBoxBadge";
 | 
			
		||||
import Modal from 'ChillMainAssets/vuejs/_components/Modal';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: "Referrer",
 | 
			
		||||
  components: {
 | 
			
		||||
    UserRenderBoxBadge,
 | 
			
		||||
    VueMultiselect,
 | 
			
		||||
    Modal
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      jobs: []
 | 
			
		||||
      jobs: [],
 | 
			
		||||
      modal: {
 | 
			
		||||
        showModal: false,
 | 
			
		||||
        modalDialogClass: "modal-dialog-scrollable modal-xl"
 | 
			
		||||
      },
 | 
			
		||||
      value: this.$store.state.accompanyingCourse.user,
 | 
			
		||||
      confirmed: false
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
@@ -118,22 +151,6 @@ export default {
 | 
			
		||||
            });
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    value: {
 | 
			
		||||
      get() {
 | 
			
		||||
        return this.$store.state.accompanyingCourse.user;
 | 
			
		||||
      },
 | 
			
		||||
      set(value) {
 | 
			
		||||
        console.log('set referrer', value);
 | 
			
		||||
        this.$store.dispatch('updateReferrer', value)
 | 
			
		||||
            .catch(({name, violations}) => {
 | 
			
		||||
              if (name === 'ValidationException' || name === 'AccessException') {
 | 
			
		||||
                violations.forEach((violation) => this.$toast.open({message: violation}));
 | 
			
		||||
              } else {
 | 
			
		||||
                this.$toast.open({message: 'An error occurred'})
 | 
			
		||||
              }
 | 
			
		||||
            });
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
    this.getJobs();
 | 
			
		||||
@@ -141,6 +158,7 @@ export default {
 | 
			
		||||
  methods: {
 | 
			
		||||
    updateReferrer(value) {
 | 
			
		||||
      this.value = value;
 | 
			
		||||
      this.toggleModal();
 | 
			
		||||
    },
 | 
			
		||||
    getJobs() {
 | 
			
		||||
      const url = '/api/1.0/main/user-job.json';
 | 
			
		||||
@@ -159,12 +177,38 @@ export default {
 | 
			
		||||
      const url = `/api/1.0/main/whoami.json`;
 | 
			
		||||
      makeFetch('GET', url)
 | 
			
		||||
          .then(user => {
 | 
			
		||||
            this.value = user
 | 
			
		||||
            // this.value = user
 | 
			
		||||
            this.updateReferrer(user);
 | 
			
		||||
          })
 | 
			
		||||
      /*.catch((error) => {
 | 
			
		||||
         commit('catchError', error);
 | 
			
		||||
         this.$toast.open({message: error.body})
 | 
			
		||||
      })*/
 | 
			
		||||
    },
 | 
			
		||||
    toggleModal() {
 | 
			
		||||
      this.modal.showModal = !this.modal.showModal;
 | 
			
		||||
    },
 | 
			
		||||
    confirmReferrer() {
 | 
			
		||||
      this.$store.dispatch('updateReferrer', this.value)
 | 
			
		||||
          .catch(({name, violations}) => {
 | 
			
		||||
            if (name === 'ValidationException' || name === 'AccessException') {
 | 
			
		||||
              violations.forEach((violation) => this.$toast.open({message: violation}));
 | 
			
		||||
            } else {
 | 
			
		||||
              this.$toast.open({message: 'An error occurred'})
 | 
			
		||||
            }
 | 
			
		||||
          });
 | 
			
		||||
      this.toggleModal()
 | 
			
		||||
    },
 | 
			
		||||
    removeReferrer() {
 | 
			
		||||
      console.log('remove option')  
 | 
			
		||||
      this.$store.dispatch('updateReferrer', null)
 | 
			
		||||
          .catch(({name, violations}) => {
 | 
			
		||||
            if (name === 'ValidationException' || name === 'AccessException') {
 | 
			
		||||
              violations.forEach((violation) => this.$toast.open({message: violation}));
 | 
			
		||||
            } else {
 | 
			
		||||
              this.$toast.open({message: 'An error occurred'})
 | 
			
		||||
            }
 | 
			
		||||
          });
 | 
			
		||||
    },
 | 
			
		||||
    cancelChange() {
 | 
			
		||||
      this.value = this.$store.state.accompanyingCourse.user
 | 
			
		||||
      this.toggleModal()
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -178,7 +178,7 @@ export default {
 | 
			
		||||
               body.civility = {type: 'chill_main_civility', id: payload.data.civility.id};
 | 
			
		||||
            }
 | 
			
		||||
            if (null !== payload.data.profession) {
 | 
			
		||||
               body.profession = {type: 'third_party_profession', id: payload.data.profession.id};
 | 
			
		||||
               body.profession = payload.data.profession;
 | 
			
		||||
            }
 | 
			
		||||
            // console.log('body', body);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -139,8 +139,10 @@ const appMessages = {
 | 
			
		||||
         set_a_scope: "indiquez au moins un service",
 | 
			
		||||
         sure: "Êtes-vous sûr ?",
 | 
			
		||||
         sure_description: "Une fois le changement confirmé, il ne sera plus possible de le remettre à l'état de brouillon !",
 | 
			
		||||
         sure_referrer: "Êtes-vous sûr de vouloir assigner ce parcours à <b>{referrer}</b>",
 | 
			
		||||
         ok: "Confirmer le parcours",
 | 
			
		||||
         delete: "Supprimer le parcours",
 | 
			
		||||
         ok_referrer: "Confirmer le référent",
 | 
			
		||||
         no_suggested_referrer: "Il n'y a aucun référent qui puisse être suggéré pour ce parcours. Vérifiez la localisation du parcours, les métiers et service indiqués. Si les données sont correctes, vous pouvez confirmer ce parcours.",
 | 
			
		||||
         one_suggested_referrer: "Un unique référent peut être suggéré pour ce parcours",
 | 
			
		||||
         choose_suggested_referrer: "Voulez-vous le désigner directement ?",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div class="container tpartycontainer">
 | 
			
		||||
      <div class="tparty-identification">
 | 
			
		||||
        <span v-if="item.result.profession" class="profession">{{ item.result.profession.name.fr }}</span>
 | 
			
		||||
        <span v-if="item.result.profession" class="profession">{{ item.result.profession }}</span>
 | 
			
		||||
        <span class="name">
 | 
			
		||||
          {{ item.result.text }} 
 | 
			
		||||
        </span>
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@
 | 
			
		||||
#  - itemBlocClass: [uniq|colored|extended]
 | 
			
		||||
#  - displayContent: [short|long] default: short
 | 
			
		||||
#  - displayAction: [true|false] default: false
 | 
			
		||||
#  - displayFontSmall: [true|false] default: false
 | 
			
		||||
#}
 | 
			
		||||
<div class="item-bloc{% if displayContent is defined %} {{ displayContent }}{% endif %}{% if itemBlocClass is defined %} {{ itemBlocClass }}{% endif %}">
 | 
			
		||||
 | 
			
		||||
@@ -83,7 +84,7 @@
 | 
			
		||||
                    {%- if w.referrers|length > 0 -%}
 | 
			
		||||
                        {% for u in w.referrers %}
 | 
			
		||||
                            <span class="wl-item">
 | 
			
		||||
                                {{ u|chill_entity_render_box }}
 | 
			
		||||
                                <span class="badge-user">{{ u|chill_entity_render_box }}</span>
 | 
			
		||||
                                {% if not loop.last %}, {% endif %}
 | 
			
		||||
                            </span>
 | 
			
		||||
                        {% endfor %}
 | 
			
		||||
@@ -110,7 +111,7 @@
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    {% if displayContent is not defined or displayContent == 'short' %}
 | 
			
		||||
        <div class="item-row column">
 | 
			
		||||
        <div class="item-row column{% if displayFontSmall is defined and displayFontSmall == true %} smallfont{% endif %}">
 | 
			
		||||
            {% include 'ChillPersonBundle:AccompanyingCourseWork:_objectifs_results_evaluations.html.twig' with {
 | 
			
		||||
                'displayContent': displayContent
 | 
			
		||||
            } %}
 | 
			
		||||
 
 | 
			
		||||
@@ -130,27 +130,20 @@
 | 
			
		||||
                        {% import "@ChillDocStore/Macro/macro.html.twig" as m %}
 | 
			
		||||
                        {% import "@ChillDocStore/Macro/macro_mimeicon.html.twig" as mm %}
 | 
			
		||||
 | 
			
		||||
                        <div class="download mb-4 container">
 | 
			
		||||
                            {% if e.documents|length > 0 %}
 | 
			
		||||
 | 
			
		||||
                        {% if e.documents|length > 0 %}
 | 
			
		||||
                            <table class="table mt-4 mx-auto">
 | 
			
		||||
                                {% for d in e.documents %}
 | 
			
		||||
                                    <div class="row">
 | 
			
		||||
                                        <div class="col text-start">
 | 
			
		||||
                                            {{ d.title }}
 | 
			
		||||
                                        </div>
 | 
			
		||||
                                        <div class="col-md-auto text-center">
 | 
			
		||||
                                            {{ mm.mimeIcon(d.storedObject.type) }}
 | 
			
		||||
                                        </div>
 | 
			
		||||
                                        <div class="col col-lg-4 text-end">
 | 
			
		||||
                                            {{ d.storedObject|chill_document_button_group(d.title, is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', w), {'small': true}) }}
 | 
			
		||||
                                        </div>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                    <tr class="border-0">
 | 
			
		||||
                                        <td class="border-0">{{ d.title }}</td>
 | 
			
		||||
                                        <td class="border-0">{{ mm.mimeIcon(d.storedObject.type) }}</td>
 | 
			
		||||
                                        <td class="border-0 text-end">{{ d.storedObject|chill_document_button_group(d.title, is_granted('CHILL_MAIN_ACCOMPANYING_PERIOD_WORK_UPDATE', w), {'small': true}) }}</td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                {% endfor %}
 | 
			
		||||
 | 
			
		||||
                            {% else %}
 | 
			
		||||
                                <span class="chill-no-data-statement">{{ 'No document found'|trans }}</span>
 | 
			
		||||
                            {% endif %}
 | 
			
		||||
                        </div>
 | 
			
		||||
                            </table>
 | 
			
		||||
                        {% else %}
 | 
			
		||||
                            <span class="chill-no-data-statement">{{ 'No document found'|trans }}</span>
 | 
			
		||||
                        {% endif %}
 | 
			
		||||
                        
 | 
			
		||||
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                </td>
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,7 @@
 | 
			
		||||
                    {% include '@ChillPerson/AccompanyingCourseWork/_item.html.twig' with {
 | 
			
		||||
                        'displayAction': true,
 | 
			
		||||
                        'displayContent': 'short',
 | 
			
		||||
                        'displayFontSmall': true,
 | 
			
		||||
                        'itemBlocClass': ''
 | 
			
		||||
                    } %}
 | 
			
		||||
                {% endfor %}
 | 
			
		||||
 
 | 
			
		||||
@@ -33,8 +33,10 @@
 | 
			
		||||
                        <span class="item-key">{{ 'Referrers'|trans ~ ' : ' }}</span>
 | 
			
		||||
                        {% for u in w.referrers %}
 | 
			
		||||
                            <span class="badge-user">{{ u|chill_entity_render_box }}</span>
 | 
			
		||||
                            {% if not loop.last %}, {% endif %}
 | 
			
		||||
                        {% endfor %}
 | 
			
		||||
                        {% if w.referrers|length == 0 %}
 | 
			
		||||
                            <span class="chill-no-data-statement">{{ 'Not given'|trans }}</span>
 | 
			
		||||
                        {% endif %}
 | 
			
		||||
                    </li>
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                    <li class="associated-persons">
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@
 | 
			
		||||
#}{{ period.user.label }},
 | 
			
		||||
 | 
			
		||||
L'usager {{ oldPersonLocation|chill_entity_render_string }} a déménagé.
 | 
			
		||||
{{ app.user|chill_entity_render_string }} a enregistré ce déménagement.
 | 
			
		||||
 | 
			
		||||
Son adresse était utilisée pour localiser le parcours n°{{ period.id }}, dont vous êtes
 | 
			
		||||
le référent.
 | 
			
		||||
 
 | 
			
		||||
@@ -69,7 +69,7 @@
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="wl-col list">
 | 
			
		||||
                            <div class="user">
 | 
			
		||||
                                {{ acp.user|chill_entity_render_box }}
 | 
			
		||||
                                <span class="badge-user">{{ acp.user|chill_entity_render_box }}</span>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@
 | 
			
		||||
            </h2>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="item-row column">
 | 
			
		||||
            <table class="obj-res-eval my-3" style="font-size: 110% !important;">
 | 
			
		||||
            <table class="obj-res-eval my-3">
 | 
			
		||||
                <thead>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <th class="eval">
 | 
			
		||||
 
 | 
			
		||||
@@ -49,7 +49,7 @@
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="item-row column">
 | 
			
		||||
                <table class="obj-res-eval my-3" style="font-size: 110% !important;">
 | 
			
		||||
                <table class="obj-res-eval my-3">
 | 
			
		||||
                    <thead>
 | 
			
		||||
                        <tr>
 | 
			
		||||
                            <th class="eval">
 | 
			
		||||
 
 | 
			
		||||
@@ -76,8 +76,17 @@ class SimilarPersonMatcher
 | 
			
		||||
 | 
			
		||||
        $qb->select('p')
 | 
			
		||||
            ->from(Person::class, 'p')
 | 
			
		||||
            ->join('p.centerHistory', 'center_history')
 | 
			
		||||
            ->where('SIMILARITY(p.fullnameCanonical, UNACCENT(LOWER(:fullName))) >= :precision')
 | 
			
		||||
            ->andWhere($qb->expr()->in('p.center', ':centers'));
 | 
			
		||||
            ->andWhere($qb->expr()->in('center_history.center', ':centers'))
 | 
			
		||||
            ->andWhere($qb->expr()->andX(
 | 
			
		||||
               $qb->expr()->lte('center_history.startDate', 'CURRENT_DATE()'),
 | 
			
		||||
                $qb->expr()->orX(
 | 
			
		||||
                    $qb->expr()->isNull('center_history.endDate'),
 | 
			
		||||
                    $qb->expr()->gt('center_history.endDate', 'CURRENT_DATE()')
 | 
			
		||||
                )
 | 
			
		||||
            ))
 | 
			
		||||
        ;
 | 
			
		||||
 | 
			
		||||
        $qb
 | 
			
		||||
            ->setParameter('fullName', $this->personRender->renderString($person, []))
 | 
			
		||||
@@ -117,7 +126,6 @@ class SimilarPersonMatcher
 | 
			
		||||
                $qb->setParameter('fullName', $this->personRender->renderString($person, []));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        dump($qb->getQuery());
 | 
			
		||||
        return $qb->getQuery()->getResult();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -204,7 +204,7 @@ class AccompanyingPeriodContext implements
 | 
			
		||||
        $options = $template->getOptions();
 | 
			
		||||
 | 
			
		||||
        $data = [];
 | 
			
		||||
        $data = array_merge($data, $this->baseContextData->getData());
 | 
			
		||||
        $data = array_merge($data, $this->baseContextData->getData($contextGenerationData['creator'] ?? null));
 | 
			
		||||
        $data['course'] = $this->normalizer->normalize($entity, 'docgen', ['docgen:expects' => AccompanyingPeriod::class, 'groups' => 'docgen:read']);
 | 
			
		||||
 | 
			
		||||
        foreach (['mainPerson', 'person1', 'person2'] as $k) {
 | 
			
		||||
 
 | 
			
		||||
@@ -165,7 +165,7 @@ final class PersonContext implements PersonContextInterface
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $data = [];
 | 
			
		||||
        $data = array_merge($data, $this->baseContextData->getData());
 | 
			
		||||
        $data = array_merge($data, $this->baseContextData->getData($contextGenerationData['creator'] ?? null));
 | 
			
		||||
        $data['person'] = $this->normalizer->normalize($entity, 'docgen', [
 | 
			
		||||
            'docgen:expects' => Person::class,
 | 
			
		||||
            'groups' => ['docgen:read'],
 | 
			
		||||
 
 | 
			
		||||
@@ -24,10 +24,36 @@ use Prophecy\Argument;
 | 
			
		||||
use Prophecy\PhpUnit\ProphecyTrait;
 | 
			
		||||
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
 | 
			
		||||
 | 
			
		||||
class ParticipationOverlapValidatorTest extends ConstraintValidatorTestCase
 | 
			
		||||
/**
 | 
			
		||||
 * @internal
 | 
			
		||||
 * @coversNothing
 | 
			
		||||
 */
 | 
			
		||||
final class ParticipationOverlapValidatorTest extends ConstraintValidatorTestCase
 | 
			
		||||
{
 | 
			
		||||
    use ProphecyTrait;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return mixed
 | 
			
		||||
     */
 | 
			
		||||
    public function getConstraint()
 | 
			
		||||
    {
 | 
			
		||||
        return new ParticipationOverlap();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testOneParticipation()
 | 
			
		||||
    {
 | 
			
		||||
        $period = new AccompanyingPeriod();
 | 
			
		||||
        $person = new Person();
 | 
			
		||||
 | 
			
		||||
        $collection = new ArrayCollection([
 | 
			
		||||
            new AccompanyingPeriodParticipation($period, $person),
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        $this->validator->validate($collection, $this->getConstraint());
 | 
			
		||||
 | 
			
		||||
        $this->assertNoViolation();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function createValidator()
 | 
			
		||||
    {
 | 
			
		||||
        $personRender = $this->prophesize(PersonRenderInterface::class);
 | 
			
		||||
@@ -37,26 +63,4 @@ class ParticipationOverlapValidatorTest extends ConstraintValidatorTestCase
 | 
			
		||||
 | 
			
		||||
        return new ParticipationOverlapValidator($personRender->reveal(), $thirdPartyRender->reveal());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testOneParticipation()
 | 
			
		||||
    {
 | 
			
		||||
        $period = new AccompanyingPeriod();
 | 
			
		||||
        $person = new Person();
 | 
			
		||||
 | 
			
		||||
        $collection = new ArrayCollection([
 | 
			
		||||
            new AccompanyingPeriodParticipation($period, $person)
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        $this->validator->validate($collection, $this->getConstraint());
 | 
			
		||||
 | 
			
		||||
        $this->assertNoViolation();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return mixed
 | 
			
		||||
     */
 | 
			
		||||
    public function getConstraint()
 | 
			
		||||
    {
 | 
			
		||||
        return new ParticipationOverlap();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -54,7 +54,7 @@ class AccompanyingPeriodValidityValidator extends ConstraintValidator
 | 
			
		||||
        $activities = $this->activityRepository->findBy(['accompanyingPeriod' => $period]);
 | 
			
		||||
 | 
			
		||||
        foreach ($activities as $activity) {
 | 
			
		||||
            $socialIssues = $activity->getSocialIssues()->toArray();
 | 
			
		||||
            $socialIssues = array_merge($socialIssues, $activity->getSocialIssues()->toArray());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        foreach ($period->getWorks() as $work) {
 | 
			
		||||
@@ -64,7 +64,7 @@ class AccompanyingPeriodValidityValidator extends ConstraintValidator
 | 
			
		||||
        $socialIssuesByKey = [];
 | 
			
		||||
 | 
			
		||||
        foreach ($socialIssues as $si) {
 | 
			
		||||
            $socialIssuesByKey[$si->getId()] = $si;
 | 
			
		||||
            $socialIssuesByKey[spl_object_hash($si)] = $si;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $periodIssuesWithAncestors = [];
 | 
			
		||||
@@ -75,7 +75,7 @@ class AccompanyingPeriodValidityValidator extends ConstraintValidator
 | 
			
		||||
                $periodIssuesWithAncestors,
 | 
			
		||||
                array_map(
 | 
			
		||||
                    static function (SocialIssue $si) {
 | 
			
		||||
                        return $si->getId();
 | 
			
		||||
                        return spl_object_hash($si);
 | 
			
		||||
                    },
 | 
			
		||||
                    $si->getAncestors(true)
 | 
			
		||||
                )
 | 
			
		||||
 
 | 
			
		||||
@@ -125,7 +125,7 @@ address_country_code: Landscode
 | 
			
		||||
'Alreay existing person': 'Reeds bestaand persoonsdossier'
 | 
			
		||||
'Add the person': 'Persoon toevoegen'
 | 
			
		||||
'Add the person and create an accompanying period': "Persoon & hulpverleningstraject aanmaken"
 | 
			
		||||
'Add the person and create a household': "Persoon & gezin aanmaken"
 | 
			
		||||
'Add the person and create a household': "Persoon & huishouden aanmaken"
 | 
			
		||||
Show person: Toon persoonsdossier
 | 
			
		||||
'Confirm the creation': 'Aanmaak dossier bevestigen'
 | 
			
		||||
'You will create this person': 'U zal het volgende dossier aanmaken'
 | 
			
		||||
@@ -177,9 +177,9 @@ An accompanying period ends: Een hulpverleningstraject loopt op zijn einde
 | 
			
		||||
An accompanying period starts: Een hulpverleningstraject gaat van start
 | 
			
		||||
Any accompanying periods are open: Geen enkel hulpverleningstraject open
 | 
			
		||||
An accompanying period is open: Een hulpverleningstraject staat open
 | 
			
		||||
Accompanying period list: Hulpverleningstraject
 | 
			
		||||
Accompanying period list: Hulpverleningstrajecten
 | 
			
		||||
Accompanying period list for person: Hulpverleningstrajecten van persoon
 | 
			
		||||
Accompanying period: Hulpverleningstraject
 | 
			
		||||
Accompanying period: Hulpverleningstrajecten
 | 
			
		||||
Any accompanying period: Geen enkel hulpverleningstraject
 | 
			
		||||
period: Hulpverleningstraject
 | 
			
		||||
New accompanying course: Nieuw hulpverleningstraject
 | 
			
		||||
@@ -215,8 +215,8 @@ No resources: "Geen hulpverlening partners"
 | 
			
		||||
Persons associated: Betrokken personen
 | 
			
		||||
Referrer: Doorverwijzer
 | 
			
		||||
Referrers: Doorverwijzers
 | 
			
		||||
Some peoples does not belong to any household currently. Add them to an household soon: Sommige personen maken nog geen deel uit van een gezin. Voeg ze zo snel mogelijk aan gezin toe.
 | 
			
		||||
Add to household now: Toevoegen aan een gezin
 | 
			
		||||
Some peoples does not belong to any household currently. Add them to an household soon: Sommige personen maken nog geen deel uit van een huishouden. Voeg ze zo snel mogelijk aan huishouden toe.
 | 
			
		||||
Add to household now: Toevoegen aan een huishouden
 | 
			
		||||
Any resource for this accompanying course: Geen enkele hulpverlening partner
 | 
			
		||||
course.draft: Ontwerp
 | 
			
		||||
course.closed: Afgesloten
 | 
			
		||||
@@ -458,7 +458,7 @@ Accompanying course location: Locatie van hulpverleningstraject
 | 
			
		||||
This course is located by: Locatie bij
 | 
			
		||||
This course has a temporarily location: Voorlopige locatie
 | 
			
		||||
Choose a person to locate by: Adres van persoon toewijzen
 | 
			
		||||
Associate at least one member with an household, and set an address to this household: Associeer minstens één betrokken persoon in dit hulpverleningstraject met een gezin en wijs een adres toe aan dit gezin.
 | 
			
		||||
Associate at least one member with an household, and set an address to this household: Associeer minstens één betrokken persoon in dit hulpverleningstraject met een huishouden en wijs een adres toe aan dit huishouden.
 | 
			
		||||
Locate by: Adres toewijzen
 | 
			
		||||
fix it: Aanvullen
 | 
			
		||||
accompanying_course:
 | 
			
		||||
@@ -480,23 +480,23 @@ accompanying_course_comment:
 | 
			
		||||
Read more: Meer lezen..
 | 
			
		||||
 | 
			
		||||
# Household
 | 
			
		||||
Household: Gezin
 | 
			
		||||
Household: Huishouden
 | 
			
		||||
Summary: Samenvatting
 | 
			
		||||
Members: Gezinsleden
 | 
			
		||||
Members: Leden huishouden
 | 
			
		||||
Addresses: Addressen
 | 
			
		||||
Move household: Nieuwe verhuis
 | 
			
		||||
Addresses history for household: Historiek adressen
 | 
			
		||||
Household accompanying period: Hulpverleningstrajecten van gezin
 | 
			
		||||
Household summary: Samenvatting gezin
 | 
			
		||||
Edit household address: Adres gezin bijwerken
 | 
			
		||||
Show household: Gezin bekijken
 | 
			
		||||
Back to household: Terugkeren naar gezin
 | 
			
		||||
Remove household composition: Gezinssamenstelling verwijderen
 | 
			
		||||
Are you sure you want to remove this composition?: Bent u zeker deze gezinssamenstelling te willen verwijderen?
 | 
			
		||||
Concerns household n°%id%: Betrokken gezin n°%id%
 | 
			
		||||
Composition: Gezinssamenstelling
 | 
			
		||||
Household accompanying period: Hulpverleningstrajecten van huishouden
 | 
			
		||||
Household summary: Samenvatting huishouden
 | 
			
		||||
Edit household address: Adres huishouden bijwerken
 | 
			
		||||
Show household: huishouden bekijken
 | 
			
		||||
Back to household: Terugkeren naar huishouden
 | 
			
		||||
Remove household composition: huishoudenssamenstelling verwijderen
 | 
			
		||||
Are you sure you want to remove this composition?: Bent u zeker deze huishoudenssamenstelling te willen verwijderen?
 | 
			
		||||
Concerns household n°%id%: Betrokken huishouden n°%id%
 | 
			
		||||
Composition: huishoudenssamenstelling
 | 
			
		||||
Budget: Budget
 | 
			
		||||
The composition has been successfully removed.: De gezinssamenstelling werd verwijdert.
 | 
			
		||||
The composition has been successfully removed.: De huishoudenssamenstelling werd verwijdert.
 | 
			
		||||
 | 
			
		||||
# accompanying course work
 | 
			
		||||
Accompanying Course Actions: Hulpverleningsmaatregelen
 | 
			
		||||
@@ -560,16 +560,16 @@ You are getting a notification for a period you are not allowed to see: De notif
 | 
			
		||||
This is the minimal period details: Hulpverleningstraject n°
 | 
			
		||||
 | 
			
		||||
household_composition:
 | 
			
		||||
    No composition yet: Geen enkele gezinssamenstelling toegewezen
 | 
			
		||||
    Compositions: Gezinssamenstelling
 | 
			
		||||
    No composition yet: Geen enkele huishoudenssamenstelling toegewezen
 | 
			
		||||
    Compositions: huishoudenssamenstelling
 | 
			
		||||
    endDate: Einddatum
 | 
			
		||||
    numberOfChildren: Aantal kinderen in het gezin
 | 
			
		||||
    Household composition: Gezinssamenstelling
 | 
			
		||||
    Composition added: Informatie over de gezinssamenstelling toegevoegd
 | 
			
		||||
    Currently no composition: Geen enkele gezinssamenstelling toegewezen
 | 
			
		||||
    Add a composition: Een gezinssamenstelling toevoegen
 | 
			
		||||
    Update composition: Gezinssamenstelling bijwerken
 | 
			
		||||
    Create: Een nieuwe gezinssamenstelling toewijzen
 | 
			
		||||
    numberOfChildren: Aantal kinderen in het huishouden
 | 
			
		||||
    Household composition: huishoudenssamenstelling
 | 
			
		||||
    Composition added: Informatie over de huishoudenssamenstelling toegevoegd
 | 
			
		||||
    Currently no composition: Geen enkele huishoudenssamenstelling toegewezen
 | 
			
		||||
    Add a composition: Een huishoudenssamenstelling toevoegen
 | 
			
		||||
    Update composition: huishoudenssamenstelling bijwerken
 | 
			
		||||
    Create: Een nieuwe huishoudenssamenstelling toewijzen
 | 
			
		||||
 | 
			
		||||
# docgen
 | 
			
		||||
Linked evaluations: Gerelateerde evaluaties
 | 
			
		||||
 
 | 
			
		||||
@@ -11,12 +11,15 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Chill\ReportBundle\Controller;
 | 
			
		||||
 | 
			
		||||
use Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter;
 | 
			
		||||
use Chill\MainBundle\Pagination\PaginatorFactory;
 | 
			
		||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
 | 
			
		||||
use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface;
 | 
			
		||||
use Chill\PersonBundle\Entity\Person;
 | 
			
		||||
use Chill\PersonBundle\Privacy\PrivacyEvent;
 | 
			
		||||
use Chill\ReportBundle\Entity\Report;
 | 
			
		||||
use Chill\ReportBundle\Form\ReportType;
 | 
			
		||||
use Chill\ReportBundle\Security\Authorization\ReportVoter;
 | 
			
		||||
use DateTime;
 | 
			
		||||
use RuntimeException;
 | 
			
		||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
 | 
			
		||||
@@ -25,7 +28,7 @@ use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Request;
 | 
			
		||||
use Symfony\Component\Security\Core\Role\Role;
 | 
			
		||||
 | 
			
		||||
use Symfony\Component\Security\Core\Security;
 | 
			
		||||
use function count;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -48,17 +51,25 @@ class ReportController extends AbstractController
 | 
			
		||||
     */
 | 
			
		||||
    protected $paginator;
 | 
			
		||||
 | 
			
		||||
    private CenterResolverManagerInterface $centerResolverManager;
 | 
			
		||||
 | 
			
		||||
    private Security $security;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * ReportController constructor.
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        EventDispatcherInterface $eventDispatcher,
 | 
			
		||||
        AuthorizationHelper $authorizationHelper,
 | 
			
		||||
        PaginatorFactory $paginator
 | 
			
		||||
        PaginatorFactory $paginator,
 | 
			
		||||
        CenterResolverManagerInterface $centerResolverManager,
 | 
			
		||||
        Security $security
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->eventDispatcher = $eventDispatcher;
 | 
			
		||||
        $this->authorizationHelper = $authorizationHelper;
 | 
			
		||||
        $this->paginator = $paginator;
 | 
			
		||||
        $this->centerResolverManager = $centerResolverManager;
 | 
			
		||||
        $this->security = $security;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -120,7 +131,7 @@ class ReportController extends AbstractController
 | 
			
		||||
                    ->trans('The form is not valid. The report has not been created !')
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
        return $this->render('ChillReportBundle:Report:new.html.twig', [
 | 
			
		||||
        return $this->render('@ChillReport/Report/new.html.twig', [
 | 
			
		||||
            'entity' => $entity,
 | 
			
		||||
            'form' => $form->createView(),
 | 
			
		||||
            'person' => $person,
 | 
			
		||||
@@ -140,7 +151,7 @@ class ReportController extends AbstractController
 | 
			
		||||
        $em = $this->getDoctrine()->getManager();
 | 
			
		||||
 | 
			
		||||
        /** @var Report $report */
 | 
			
		||||
        $report = $em->getRepository('ChillReportBundle:Report')->find($report_id);
 | 
			
		||||
        $report = $em->getRepository(Report::class)->find($report_id);
 | 
			
		||||
 | 
			
		||||
        if (!$report) {
 | 
			
		||||
            throw $this->createNotFoundException(
 | 
			
		||||
@@ -189,7 +200,7 @@ class ReportController extends AbstractController
 | 
			
		||||
        $cFGroup = $em->getRepository(\Chill\CustomFieldsBundle\Entity\CustomFieldsGroup::class)->find($cf_group_id);
 | 
			
		||||
        $reports = $em->getRepository('ChillReportBundle:Report')->findByCFGroup($cFGroup);
 | 
			
		||||
 | 
			
		||||
        $response = $this->render('ChillReportBundle:Report:export.csv.twig', [
 | 
			
		||||
        $response = $this->render('@ChillReport/Report/export.csv.twig', [
 | 
			
		||||
            'reports' => $reports,
 | 
			
		||||
            'cf_group' => $cFGroup,
 | 
			
		||||
        ]);
 | 
			
		||||
@@ -218,9 +229,9 @@ class ReportController extends AbstractController
 | 
			
		||||
 | 
			
		||||
        $reachableScopes = $this->authorizationHelper
 | 
			
		||||
            ->getReachableScopes(
 | 
			
		||||
                $this->getUser(),
 | 
			
		||||
                new Role('CHILL_REPORT_SEE'),
 | 
			
		||||
                $person->getCenter()
 | 
			
		||||
                $this->security->getUser(),
 | 
			
		||||
                ReportVoter::SEE,
 | 
			
		||||
                $this->centerResolverManager->resolveCenters($person)
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
        $total = $em
 | 
			
		||||
@@ -298,7 +309,7 @@ class ReportController extends AbstractController
 | 
			
		||||
 | 
			
		||||
        $form = $this->createCreateForm($entity, $person, $cFGroup);
 | 
			
		||||
 | 
			
		||||
        return $this->render('ChillReportBundle:Report:new.html.twig', [
 | 
			
		||||
        return $this->render('@ChillReport/Report/new.html.twig', [
 | 
			
		||||
            'entity' => $entity,
 | 
			
		||||
            'form' => $form->createView(),
 | 
			
		||||
            'person' => $person,
 | 
			
		||||
@@ -515,7 +526,7 @@ class ReportController extends AbstractController
 | 
			
		||||
 | 
			
		||||
        $person = $em->getRepository(\Chill\PersonBundle\Entity\Person::class)->find($person_id);
 | 
			
		||||
 | 
			
		||||
        $entity = $em->getRepository('ChillReportBundle:Report')->find($report_id);
 | 
			
		||||
        $entity = $em->getRepository(Report::class)->find($report_id);
 | 
			
		||||
 | 
			
		||||
        if (!$entity || !$person) {
 | 
			
		||||
            throw $this->createNotFoundException(
 | 
			
		||||
@@ -532,7 +543,7 @@ class ReportController extends AbstractController
 | 
			
		||||
        ]);
 | 
			
		||||
        $this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
 | 
			
		||||
 | 
			
		||||
        return $this->render('ChillReportBundle:Report:view.html.twig', [
 | 
			
		||||
        return $this->render('@ChillReport/Report/view.html.twig', [
 | 
			
		||||
            'entity' => $entity,
 | 
			
		||||
            'person' => $person,
 | 
			
		||||
        ]);
 | 
			
		||||
@@ -578,8 +589,8 @@ class ReportController extends AbstractController
 | 
			
		||||
            ),
 | 
			
		||||
            'method' => 'PUT',
 | 
			
		||||
            'cFGroup' => $entity->getCFGroup(),
 | 
			
		||||
            'role' => new Role('CHILL_REPORT_UPDATE'),
 | 
			
		||||
            'center' => $entity->getPerson()->getCenter(),
 | 
			
		||||
            //'role' => ReportVoter::UPDATE,
 | 
			
		||||
            //'center' => $this->centerResolverManager->resolveCenters($entity->getPerson()),
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -74,15 +74,15 @@ class ReportType extends AbstractType
 | 
			
		||||
                    'group' => $options['cFGroup'], ]
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
        $this->appendScopeChoices(
 | 
			
		||||
            $builder,
 | 
			
		||||
            $options['role'],
 | 
			
		||||
            $options['center'],
 | 
			
		||||
            $this->user,
 | 
			
		||||
            $this->authorizationHelper,
 | 
			
		||||
            $this->translatableStringHelper,
 | 
			
		||||
            $this->om
 | 
			
		||||
        );
 | 
			
		||||
        //$this->appendScopeChoices(
 | 
			
		||||
        //    $builder,
 | 
			
		||||
        //    $options['role'],
 | 
			
		||||
        //    $options['center'],
 | 
			
		||||
        //    $this->user,
 | 
			
		||||
        //    $this->authorizationHelper,
 | 
			
		||||
        //    $this->translatableStringHelper,
 | 
			
		||||
        //    $this->om
 | 
			
		||||
        //);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function configureOptions(OptionsResolver $resolver)
 | 
			
		||||
@@ -97,7 +97,7 @@ class ReportType extends AbstractType
 | 
			
		||||
 | 
			
		||||
        $resolver->setAllowedTypes('cFGroup', 'Chill\CustomFieldsBundle\Entity\CustomFieldsGroup');
 | 
			
		||||
 | 
			
		||||
        $this->appendScopeChoicesOptions($resolver);
 | 
			
		||||
        //$this->appendScopeChoicesOptions($resolver);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,9 @@
 | 
			
		||||
 | 
			
		||||
    {{ form_row(edit_form.user) }}
 | 
			
		||||
    {{ form_row(edit_form.date) }}
 | 
			
		||||
    {#
 | 
			
		||||
    {{ form_row(edit_form.scope) }}
 | 
			
		||||
    #}
 | 
			
		||||
    {{ form_row(edit_form.cFData) }}
 | 
			
		||||
 | 
			
		||||
    {{ form_widget(edit_form) }}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,5 @@
 | 
			
		||||
services:
 | 
			
		||||
    Chill\ReportBundle\Controller\ReportController:
 | 
			
		||||
        arguments:
 | 
			
		||||
            $eventDispatcher: '@Symfony\Component\EventDispatcher\EventDispatcherInterface'
 | 
			
		||||
            $authorizationHelper: '@Chill\MainBundle\Security\Authorization\AuthorizationHelper'
 | 
			
		||||
            $paginator: '@Chill\MainBundle\Pagination\PaginatorFactory'
 | 
			
		||||
        autowire: true
 | 
			
		||||
        autoconfigure: true
 | 
			
		||||
        tags: ['controller.service_arguments']
 | 
			
		||||
 
 | 
			
		||||
@@ -151,21 +151,6 @@ class ChillThirdPartyExtension extends Extension implements PrependExtensionInte
 | 
			
		||||
                        ],
 | 
			
		||||
                    ],
 | 
			
		||||
                ],
 | 
			
		||||
                [
 | 
			
		||||
                    'class' => \Chill\ThirdPartyBundle\Entity\ThirdPartyProfession::class,
 | 
			
		||||
                    // 'controller' => \Chill\MainBundle\Controller\ProfessionApiController::class,
 | 
			
		||||
                    'name' => 'profession',
 | 
			
		||||
                    'base_path' => '/api/1.0/thirdparty/professions',
 | 
			
		||||
                    'base_role' => 'ROLE_USER',
 | 
			
		||||
                    'actions' => [
 | 
			
		||||
                        '_index' => [
 | 
			
		||||
                            'methods' => [
 | 
			
		||||
                                Request::METHOD_GET => true,
 | 
			
		||||
                                Request::METHOD_HEAD => true,
 | 
			
		||||
                            ],
 | 
			
		||||
                        ],
 | 
			
		||||
                    ],
 | 
			
		||||
                ],
 | 
			
		||||
            ],
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -250,14 +250,11 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * [fr] Qualité.
 | 
			
		||||
     *
 | 
			
		||||
     * @var ThirdPartyProfession
 | 
			
		||||
     * @ORM\ManyToOne(targetEntity="Chill\ThirdPartyBundle\Entity\ThirdPartyProfession")
 | 
			
		||||
     * ORM\JoinColumn(name="profession", referencedColumnName="id", nullable=true)
 | 
			
		||||
     * @ORM\Column(name="profession", type="text", nullable=false)
 | 
			
		||||
     * @Groups({"read", "write", "docgen:read", "docgen:read:3party:parent"})
 | 
			
		||||
     * @Context(normalizationContext={"groups": "docgen:read"}, groups={"docgen:read:3party:parent"})
 | 
			
		||||
     */
 | 
			
		||||
    private ?ThirdPartyProfession $profession = null;
 | 
			
		||||
    private string $profession = '';
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @ORM\Column(name="telephone", type="phone_number", nullable=true)
 | 
			
		||||
@@ -491,9 +488,9 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return ThirdPartyProfession
 | 
			
		||||
     * @return string
 | 
			
		||||
     */
 | 
			
		||||
    public function getProfession(): ?ThirdPartyProfession
 | 
			
		||||
    public function getProfession(): string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->profession;
 | 
			
		||||
    }
 | 
			
		||||
@@ -808,12 +805,9 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return $this
 | 
			
		||||
     */
 | 
			
		||||
    public function setProfession(?ThirdPartyProfession $profession): ThirdParty
 | 
			
		||||
    public function setProfession(?string $profession): self
 | 
			
		||||
    {
 | 
			
		||||
        $this->profession = $profession;
 | 
			
		||||
        $this->profession = (string) $profession;
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -20,14 +20,10 @@ use Chill\MainBundle\Form\Type\PickCivilityType;
 | 
			
		||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
 | 
			
		||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
 | 
			
		||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
 | 
			
		||||
use Chill\ThirdPartyBundle\Entity\ThirdPartyProfession;
 | 
			
		||||
use Chill\ThirdPartyBundle\Form\Type\PickThirdPartyTypeCategoryType;
 | 
			
		||||
use Chill\ThirdPartyBundle\Security\Voter\ThirdPartyVoter;
 | 
			
		||||
use Chill\ThirdPartyBundle\ThirdPartyType\ThirdPartyTypeManager;
 | 
			
		||||
use Doctrine\ORM\EntityManagerInterface;
 | 
			
		||||
use Doctrine\ORM\EntityRepository;
 | 
			
		||||
use Doctrine\ORM\QueryBuilder;
 | 
			
		||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\Form\AbstractType;
 | 
			
		||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
 | 
			
		||||
@@ -111,18 +107,10 @@ class ThirdPartyType extends AbstractType
 | 
			
		||||
                    'placeholder' => 'thirdparty.choose civility',
 | 
			
		||||
                    'required' => false,
 | 
			
		||||
                ])
 | 
			
		||||
                ->add('profession', EntityType::class, [
 | 
			
		||||
                ->add('profession', TextType::class, [
 | 
			
		||||
                    'label' => 'thirdparty.Profession',
 | 
			
		||||
                    'class' => ThirdPartyProfession::class,
 | 
			
		||||
                    'choice_label' => function (ThirdPartyProfession $profession): string {
 | 
			
		||||
                        return $this->translatableStringHelper->localize($profession->getName());
 | 
			
		||||
                    },
 | 
			
		||||
                    'query_builder' => static function (EntityRepository $er): QueryBuilder {
 | 
			
		||||
                        return $er->createQueryBuilder('p')
 | 
			
		||||
                            ->where('p.active = true');
 | 
			
		||||
                    },
 | 
			
		||||
                    'placeholder' => 'thirdparty.choose profession',
 | 
			
		||||
                    'required' => false,
 | 
			
		||||
                    'empty_data' => '',
 | 
			
		||||
                ])
 | 
			
		||||
                ->add('contactDataAnonymous', CheckboxType::class, [
 | 
			
		||||
                    'required' => false,
 | 
			
		||||
 
 | 
			
		||||
@@ -36,7 +36,7 @@
 | 
			
		||||
                <ul class="list-content fa-ul">
 | 
			
		||||
                    <li v-if="getProfession.length > 0">
 | 
			
		||||
                        <i class="fa fa-li fa-id-card"></i>
 | 
			
		||||
                        <p><span v-for="p in getProfession" :key="p" class="list-item list-professions">{{ p[0].toUpperCase() + p.slice(1).toLowerCase() }}</span></p>
 | 
			
		||||
                        <p><span>{{ getProfession[0] }}</span></p>
 | 
			
		||||
                    </li>
 | 
			
		||||
                    <li v-if="hasParent">
 | 
			
		||||
                        <i class="fa fa-li fa-hand-o-right"></i>
 | 
			
		||||
@@ -136,13 +136,14 @@ export default {
 | 
			
		||||
        getProfession() {
 | 
			
		||||
            let profession = []
 | 
			
		||||
            if (this.hasParent && this.thirdparty.profession) {
 | 
			
		||||
                profession.push(this.thirdparty.profession.name.fr)
 | 
			
		||||
                profession.push(this.thirdparty.profession)
 | 
			
		||||
                return profession;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!this.hasParent && this.thirdparty.category) {
 | 
			
		||||
                profession = this.thirdparty.category.map((category) => category.text);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return profession;
 | 
			
		||||
        }
 | 
			
		||||
        /* TODO need backend normalizer to serve children without circular reference
 | 
			
		||||
 
 | 
			
		||||
@@ -73,13 +73,13 @@
 | 
			
		||||
                  <option v-for="civility in civilities" :key="civility.id" :value="civility">{{ civility.name.fr }}</option>
 | 
			
		||||
               </select>
 | 
			
		||||
            </div>
 | 
			
		||||
            <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>
 | 
			
		||||
                  <option v-for="profession in professions" :key="profession.id" :value="profession">{{ profession.name.fr }}</option>
 | 
			
		||||
               </select>
 | 
			
		||||
            </div>
 | 
			
		||||
           <div class="input-group mb-3 input-section">
 | 
			
		||||
             <input class="form-control form-control-lg"
 | 
			
		||||
                    v-model="thirdparty.profession"
 | 
			
		||||
                    v-bind:placeholder="$t('thirdparty.profession')"
 | 
			
		||||
                    v-bind:aria-label="$t('thirdparty.profession')"
 | 
			
		||||
                    aria-describedby="profession" />
 | 
			
		||||
           </div>
 | 
			
		||||
         </div>
 | 
			
		||||
         <div class="child-info">
 | 
			
		||||
            <div class="input-section">
 | 
			
		||||
@@ -192,9 +192,8 @@ export default {
 | 
			
		||||
            name: '',
 | 
			
		||||
            telephone: '',
 | 
			
		||||
            civility: null,
 | 
			
		||||
            profession: null,
 | 
			
		||||
            profession: '',
 | 
			
		||||
         },
 | 
			
		||||
         professions: [],
 | 
			
		||||
         civilities: [],
 | 
			
		||||
         addAddress: {
 | 
			
		||||
            options: {
 | 
			
		||||
@@ -274,18 +273,6 @@ export default {
 | 
			
		||||
                  this.$toast.open({message: error.body})
 | 
			
		||||
               })
 | 
			
		||||
      },
 | 
			
		||||
      loadProfessions() {
 | 
			
		||||
         const url = `/api/1.0/thirdparty/professions.json`;
 | 
			
		||||
         return makeFetch('GET', url)
 | 
			
		||||
               .then(response => {
 | 
			
		||||
                  this.$data.professions = response.results;
 | 
			
		||||
                  return Promise.resolve();
 | 
			
		||||
               })
 | 
			
		||||
               .catch((error) => {
 | 
			
		||||
                  console.log(error)
 | 
			
		||||
                  this.$toast.open({message: error.body})
 | 
			
		||||
               })
 | 
			
		||||
      },
 | 
			
		||||
      submitAddress(payload) {
 | 
			
		||||
         console.log('submitAddress', payload);
 | 
			
		||||
          if (typeof payload.addressId !== 'undefined') { // <--
 | 
			
		||||
@@ -311,7 +298,6 @@ export default {
 | 
			
		||||
   },
 | 
			
		||||
   mounted() {
 | 
			
		||||
      let dependencies = [];
 | 
			
		||||
      dependencies.push(this.loadProfessions());
 | 
			
		||||
      dependencies.push(this.loadCivilities());
 | 
			
		||||
      if (this.action !== 'create') {
 | 
			
		||||
         if (this.id) {
 | 
			
		||||
 
 | 
			
		||||
@@ -112,14 +112,3 @@ paths:
 | 
			
		||||
          description: "OK"
 | 
			
		||||
        422:
 | 
			
		||||
          description: "Object with validation errors"
 | 
			
		||||
 | 
			
		||||
  /1.0/thirdparty/professions.json:
 | 
			
		||||
    get:
 | 
			
		||||
      tags:
 | 
			
		||||
        - thirdparty
 | 
			
		||||
      summary: Return all thirdparty professions
 | 
			
		||||
      responses:
 | 
			
		||||
          200:
 | 
			
		||||
              description: "ok"
 | 
			
		||||
          401:
 | 
			
		||||
              description: "Unauthorized"
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,3 @@ services:
 | 
			
		||||
  Chill\ThirdPartyBundle\DataFixtures\ORM\LoadThirdPartyCategory:
 | 
			
		||||
    tags:
 | 
			
		||||
      - { 'name': doctrine.fixture.orm }
 | 
			
		||||
 | 
			
		||||
  Chill\ThirdPartyBundle\DataFixtures\ORM\LoadThirdPartyProfession:
 | 
			
		||||
    tags:
 | 
			
		||||
      - { 'name': doctrine.fixture.orm }
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,63 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Chill\Migrations\ThirdParty;
 | 
			
		||||
 | 
			
		||||
use Chill\ThirdPartyBundle\Entity\ThirdPartyProfession;
 | 
			
		||||
use Doctrine\DBAL\Schema\Schema;
 | 
			
		||||
use Doctrine\DBAL\Types\Types;
 | 
			
		||||
use Doctrine\Migrations\AbstractMigration;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ContainerInterface;
 | 
			
		||||
 | 
			
		||||
final class Version20230215175150 extends AbstractMigration implements ContainerAwareInterface
 | 
			
		||||
{
 | 
			
		||||
    public ContainerInterface $container;
 | 
			
		||||
 | 
			
		||||
    public function down(Schema $schema): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->addSql('ALTER TABLE chill_3party.third_party DROP profession');
 | 
			
		||||
//        $this->addSql('ALTER TABLE chill_3party.third_party ADD profession_id INT DEFAULT NULL');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getDescription(): string
 | 
			
		||||
    {
 | 
			
		||||
        return 'Change profession to a string field and transfer values';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return mixed
 | 
			
		||||
     */
 | 
			
		||||
    public function setContainer(?ContainerInterface $container = null)
 | 
			
		||||
    {
 | 
			
		||||
        $this->container = $container;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function up(Schema $schema): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->addSql('ALTER TABLE chill_3party.third_party ADD profession TEXT DEFAULT \'\' NOT NULL');
 | 
			
		||||
 | 
			
		||||
        $em = $this->container->get('doctrine.orm.entity_manager');
 | 
			
		||||
        $professions = $em->getRepository(ThirdPartyProfession::class)->findAll();
 | 
			
		||||
 | 
			
		||||
        foreach ($professions as $p) {
 | 
			
		||||
            $id = $p->getId();
 | 
			
		||||
            $name = $p->getName()['fr'];
 | 
			
		||||
 | 
			
		||||
            $this->addSql(
 | 
			
		||||
                'UPDATE chill_3party.third_party SET profession = :profession
 | 
			
		||||
                          WHERE chill_3party.third_party.profession_id = :id;',
 | 
			
		||||
                ['profession' => $name, 'id' => $id],
 | 
			
		||||
                ['profession' => Types::STRING, 'id' => Types::INTEGER]
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -18,6 +18,7 @@ use Chill\MainBundle\Entity\User;
 | 
			
		||||
use Psr\Log\LoggerInterface;
 | 
			
		||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 | 
			
		||||
use Symfony\Component\HttpFoundation\JsonResponse;
 | 
			
		||||
use Symfony\Component\HttpFoundation\RequestStack;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Response;
 | 
			
		||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
 | 
			
		||||
use Symfony\Component\Mime\Part\DataPart;
 | 
			
		||||
@@ -40,6 +41,8 @@ class Convert
 | 
			
		||||
 | 
			
		||||
    private LoggerInterface $logger;
 | 
			
		||||
 | 
			
		||||
    private RequestStack $requestStack;
 | 
			
		||||
 | 
			
		||||
    private Security $security;
 | 
			
		||||
 | 
			
		||||
    private StoredObjectManagerInterface $storedObjectManager;
 | 
			
		||||
@@ -49,12 +52,14 @@ class Convert
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        HttpClientInterface $httpClient,
 | 
			
		||||
        RequestStack $requestStack,
 | 
			
		||||
        Security $security,
 | 
			
		||||
        StoredObjectManagerInterface $storedObjectManager,
 | 
			
		||||
        LoggerInterface $logger,
 | 
			
		||||
        ParameterBagInterface $parameters
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->httpClient = $httpClient;
 | 
			
		||||
        $this->requestStack = $requestStack;
 | 
			
		||||
        $this->security = $security;
 | 
			
		||||
        $this->storedObjectManager = $storedObjectManager;
 | 
			
		||||
        $this->logger = $logger;
 | 
			
		||||
@@ -68,6 +73,10 @@ class Convert
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $content = $this->storedObjectManager->read($storedObject);
 | 
			
		||||
        $query = [];
 | 
			
		||||
        if (null !== $request = $this->requestStack->getCurrentRequest()) {
 | 
			
		||||
            $query['lang'] = $request->getLocale();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            $url = sprintf('%s/cool/convert-to/pdf', $this->collaboraDomain);
 | 
			
		||||
@@ -76,6 +85,7 @@ class Convert
 | 
			
		||||
            ]);
 | 
			
		||||
            $response = $this->httpClient->request('POST', $url, [
 | 
			
		||||
                'headers' => $form->getPreparedHeaders()->toArray(),
 | 
			
		||||
                'query' => $query,
 | 
			
		||||
                'body' => $form->bodyToString(),
 | 
			
		||||
                'timeout' => 10,
 | 
			
		||||
            ]);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user