Compare commits

...

6 Commits

Author SHA1 Message Date
9eb571549b Prepare for release 2.20.0 2024-06-05 16:21:11 +02:00
db8257d230 Merge branch '170-export-action-referrer' into 'master'
Resolve "Dans la liste des évaluations et la liste des actions, il n'y a pas le nom des référents de l'action"

Closes #170

See merge request Chill-Projet/chill-bundles!695
2024-06-05 14:08:05 +00:00
bce93efe83 Resolve "Dans la liste des évaluations et la liste des actions, il n'y a pas le nom des référents de l'action" 2024-06-05 14:08:05 +00:00
06401af801 Merge branch '145-permettre-de-visualiser-les-documents-dans-libreoffice-en-utilisant-webdav' into 'master'
Add history to storedObject, instead of creating new stored object instances

Closes #145

See merge request Chill-Projet/chill-bundles!698
2024-06-04 20:37:36 +00:00
ea1d4c48f2 Add history support to StoredObject entity
This commit adds a history saving feature to the StoredObject entity, which allows saving versions of the object's changes over time. This is achieved by implementing a saveHistory method that captures data attributes like filename, IV, key information, and type. The corresponding Automated tests were also created. Furthermore, adjustments were made to the StoredObject test to align with the new feature.
2024-06-04 22:31:50 +02:00
nobohan
33cba27dd4 Translations: Added translations for choices of durations (> 5 hours) 2024-06-04 21:24:58 +02:00
11 changed files with 166 additions and 53 deletions

21
.changes/v2.20.0.md Normal file
View File

@@ -0,0 +1,21 @@
## v2.20.0 - 2024-06-05
### Fixed
* ([#170](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/170)) Display agents traitants instead of accompanying period referrer in export list social actions.
* Added translations for choices of durations (> 5 hours)
### Feature
* ([#145](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/145)) Allow to open documents in LibreOffice locally (need configuration within security);
This endpoint should be added to make the endpoint works properly:
```yaml
security:
firewalls:
dav:
pattern: ^/dav
provider: chain_provider
stateless: true
guard:
authenticators:
- Chill\DocStoreBundle\Security\Guard\JWTOnDavUrlAuthenticator
```

View File

@@ -6,6 +6,28 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html),
and is generated by [Changie](https://github.com/miniscruff/changie). and is generated by [Changie](https://github.com/miniscruff/changie).
## v2.20.0 - 2024-06-05
### Fixed
* ([#170](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/170)) Display agents traitants instead of accompanying period referrer in export list social actions.
* Added translations for choices of durations (> 5 hours)
### Feature
* ([#145](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/145)) Allow to open documents in LibreOffice locally (need configuration within security);
This endpoint should be added to make the endpoint works properly:
```yaml
security:
firewalls:
dav:
pattern: ^/dav
provider: chain_provider
stateless: true
guard:
authenticators:
- Chill\DocStoreBundle\Security\Guard\JWTOnDavUrlAuthenticator
```
## v2.19.0 - 2024-05-14 ## v2.19.0 - 2024-05-14
### Feature ### Feature
* ([#197](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/197)) Make the script which subscribe to microsoft calendars changes more tolerant to errors or missing configuration on the microsoft side * ([#197](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/197)) Make the script which subscribe to microsoft calendars changes more tolerant to errors or missing configuration on the microsoft side

View File

@@ -77,6 +77,18 @@ Choose a type: Choisir un type
4 hours: 4 heures 4 hours: 4 heures
4 hours 30: 4 heures 30 4 hours 30: 4 heures 30
5 hours: 5 heures 5 hours: 5 heures
5 hours 30: 5 heure 30
6 hours: 6 heures
6 hours 30: 6 heure 30
7 hours: 7 heures
7 hours 30: 7 heure 30
8 hours: 8 heures
8 hours 30: 8 heure 30
9 hours: 9 heures
9 hours 30: 9 heure 30
10 hours: 10 heures
11 hours: 11 heures
12 hours: 12 heures
Concerned groups: Parties concernées par l'échange Concerned groups: Parties concernées par l'échange
Persons in accompanying course: Usagers du parcours Persons in accompanying course: Usagers du parcours
Third persons: Tiers non-pro. Third persons: Tiers non-pro.

View File

@@ -72,21 +72,21 @@ days: jours
1 hour 30: 1 heure 30 1 hour 30: 1 heure 30
1 hour 45: 1 heure 45 1 hour 45: 1 heure 45
2 hours: 2 heures 2 hours: 2 heures
2 hours 30: 2 heure 30 2 hours 30: 2 heures 30
3 hours: 3 heures 3 hours: 3 heures
3 hours 30: 3 heure 30 3 hours 30: 3 heures 30
4 hours: 4 heures 4 hours: 4 heures
4 hours 30: 4 heure 30 4 hours 30: 4 heures 30
5 hours: 5 heures 5 hours: 5 heures
5 hours 30: 5 heure 30 5 hours 30: 5 heures 30
6 hours: 6 heures 6 hours: 6 heures
6 hours 30: 6 heure 30 6 hours 30: 6 heures 30
7 hours: 7 heures 7 hours: 7 heures
7 hours 30: 7 heure 30 7 hours 30: 7 heures 30
8 hours: 8 heures 8 hours: 8 heures
8 hours 30: 8 heure 30 8 hours 30: 8 heures 30
9 hours: 9 heures 9 hours: 9 heures
9 hours 30: 9 heure 30 9 hours 30: 9 heures 30
10 hours: 10 heures 10 hours: 10 heures
1/2 day: 1/2 jour 1/2 day: 1/2 jour
1 day: 1 jour 1 day: 1 jour

View File

@@ -354,4 +354,19 @@ class StoredObject implements AsyncFileInterface, Document, TrackCreationInterfa
return $this; return $this;
} }
public function saveHistory(): void
{
if ('' === $this->getFilename()) {
return;
}
$this->datas['history'][] = [
'filename' => $this->getFilename(),
'iv' => $this->getIv(),
'key_infos' => $this->getKeyInfos(),
'type' => $this->getType(),
'before' => (new \DateTimeImmutable('now'))->getTimestamp(),
];
}
} }

View File

@@ -59,8 +59,8 @@ class StoredObjectDataMapper implements DataMapperInterface
/** @var StoredObject $viewData */ /** @var StoredObject $viewData */
if ($viewData->getFilename() !== $forms['stored_object']->getData()['filename']) { if ($viewData->getFilename() !== $forms['stored_object']->getData()['filename']) {
// we do not want to erase the previous object // we want to keep the previous history
$viewData = new StoredObject(); $viewData->saveHistory();
} }
$viewData->setFilename($forms['stored_object']->getData()['filename']); $viewData->setFilename($forms['stored_object']->getData()['filename']);

View File

@@ -0,0 +1,53 @@
<?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\DocStoreBundle\Tests\Entity;
use Chill\DocStoreBundle\Entity\StoredObject;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
/**
* @internal
*
* @coversNothing
*/
class StoredObjectTest extends KernelTestCase
{
public function testSaveHistory(): void
{
$storedObject = new StoredObject();
$storedObject
->setFilename('test_0')
->setIv([2, 4, 6, 8])
->setKeyInfos(['key' => ['data0' => 'data0']])
->setType('text/html');
$storedObject->saveHistory();
$storedObject
->setFilename('test_1')
->setIv([8, 10, 12])
->setKeyInfos(['key' => ['data1' => 'data1']])
->setType('text/text');
$storedObject->saveHistory();
self::assertEquals('test_0', $storedObject->getDatas()['history'][0]['filename']);
self::assertEquals([2, 4, 6, 8], $storedObject->getDatas()['history'][0]['iv']);
self::assertEquals(['key' => ['data0' => 'data0']], $storedObject->getDatas()['history'][0]['key_infos']);
self::assertEquals('text/html', $storedObject->getDatas()['history'][0]['type']);
self::assertEquals('test_1', $storedObject->getDatas()['history'][1]['filename']);
self::assertEquals([8, 10, 12], $storedObject->getDatas()['history'][1]['iv']);
self::assertEquals(['key' => ['data1' => 'data1']], $storedObject->getDatas()['history'][1]['key_infos']);
self::assertEquals('text/text', $storedObject->getDatas()['history'][1]['type']);
}
}

View File

@@ -56,14 +56,14 @@ class StoredObjectTypeTest extends TypeTestCase
{"filename":"abcdef","iv":[10, 15, 20, 30],"keyInfos":[],"type":"text/html","status":"object_store_created"} {"filename":"abcdef","iv":[10, 15, 20, 30],"keyInfos":[],"type":"text/html","status":"object_store_created"}
JSON]; JSON];
$model = new StoredObject(); $model = new StoredObject();
$originalObjectId = spl_object_id($model); $originalObjectId = spl_object_hash($model);
$form = $this->factory->create(StoredObjectType::class, $model, ['has_title' => true]); $form = $this->factory->create(StoredObjectType::class, $model, ['has_title' => true]);
$form->submit($formData); $form->submit($formData);
$this->assertTrue($form->isSynchronized()); $this->assertTrue($form->isSynchronized());
$model = $form->getData(); $model = $form->getData();
$this->assertNotEquals($originalObjectId, spl_object_hash($model)); $this->assertEquals($originalObjectId, spl_object_hash($model));
$this->assertEquals('abcdef', $model->getFilename()); $this->assertEquals('abcdef', $model->getFilename());
$this->assertEquals([10, 15, 20, 30], $model->getIv()); $this->assertEquals([10, 15, 20, 30], $model->getIv());
$this->assertEquals('text/html', $model->getType()); $this->assertEquals('text/html', $model->getType());

View File

@@ -54,7 +54,6 @@ final readonly class ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeri
'socialAction', 'socialAction',
'socialIssue', 'socialIssue',
'acp_id', 'acp_id',
'acp_user',
'startDate', 'startDate',
'endDate', 'endDate',
'goalsId', 'goalsId',
@@ -70,8 +69,8 @@ final readonly class ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeri
'personsName', 'personsName',
'thirdParties', 'thirdParties',
'handlingThierParty', 'handlingThierParty',
// 'acpwReferrers', 'acpwReferrers',
'referrers', 'referrer',
'createdAt', 'createdAt',
'createdBy', 'createdBy',
'updatedAt', 'updatedAt',
@@ -157,9 +156,9 @@ final readonly class ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeri
[] []
); );
}, },
'createdBy', 'updatedBy', 'acp_user' => $this->userHelper->getLabel($key, $values, 'export.list.acpw.'.$key), 'createdBy', 'updatedBy' => $this->userHelper->getLabel($key, $values, 'export.list.acpw.'.$key),
'referrers' => $this->userHelper->getLabel($key, $values, 'export.list.acpw.'.$key), 'referrer' => $this->userHelper->getLabel($key, $values, 'export.list.acpw.'.$key),
// 'acpwReferrers' => $this->userHelper->getLabelMulti($key, $values, 'export.list.acpw.' . $key), 'acpwReferrers' => $this->userHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key),
'personsName' => $this->personHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key), 'personsName' => $this->personHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key),
'handlingThierParty' => $this->thirdPartyHelper->getLabel($key, $values, 'export.list.acpw.'.$key), 'handlingThierParty' => $this->thirdPartyHelper->getLabel($key, $values, 'export.list.acpw.'.$key),
'thirdParties' => $this->thirdPartyHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key), 'thirdParties' => $this->thirdPartyHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key),
@@ -273,8 +272,7 @@ final readonly class ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeri
// join acp // join acp
$qb $qb
->addSelect('acp.id AS acp_id') ->addSelect('acp.id AS acp_id');
->addSelect('IDENTITY(acp.user) AS acp_user');
// persons // persons
$qb $qb
@@ -283,21 +281,18 @@ final readonly class ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeri
->addSelect('(SELECT AGGREGATE(person1_acpw_member.id) FROM '.Person::class.' person1_acpw_member ' ->addSelect('(SELECT AGGREGATE(person1_acpw_member.id) FROM '.Person::class.' person1_acpw_member '
.'WHERE person1_acpw_member MEMBER OF acpw.persons) AS personsName'); .'WHERE person1_acpw_member MEMBER OF acpw.persons) AS personsName');
// referrers => at date XXXX // referrer => at date XXXX
$qb
->addSelect('(SELECT JSON_BUILD_OBJECT(\'uid\', IDENTITY(history.user), \'d\', history.startDate) FROM '.UserHistory::class.' history '.
'WHERE history.accompanyingPeriod = acp AND history.startDate <= :calcDate AND (history.endDate IS NULL OR history.endDate > :calcDate)) AS referrers');
/*
// acpwReferrers at date XXX
$qb $qb
->addSelect('( ->addSelect('(
SELECT IDENTITY(acpw_ref_history.accompanyingPeriodWork) AS acpw_ref_history_id, SELECT JSON_BUILD_OBJECT(\'uid\', IDENTITY(history.user), \'d\', history.startDate) FROM '.UserHistory::class.' history '.
JSON_BUILD_OBJECT(\'uid\', IDENTITY(acpw_ref_history.user), \'d\', acpw_ref_history.startDate) 'WHERE history.accompanyingPeriod = acp AND history.startDate <= :calcDate AND (history.endDate IS NULL OR history.endDate > :calcDate)) AS referrer');
FROM ' . AccompanyingPeriodWorkReferrerHistory::class . ' acpw_ref_history ' .
'WHERE acpw_ref_history.accompanyingPeriodWork = acpw AND acpw_ref_history.startDate <= :calcDate AND (acpw_ref_history.endDate IS NULL or acpw_ref_history.endDate > :calcDate) GROUP BY acpw_ref_history_id) AS acpwReferrers' // acpwReferrer at date XXX
); $qb->addSelect('(SELECT AGGREGATE(IDENTITY(acpwrh.user)) FROM '.AccompanyingPeriodWorkReferrerHistory::class.' acpwrh
*/ WHERE acpwrh.accompanyingPeriodWork = acpw
AND acpwrh.startDate <= :calcDate AND (acpwrh.endDate IS NULL or acpwrh.endDate > :calcDate)
) AS acpwReferrers');
$qb->setParameter('calcDate', $calcDate);
// thirdparties // thirdparties
$qb $qb

View File

@@ -54,7 +54,6 @@ final readonly class ListAccompanyingPeriodWorkAssociatePersonOnWork implements
'socialAction', 'socialAction',
'socialIssue', 'socialIssue',
'acp_id', 'acp_id',
'acp_user',
'startDate', 'startDate',
'endDate', 'endDate',
'goalsId', 'goalsId',
@@ -70,8 +69,8 @@ final readonly class ListAccompanyingPeriodWorkAssociatePersonOnWork implements
'personsName', 'personsName',
'thirdParties', 'thirdParties',
'handlingThierParty', 'handlingThierParty',
// 'acpwReferrers', 'acpwReferrers',
'referrers', 'referrer',
'createdAt', 'createdAt',
'createdBy', 'createdBy',
'updatedAt', 'updatedAt',
@@ -157,9 +156,9 @@ final readonly class ListAccompanyingPeriodWorkAssociatePersonOnWork implements
[] []
); );
}, },
'createdBy', 'updatedBy', 'acp_user' => $this->userHelper->getLabel($key, $values, 'export.list.acpw.'.$key), 'createdBy', 'updatedBy' => $this->userHelper->getLabel($key, $values, 'export.list.acpw.'.$key),
'referrers' => $this->userHelper->getLabel($key, $values, 'export.list.acpw.'.$key), 'referrer' => $this->userHelper->getLabel($key, $values, 'export.list.acpw.'.$key),
// 'acpwReferrers' => $this->userHelper->getLabelMulti($key, $values, 'export.list.acpw.' . $key), 'acpwReferrers' => $this->userHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key),
'personsName' => $this->personHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key), 'personsName' => $this->personHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key),
'handlingThierParty' => $this->thirdPartyHelper->getLabel($key, $values, 'export.list.acpw.'.$key), 'handlingThierParty' => $this->thirdPartyHelper->getLabel($key, $values, 'export.list.acpw.'.$key),
'thirdParties' => $this->thirdPartyHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key), 'thirdParties' => $this->thirdPartyHelper->getLabelMulti($key, $values, 'export.list.acpw.'.$key),
@@ -268,8 +267,7 @@ final readonly class ListAccompanyingPeriodWorkAssociatePersonOnWork implements
// join acp // join acp
$qb $qb
->addSelect('acp.id AS acp_id') ->addSelect('acp.id AS acp_id');
->addSelect('IDENTITY(acp.user) AS acp_user');
// persons // persons
$qb $qb
@@ -278,21 +276,17 @@ final readonly class ListAccompanyingPeriodWorkAssociatePersonOnWork implements
->addSelect('(SELECT AGGREGATE(person1_acpw_member.id) FROM '.Person::class.' person1_acpw_member ' ->addSelect('(SELECT AGGREGATE(person1_acpw_member.id) FROM '.Person::class.' person1_acpw_member '
.'WHERE person1_acpw_member MEMBER OF acpw.persons) AS personsName'); .'WHERE person1_acpw_member MEMBER OF acpw.persons) AS personsName');
// referrers => at date XXXX // referrer => at date XXXX
$qb $qb
->addSelect('(SELECT JSON_BUILD_OBJECT(\'uid\', IDENTITY(history.user), \'d\', history.startDate) FROM '.UserHistory::class.' history '. ->addSelect('(SELECT JSON_BUILD_OBJECT(\'uid\', IDENTITY(history.user), \'d\', history.startDate) FROM '.UserHistory::class.' history '.
'WHERE history.accompanyingPeriod = acp AND history.startDate <= :calcDate AND (history.endDate IS NULL OR history.endDate > :calcDate)) AS referrers'); 'WHERE history.accompanyingPeriod = acp AND history.startDate <= :calcDate AND (history.endDate IS NULL OR history.endDate > :calcDate)) AS referrer');
/*
// acpwReferrers at date XXX // acpwReferrers at date XXX
$qb $qb->addSelect('(SELECT AGGREGATE(IDENTITY(acpwrh.user)) FROM '.AccompanyingPeriodWorkReferrerHistory::class.' acpwrh
->addSelect('( WHERE acpwrh.accompanyingPeriodWork = acpw
SELECT IDENTITY(acpw_ref_history.accompanyingPeriodWork) AS acpw_ref_history_id, AND acpwrh.startDate <= :calcDate AND (acpwrh.endDate IS NULL or acpwrh.endDate > :calcDate)
JSON_BUILD_OBJECT(\'uid\', IDENTITY(acpw_ref_history.user), \'d\', acpw_ref_history.startDate) ) AS acpwReferrers');
FROM ' . AccompanyingPeriodWorkReferrerHistory::class . ' acpw_ref_history ' . $qb->setParameter('calcDate', $calcDate);
'WHERE acpw_ref_history.accompanyingPeriodWork = acpw AND acpw_ref_history.startDate <= :calcDate AND (acpw_ref_history.endDate IS NULL or acpw_ref_history.endDate > :calcDate) GROUP BY acpw_ref_history_id) AS acpwReferrers'
);
*/
// thirdparties // thirdparties
$qb $qb

View File

@@ -1405,7 +1405,8 @@ export:
updatedBy: Modifié par updatedBy: Modifié par
acp_id: Identifiant du parcours acp_id: Identifiant du parcours
acp_user: Référent du parcours acp_user: Référent du parcours
referrers: Agents traitants acpwReferrers: Agents traitants
referrer: Référent du parcours
personsId: Identifiants des usagers personsId: Identifiants des usagers
personsName: Usagers de l'action personsName: Usagers de l'action
goalsId: Identifiants des objectifs goalsId: Identifiants des objectifs