Associate generate document with evaluation and update UX to go back to

documents
This commit is contained in:
Julien Fastré 2021-08-20 12:44:15 +02:00
parent 80672a038c
commit 7f28effc1e
8 changed files with 175 additions and 16 deletions

View File

@ -4,6 +4,9 @@ namespace Chill\DocGeneratorBundle\Controller;
use Chill\DocGeneratorBundle\Repository\DocGeneratorTemplateRepository; use Chill\DocGeneratorBundle\Repository\DocGeneratorTemplateRepository;
use Chill\DocStoreBundle\Entity\StoredObject; use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
use GuzzleHttp\Exception\TransferException; use GuzzleHttp\Exception\TransferException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
@ -105,14 +108,26 @@ class DocGeneratorTemplateController extends AbstractController
]); ]);
if ($putResponse->getStatusCode() == 201) { if ($putResponse->getStatusCode() == 201) {
$em = $this->getDoctrine()->getManager();
$storedObject = new StoredObject(); $storedObject = new StoredObject();
$storedObject $storedObject
// currently, only docx is supported // currently, only docx is supported
->setType('application/vnd.openxmlformats-officedocument.wordprocessingml.document') ->setType('application/vnd.openxmlformats-officedocument.wordprocessingml.document')
->setFilename($genDocName); ->setFilename($genDocName);
$em = $this->getDoctrine()->getManager();
$em->persist($storedObject); $em->persist($storedObject);
// Only for evaluation
if ($entity instanceof AccompanyingPeriodWorkEvaluation) {
$doc = new AccompanyingPeriodWorkEvaluationDocument();
$doc
->setStoredObject($storedObject)
->setTemplate($template)
;
$entity->addDocument($doc);
$em->persist($doc);
}
$em->flush(); $em->flush();
return $this->redirectToRoute('chill_wopi_file_edit', [ return $this->redirectToRoute('chill_wopi_file_edit', [

View File

@ -4,11 +4,11 @@ namespace Chill\DocGeneratorBundle\Entity;
use Chill\DocGeneratorBundle\Repository\DocGeneratorTemplateRepository; use Chill\DocGeneratorBundle\Repository\DocGeneratorTemplateRepository;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation as Serializer;
/** /**
* @ORM\Entity * @ORM\Entity
* @ORM\Table(name="chill_docgen_template") * @ORM\Table(name="chill_docgen_template")
*/ */
class DocGeneratorTemplate class DocGeneratorTemplate
{ {
@ -16,11 +16,13 @@ class DocGeneratorTemplate
* @ORM\Id * @ORM\Id
* @ORM\GeneratedValue * @ORM\GeneratedValue
* @ORM\Column(type="integer") * @ORM\Column(type="integer")
* @Serializer\Groups({"read"})
*/ */
private int $id; private int $id;
/** /**
* @ORM\Column(type="json_array") * @ORM\Column(type="json_array")
* @Serializer\Groups({"read"})
*/ */
private array $name = []; private array $name = [];

View File

@ -8,12 +8,11 @@ use Doctrine\ORM\Mapping as ORM;
use ChampsLibres\AsyncUploaderBundle\Model\AsyncFileInterface; use ChampsLibres\AsyncUploaderBundle\Model\AsyncFileInterface;
use ChampsLibres\AsyncUploaderBundle\Validator\Constraints\AsyncFileExists; use ChampsLibres\AsyncUploaderBundle\Validator\Constraints\AsyncFileExists;
use DateTimeInterface; use DateTimeInterface;
use Symfony\Component\Serializer\Annotation as Serializer;
/** /**
* Represent a document stored in an object store * Represent a document stored in an object store
* *
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*
* @ORM\Entity() * @ORM\Entity()
* @ORM\Table("chill_doc.stored_object") * @ORM\Table("chill_doc.stored_object")
* @AsyncFileExists( * @AsyncFileExists(
@ -26,11 +25,13 @@ class StoredObject implements AsyncFileInterface
* @ORM\Id() * @ORM\Id()
* @ORM\GeneratedValue() * @ORM\GeneratedValue()
* @ORM\Column(type="integer") * @ORM\Column(type="integer")
* @Serializer\Groups({"read"})
*/ */
private $id; private $id;
/** /**
* @ORM\Column(type="text") * @ORM\Column(type="text")
* @Serializer\Groups({"read"})
*/ */
private $filename; private $filename;
@ -48,16 +49,19 @@ class StoredObject implements AsyncFileInterface
/** /**
* @ORM\Column(type="datetime", name="creation_date") * @ORM\Column(type="datetime", name="creation_date")
* @Serializer\Groups({"read"})
*/ */
private DateTimeInterface $creationDate; private DateTimeInterface $creationDate;
/** /**
* @ORM\Column(type="text", name="type") * @ORM\Column(type="text", name="type")
* @Serializer\Groups({"read"})
*/ */
private string $type = ''; private string $type = '';
/** /**
* @ORM\Column(type="json_array", name="datas") * @ORM\Column(type="json_array", name="datas")
* @Serializer\Groups({"read"})
*/ */
private array $datas = []; private array $datas = [];

View File

@ -135,6 +135,7 @@ class AccompanyingPeriodWorkEvaluation implements TrackUpdateInterface, TrackCre
* *
* @Serializer\Groups({"read"}) * @Serializer\Groups({"read"})
* @Serializer\Groups({"write"}) * @Serializer\Groups({"write"})
* @Serializer\Groups({"accompanying_period_work_evaluation:create"})
* *
* @var mixed * @var mixed
* *
@ -382,6 +383,22 @@ class AccompanyingPeriodWorkEvaluation implements TrackUpdateInterface, TrackCre
return $this->documents; return $this->documents;
} }
public function addDocument(AccompanyingPeriodWorkEvaluationDocument $document): self
{
if (!$this->documents->contains($document)) {
$this->documents[] = $document;
$document->setAccompanyingPeriodWorkEvaluation($this);
}
return $this;
}
public function removeDocument(AccompanyingPeriodWorkEvaluationDocument $document): self
{
$this->documents->removeElement($document);
return $this;
}
/** /**
* Arbitrary data, used for client * Arbitrary data, used for client
* *

View File

@ -2,6 +2,7 @@
namespace Chill\PersonBundle\Entity\AccompanyingPeriod; namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate;
use Chill\DocStoreBundle\Entity\StoredObject; use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface; use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface; use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
@ -37,7 +38,7 @@ class AccompanyingPeriodWorkEvaluationDocument implements \Chill\MainBundle\Doct
* inversedBy="documents" * inversedBy="documents"
* ) * )
*/ */
private ?AccompanyingPeriodWorkEvaluation $accompanyingPeriodWorkEvaluation; private ?AccompanyingPeriodWorkEvaluation $accompanyingPeriodWorkEvaluation = null;
/** /**
* @ORM\ManyToOne( * @ORM\ManyToOne(
@ -45,13 +46,13 @@ class AccompanyingPeriodWorkEvaluationDocument implements \Chill\MainBundle\Doct
* ) * )
* @Serializer\Groups({"read"}) * @Serializer\Groups({"read"})
*/ */
private ?User $createdBy; private ?User $createdBy = null;
/** /**
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null}) * @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
* @Serializer\Groups({"read"}) * @Serializer\Groups({"read"})
*/ */
private ?\DateTimeImmutable $createdAt; private ?\DateTimeImmutable $createdAt = null;
/** /**
* @ORM\ManyToOne( * @ORM\ManyToOne(
@ -59,18 +60,29 @@ class AccompanyingPeriodWorkEvaluationDocument implements \Chill\MainBundle\Doct
* ) * )
* @Serializer\Groups({"read"}) * @Serializer\Groups({"read"})
*/ */
private ?User $updatedBy; private ?User $updatedBy = null;
/** /**
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null}) * @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
* @Serializer\Groups({"read"}) * @Serializer\Groups({"read"})
*/ */
private ?DateTimeImmutable $updatedAt; private ?\DateTimeImmutable $updatedAt = null;
// TODO: indiquer le document généré par le module "document" /**
private ?StoredObject $storedObject; * @ORM\ManyToOne(
* targetEntity=StoredObject::class
* )
* @Serializer\Groups({"read"})
*/
private ?StoredObject $storedObject = null;
// TODO: ajouter gabarit /**
* @ORM\ManyToOne(
* targetEntity=DocGeneratorTemplate::class
* )
* @Serializer\Groups({"read"})
*/
private ?DocGeneratorTemplate $template = null;
/** /**
* @return AccompanyingPeriodWorkEvaluation|null * @return AccompanyingPeriodWorkEvaluation|null
@ -86,6 +98,14 @@ class AccompanyingPeriodWorkEvaluationDocument implements \Chill\MainBundle\Doct
*/ */
public function setAccompanyingPeriodWorkEvaluation(?AccompanyingPeriodWorkEvaluation $accompanyingPeriodWorkEvaluation): AccompanyingPeriodWorkEvaluationDocument public function setAccompanyingPeriodWorkEvaluation(?AccompanyingPeriodWorkEvaluation $accompanyingPeriodWorkEvaluation): AccompanyingPeriodWorkEvaluationDocument
{ {
// if an evaluation is already associated, we cannot change the association (removing the association,
// by setting a null value, is allowed.
if ($this->accompanyingPeriodWorkEvaluation instanceof AccompanyingPeriodWorkEvaluation
&& $accompanyingPeriodWorkEvaluation instanceof AccompanyingPeriodWorkEvaluation) {
if ($this->accompanyingPeriodWorkEvaluation !== $accompanyingPeriodWorkEvaluation) {
throw new \RuntimeException("It is not allowed to change the evaluation for a document");
}
}
$this->accompanyingPeriodWorkEvaluation = $accompanyingPeriodWorkEvaluation; $this->accompanyingPeriodWorkEvaluation = $accompanyingPeriodWorkEvaluation;
return $this; return $this;
} }
@ -172,4 +192,22 @@ class AccompanyingPeriodWorkEvaluationDocument implements \Chill\MainBundle\Doct
return $this->updatedAt; return $this->updatedAt;
} }
/**
* @return DocGeneratorTemplate|null
*/
public function getTemplate(): ?DocGeneratorTemplate
{
return $this->template;
}
/**
* @param DocGeneratorTemplate|null $template
* @return AccompanyingPeriodWorkEvaluationDocument
*/
public function setTemplate(?DocGeneratorTemplate $template): AccompanyingPeriodWorkEvaluationDocument
{
$this->template = $template;
return $this;
}
} }

View File

@ -19,8 +19,20 @@
<dt v-if="evaluation.warningInterval">{{ $t('warningInterval') }} :</dt> <dt v-if="evaluation.warningInterval">{{ $t('warningInterval') }} :</dt>
<dd v-if="evaluation.warningInterval">{{ evaluation.warningInterval }}</dd> <dd v-if="evaluation.warningInterval">{{ evaluation.warningInterval }}</dd>
<dt v-if="evaluation.documents && evaluation.documents.length > 0">{{ $t('documents') }} :</dt> <template v-if="evaluation.documents.length > 1">
<dd v-if="evaluation.documents && evaluation.documents.length > 0">{{ evaluation.documents.length }}</dd> <dt>{{ $t('documents') }} :</dt>
<dd>
<ul>
<li v-for="d in evaluation.documents" :key="d.id">
{{ d.template.name.fr }}
<a :href="buildEditLink(d.storedObject)" class="btn btn-action btn-sm">
<i class="fa fa-edit"></i>
</a>
</li>
</ul>
</dd>
</template>
</dl> </dl>
<dl class="item-details"> <dl class="item-details">
@ -82,7 +94,7 @@ export default {
computed: { computed: {
pickedEvaluations() { pickedEvaluations() {
return this.$store.state.evaluationsPicked; return this.$store.state.evaluationsPicked;
} },
}, },
methods: { methods: {
removeEvaluation(e) { removeEvaluation(e) {
@ -95,7 +107,10 @@ export default {
}, },
submitForm() { submitForm() {
this.toggleEditEvaluation(); this.toggleEditEvaluation();
} },
buildEditLink(storedObject) {
return `/wopi/edit/${storedObject.filename}`;
},
} }
} }
</script> </script>

View File

@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace Chill\Migrations\Person;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Add a link between evaluation document, stored object, and document template
*/
final class Version20210820093927 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add a link between evaluation document, stored object, and document template';
}
public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_person_accompanying_period_work_evaluation_document ADD template_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE chill_person_accompanying_period_work_evaluation_document ADD storedObject_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE chill_person_accompanying_period_work_evaluation_document ADD CONSTRAINT FK_33EC92296C99C13A FOREIGN KEY (storedObject_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE chill_person_accompanying_period_work_evaluation_document ADD CONSTRAINT FK_33EC92295DA0FB8 FOREIGN KEY (template_id) REFERENCES chill_docgen_template (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('CREATE INDEX IDX_33EC92296C99C13A ON chill_person_accompanying_period_work_evaluation_document (storedObject_id)');
$this->addSql('CREATE INDEX IDX_33EC92295DA0FB8 ON chill_person_accompanying_period_work_evaluation_document (template_id)');
}
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_person_accompanying_period_work_evaluation_document DROP CONSTRAINT FK_33EC92296C99C13A');
$this->addSql('ALTER TABLE chill_person_accompanying_period_work_evaluation_document DROP CONSTRAINT FK_33EC92295DA0FB8');
$this->addSql('DROP INDEX IDX_33EC92296C99C13A');
$this->addSql('DROP INDEX IDX_33EC92295DA0FB8');
$this->addSql('ALTER TABLE chill_person_accompanying_period_work_evaluation_document DROP template_id');
$this->addSql('ALTER TABLE chill_person_accompanying_period_work_evaluation_document DROP storedObject_id');
}
}

View File

@ -0,0 +1,29 @@
<?php
declare(strict_types=1);
namespace Chill\Migrations\Person;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Add missing sequence for evaluation documents
*/
final class Version20210820100407 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add missing sequence for evaluation documents';
}
public function up(Schema $schema): void
{
$this->addSql('CREATE SEQUENCE chill_person_social_work_eval_doc_id_seq INCREMENT BY 1 MINVALUE 1000 START 1000');
}
public function down(Schema $schema): void
{
$this->addSql('DROP SEQUENCE chill_person_social_work_eval_doc_id_seq');
}
}