Skip to content
Snippets Groups Projects
Commit 69dc14b6 authored by gauthierb's avatar gauthierb
Browse files

PJ :

- ajout notification par mail lorsque toutes les PJ obligatoires sont fournies ; 
- correction bug : le total HETD n'était pas pris en compte par la règle métier PiecesJointesFournies.
parent 5b290a39
No related branches found
No related tags found
No related merge requests found
......@@ -4,8 +4,6 @@ namespace Application\Controller;
use Application\Assertion\FichierAssertion;
use Application\Assertion\PieceJointeAssertion;
use Application\Controller\Plugin\Context;
use UnicaenApp\Controller\Plugin\AppInfos;
use Application\Entity\Db\Fichier;
use Application\Entity\Db\IntervenantExterieur;
use Application\Entity\Db\PieceJointe;
......@@ -21,10 +19,9 @@ use Application\Service\Workflow\WorkflowIntervenantAwareInterface;
use Application\Service\Workflow\WorkflowIntervenantAwareTrait;
use BjyAuthorize\Exception\UnAuthorizedException;
use Common\Exception\MessageException;
use Common\Exception\RuntimeException;
use Common\Exception\PieceJointe\AucuneAFournirException;
use Common\Exception\PieceJointe\PieceJointeException;
use Doctrine\ORM\EntityManager;
use Zend\Form\Form;
use Zend\Http\Response;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
......@@ -32,9 +29,10 @@ use Zend\View\Model\ViewModel;
/**
* Description of UploadController
*
* @method EntityManager em()
* @method Context context()
* @method AppInfos appInfos()
* @method Doctrine\ORM\EntityManager em()
* @method Application\Controller\Plugin\Context context()
* @method UnicaenApp\Controller\Plugin\AppInfos appInfos()
* @method UnicaenApp\Controller\Plugin\Mail mail()
*
* @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
*/
......@@ -43,11 +41,6 @@ class PieceJointeController extends AbstractActionController implements ContextP
use ContextProviderAwareTrait;
use WorkflowIntervenantAwareTrait;
/**
* @var Form
*/
private $form;
/**
* @var string
*/
......@@ -139,7 +132,6 @@ class PieceJointeController extends AbstractActionController implements ContextP
$messages['success'][] = "Toutes les pièces justificatives fournies ont été validées par votre composante.";
}
$this->view->setVariables(array(
'urlStatus' => $this->url()->fromRoute('piece-jointe/intervenant/status', [], [], true),
'messages' => $messages,
......@@ -196,6 +188,7 @@ class PieceJointeController extends AbstractActionController implements ContextP
if ($form->isValid()) {
$data = $form->getData();
$this->getServicePieceJointe()->createFromFiles($data['files'], $intervenant, $typePieceJointe);
$this->notifyPiecesJointesFournies();
return $redir;
}
......@@ -204,6 +197,62 @@ class PieceJointeController extends AbstractActionController implements ContextP
return $redir;
}
private function notifyPiecesJointesFournies()
{
// notif ssi toutes les PJ obligatoires ont été founies
if (!$this->getRulePiecesJointesFournies()->execute()) {
return;
}
// pas de nottif si c'est un gestionnaire qui dépose des PJ
if ($this->getContextProvider()->getSelectedIdentityRole() instanceof \Application\Acl\ComposanteRole) {
return;
}
// extraction des messages d'info (ce sont les feuilles du tableau)
$messages = \UnicaenApp\Util::extractArrayLeafNodes($this->statusAction()->getVariable('messages'));
// corps au format HTML
$renderer = $this->getServiceLocator()->get('view_manager')->getRenderer(); /* @var $renderer \Zend\View\Renderer\PhpRenderer */
$html = $renderer->render('application/piece-jointe/partial/mail', [
'messages' => $messages,
'intervenant' => $this->getIntervenant(),
'url' => $this->url()->fromRoute('piece-jointe/intervenant', [], ['force_canonical' => true], true),
]);
$part = new \Zend\Mime\Part($html);
$part->type = \Zend\Mime\Mime::TYPE_HTML;
$part->charset = 'UTF-8';
$body = new \Zend\Mime\Message();
$body->addPart($part);
// init
$message = new \Zend\Mail\Message();
$message->setEncoding('UTF-8')
->setFrom('ne_pas_repondre@unicaen.fr', "Application " . ($app = $this->appInfos()->getNom()))
->setSubject(sprintf("[%s] Pièces justificatives déposées par %s", $app, $this->getIntervenant()))
->setBody($body);
// destinataires
$destinataires = $this->getPieceJointeProcess()->getDestinatairesMail();
if (!$destinataires) {
throw new RuntimeException(sprintf("Aucun destinataire trouvé concernant %s.", $this->getIntervenant()));
}
$message->addTo($destinataires);
// envoi
$this->mail()->send($message);
}
/**
* @return PiecesJointesFourniesRule
*/
private function getRulePiecesJointesFournies()
{
$rule = $this->getServiceLocator()->get('PiecesJointesFourniesRule');
$rule->setIntervenant($this->getIntervenant());
return $rule;
}
/**
* Téléchargement d'un fichier.
*
......
......@@ -11,7 +11,8 @@ class TypeRole implements HistoriqueAwareInterface, RoleInterface
{
use HistoriqueAwareTrait;
const CODE_RA = 'RA';
const CODE_RESPONSABLE_COMPOSANTE = 'responsable-composante';
const CODE_GESTIONNAIRE_COMPOSANTE = 'gestionnaire-composante';
/**
* @var string
......
......@@ -25,6 +25,10 @@ class PiecesJointesFourniesRule extends AbstractRule implements ServiceLocatorAw
use ContextProviderAwareTrait;
use IntervenantAwareTrait;
/**
*
* @return boolean
*/
public function execute()
{
// liste des PJ déjà fournies
......@@ -49,7 +53,7 @@ class PiecesJointesFourniesRule extends AbstractRule implements ServiceLocatorAw
if (array_key_exists($tpjs->getType()->getId(), $typesFournis)) {
continue;
}
if (!$tpjs->getObligatoire()) {
if (!$tpjs->isObligatoire($this->totalHETDIntervenant)) {
continue;
}
$typesNonFournis[$tpjs->getType()->getId()] = $tpjs->getType();
......@@ -65,6 +69,10 @@ class PiecesJointesFourniesRule extends AbstractRule implements ServiceLocatorAw
return true;
}
/**
*
* @return boolean
*/
public function isRelevant()
{
return $this->getIntervenant() instanceof IntervenantExterieur && null !== $this->getIntervenant()->getDossier();
......@@ -113,6 +121,25 @@ class PiecesJointesFourniesRule extends AbstractRule implements ServiceLocatorAw
return $this;
}
/**
* @var float
*/
protected $totalHETDIntervenant;
/**
* Spécifie le total d'HETD de l'intervenant.
* Ce total est pris en compte pour déterminer le caractère obligatoire de certain type de PJ.
*
* @param float $totalHETDIntervenant
* @return self
*/
public function setTotalHETDIntervenant($totalHETDIntervenant)
{
$this->totalHETDIntervenant = $totalHETDIntervenant;
return $this;
}
/**
* Réinitialise les variables de travail.
*
......
......@@ -4,7 +4,7 @@ namespace Application\Service\Process;
use Application\Service\AbstractService;
use Application\Entity\Db\IntervenantExterieur;
use Application\Service\StatutIntervenant as StatutIntervenantService;
use Application\Service\Stucture as StuctureService;
use Application\Service\TypePieceJointe as TypePieceJointeService;
use Application\Service\TypePieceJointeStatut as TypePieceJointeStatutService;
use Application\Service\PieceJointe as PieceJointeService;
......@@ -12,6 +12,7 @@ use Application\Entity\Db\TypePieceJointe;
use Application\Entity\Db\TypePieceJointeStatut;
use Application\Entity\Db\PieceJointe;
use Application\Rule\Intervenant\PiecesJointesFourniesRule;
use Common\Exception\RuntimeException;
/**
* Processus de gestion de la liste de pièces à fournir pour un dossier vacataire.
......@@ -303,7 +304,7 @@ class PieceJointeProcess extends AbstractService
$structure = $this->getIntervenant()->getStructure();
do {
$qb = $service->finderByTypeRole(\Application\Entity\Db\TypeRole::CODE_RA);
$qb = $service->finderByTypeRole(\Application\Entity\Db\TypeRole::CODE_GESTIONNAIRE_COMPOSANTE);
$service->finderByStructure($structure, $qb);
$roles = $service->getList($qb);
$structure = $structure->getParente();
......@@ -314,11 +315,42 @@ class PieceJointeProcess extends AbstractService
}
/**
* @return StatutIntervenantService
* Recherche les destinataires du mail de notification lorsque toutes les pièces justificatives
* obligaoires ont été fournies.
*
* @return string[]
*/
public function getDestinatairesMail()
{
// recherches des composantes d'intervention
$serviceService = $this->getServiceService();
$serviceStructure = $this->getServiceStructure(); /* @var $serviceStructure \Application\Service\Structure */
$qb = $serviceStructure->initQuery()[0];
$serviceStructure->join($serviceService, $qb, 'service');
$serviceService->finderByIntervenant($this->getIntervenant(), $qb);
$structures = $serviceStructure->getList($qb);
if (!$structures) {
$structures = [ $this->getIntervenant()->getStructure() ];
}
if (!$structures) {
throw new RuntimeException(sprintf("Aucune composante d'intervention ni structure d'affectation trouvée pour %s.",
$this->getIntervenant()));
}
$contacts = [];
foreach ($structures as $structure) {
$contacts += $serviceStructure->getMailsContact($structure);
}
return $contacts;
}
/**
* @return StuctureService
*/
private function getServiceStatut()
private function getServiceStructure()
{
return $this->getServiceLocator()->get('applicationStatutIntervenant');
return $this->getServiceLocator()->get('applicationStructure');
}
/**
......
......@@ -50,6 +50,58 @@ class Structure extends AbstractEntityService
);
}
/**
* Recherche les adresses mails de contact d'une structure.
*
* Si une adresse de contact est spécifiée pour cette structure dans la table, on retourne cette adresse.
* Sinon, on recherche les personnes ayant un rôle spécifique dans la structure, en remontant la hiérarchie
* des structures mères tant que personne n'est trouvé (et si demandé).
*
* @param \Application\Entity\Db\Structure $structure Structure concernée
* @param boolean $remonterStructures Remonter les structures mères ?
* @return string[] mail => nom
*/
public function getMailsContact(EntityStructure $structure, $remonterStructures = true)
{
if ($structure->getContactPj()) {
return [ $structure->getContactPj() ];
}
$serviceRole = $this->getServiceLocator()->get('applicationRole');
$str = $structure;
// recherche des rôles dans la structure, en remontant la hiérarchie des structures si besoin et demandé
do {
// recherche de "gestionnaires" en priorité
$qb = $serviceRole->finderByTypeRole(\Application\Entity\Db\TypeRole::CODE_GESTIONNAIRE_COMPOSANTE);
$serviceRole->finderByStructure($str, $qb);
$roles = $serviceRole->getList($qb);
if (count($roles)) {
continue; // on a trouvé du monde, ça nous va
}
// si aucun gestionnaire trouvé, recherche de "responsables"
$qb = $serviceRole->finderByTypeRole(\Application\Entity\Db\TypeRole::CODE_RESPONSABLE_COMPOSANTE);
$serviceRole->finderByStructure($str, $qb);
$roles = $serviceRole->getList($qb);
// on grimpe la hiérarchie des structures
$str = $str->getParente();
}
while ($remonterStructures && !count($roles) && $str);
// mise en forme du résultat
$contacts = [];
foreach ($roles as $role) { /* @var $role \Application\Entity\Db\Role */
$mail = $role->getPersonnel()->getEmail();
$name = $role->getPersonnel()->getNomUsuel() . ' ' . $role->getPersonnel()->getPrenom();
$contacts[$mail] = $name;
}
return $contacts;
}
/**
* Retourne la liste des structures selon le contexte donné
*
......
<p>
Bonjour.
</p>
<p>
Ceci est un message d'information concernant le dépôt de pièces justificatives par l'intervenant
<?php echo $this->intervenant ?> dans l'application
<a href="<?php echo $this->url ?>"><?php echo $this->appInfos()->nom ?></a>.
</p>
<?php echo $this->htmlList($this->messages) ?>
<p>
Bonne continuation.
</p>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment