<?php
// src/Controller/ApprenantController.php
namespace App\Controller;
use DateTimeZone;
use IntlDateFormatter;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use App\Classes\GeneratePDF;
/**
* @Route("/apprenant", name="apprenant_")
*/
class ApprenantController extends DigiEntityController
{
const REF = 'apprenant';
const NAME = 'Apprenant';
const CERFA_PDF_NUM = '14';
public function field_format($name, $field, $options=[])
{
$html = '';
$style = '';
$digi_map = (!empty($field['digi_map']) && is_string($field['digi_map']) ?' data-digi="'.$field['digi_map'].'"' :'');
if (!empty($field['align']))
$style .= 'text-align: '.$field['align'].';';
if (!empty($field['width']))
$style .= 'width: '.$field['width'].';';
// True par défaut
$required = !isset($field['required']) || $field['required'];
$class = ($required ?'required' :'');
if (!empty($field['premsg']))
$html .= '<span class="msg">'.$field['premsg'].'</span> ';
if (!empty($options['checkbox_to_radio']))
$class .= ' radio';
if ($field['type']=='checkbox') {
if (isset($field['values']['Yes']))
$value_ok = 'Yes';
else
$value_ok = 'Oui';
$html .= '<input type="checkbox" id="'.$name.'"'.$digi_map.' name="'.$name.'" value="'.$value_ok.'"'.($field['value']==$value_ok ?' checked' :'').($class ?' class="'.$class.'" ' :'').($style ?' style="'.$style.'" ' :'').' /> <label for="'.$name.'">'.$field['values'][$value_ok].'</label>';
}
elseif ($field['type']=='radio') {
foreach($field['values'] as $value=>$label)
$html .= '<input type="radio" id="'.$name.'_'.$value.'"'.$digi_map.' name="'.$name.'" value="'.$value.'"'.($field['value']==$value ?' checked' :'').' /> <label for="'.$name.'_'.$value.'">'.$label.'</label>';
}
elseif ($field['type']=='select') {
$html .= '<select id="'.$name.'"'.$digi_map.' name="'.$name.'"'.($class ?' class="'.$class.'" ' :'').($style ?' style="'.$style.'" ' :'').' data-value="'.$field['value'].'"'.($required ?' required' :'').'>'.(empty($field['noempty']) ?'<option value=""></option>' :'');
foreach($field['values'] as $value=>$select_option) {
if (is_array($select_option)) {
$label = $select_option['label'];
$disabled = !empty($select_option['disabled']) || in_array('disabled', $select_option);
}
else {
$label = $select_option;
$disabled = false;
}
$html .= '<option value="'.$value.'"'.($field['value']==$value ?' selected' :'').($disabled ?' disabled' :'').' data-detail="'.htmlspecialchars(json_encode($select_option)).'">'.$label.'</option>';
}
$html .= '</select>';
}
elseif ($field['type'] =='date') {
$html .= '<input type="date" id="'.$name.'"'.$digi_map.' name="'.$name.'" placeholder="'.$field['label'].'" value="'.$field['value'].'" data-value="'.$field['value'].'"'.(!empty($field['maxlength']) ?' size="'.$field['maxlength'].'" maxlength="'.$field['maxlength'].'"' :'').($class ?' class="'.$class.'" ' :'').($style ?' style="'.$style.'" ' :'').($required ?' required' :'').' />';
}
elseif ($field['type'] =='textarea') {
$html .= '<textarea id="'.$name.'"'.$digi_map.' name="'.$name.'" placeholder="'.$field['label'].'" data-value="'.$field['value'].'"'.(!empty($field['maxlength']) ?' size="'.$field['maxlength'].'" maxlength="'.$field['maxlength'].'"' :'').($class ?' class="'.$class.'" ' :'').($style ?' style="'.$style.'" ' :'').($required ?' required' :'').' />'.$field['value'].'</texrarea>';
}
else { // text
$html .= '<input type="text" id="'.$name.'"'.$digi_map.' name="'.$name.'" placeholder="'.$field['label'].'" value="'.$field['value'].'" data-value="'.(isset($field['value']) ?$field['value'] :'').'"'.(!empty($field['maxlength']) ?' size="'.$field['maxlength'].'" maxlength="'.$field['maxlength'].'"' :'').($class ?' class="'.$class.'" ' :'').($style ?' style="'.$style.'" ' :'').($required ?' required' :'').' />'.(!empty($field['unit']) ?' '.$field['unit'] :'');
}
if (empty($field['noreset']) && empty($options['noreset']) && ! in_array($field['type'], ['checkbox']))
$html .= ' <span class="reset" data-for="'.$name.'">X</span>';
if (!empty($field['digi_map']))
$html .= ' <span class="digi_mapped" title="'.$field['digi_map'].'">D</span>';
elseif (!isset($field['digi_map']) || $field['digi_map']!==false)
$html .= ' <span class="digi_unmapped">D</span>';
if (!empty($field['postmsg']))
$html .= ' <span class="msg">'.$field['postmsg'].'</span>';
return $html;
}
/**
* @Route("/{id}/certificat", name="certificat")
*/
public function CertificatAction(Request $request): Response
{
if (!($params = $this->cerfa_params($request)))
die('Paramètres invalides');
extract($params);
//var_dump($params); die();
$locale = 'fr_FR';
$timezone = 'Europe/Paris';
setlocale(LC_ALL, $locale);
date_default_timezone_set($timezone);
$datetimezone = new DateTimeZone($timezone);
$dayformatter = new IntlDateFormatter(
$locale, // the locale to use, e.g. 'en_GB'
IntlDateFormatter::FULL, // how the date should be formatted, e.g. IntlDateFormatter::FULL
IntlDateFormatter::FULL, // how the time should be formatted, e.g. IntlDateFormatter::FULL
$timezone // the time should be returned in which timezone?
);
$dayformatter->setPattern('dd/mm/YYYY');
$dayformatter = new IntlDateFormatter(
$locale, // the locale to use, e.g. 'en_GB'
IntlDateFormatter::FULL, // how the date should be formatted, e.g. IntlDateFormatter::FULL
IntlDateFormatter::FULL, // how the time should be formatted, e.g. IntlDateFormatter::FULL
$timezone // the time should be returned in which timezone?
);
$dayformatter->setPattern('d MMMM YYYY');
// Params
$this->params = [
'date' => $dayformatter->format(new \DateTime()),
'apprenant' => $apprenant,
'session' => $session,
'company' => $company,
'program' => $program,
];
// Twig template
$tplfile = 'apprenant/certificat.html.twig';
return $this->render($tplfile, $this->params);
}
/**
* @Route("/cerfa_list", name="cerfa_list")
*/
public function CERFAListAction(Request $request): Response
{
$repository = $this->em->getRepository('App\\Entity\\Financeur');
$f = $repository->findByQ('CERFA');
//var_dump($f);
$repository = $this->em->getRepository('App\\Entity\\SessionCustomer');
$customer_list = $repository->findByQ('CERFA');
// Traitement
$list = [];
foreach($customer_list as $customer) {
foreach($customer->getApprenants() as $apprenant) {
$list[] = [
'customer'=>$customer,
'apprenant'=>$apprenant,
'entreprise'=>$customer->getEntreprise(),
'session'=>$customer->getSession(),
];
}
}
usort($list, function($a, $b){
$i = $a['apprenant']->getContratSignature();
$j = $b['apprenant']->getContratSignature();
//var_dump($a['apprenant']->getNom(), $i); echo '<br />'; var_dump($b['apprenant'], $b['apprenant']->getNom(), $j, $i==$j, $i<$j); echo '<hr />';
if ($i==$j)
return 0;
return ($i<$j) ?-1 :1;
});
//var_dump($list);
//die();
// Params
$this->params();
$this->params['page']['head']['title'] = 'Formulaires Cerfa';
$this->params['page']['subtitle'] = 'Liste des CERFA à faire';
$this->params['page']['breadcrumbs'][] = [
'route' => static::REF.'_cerfa_list',
'label' => 'Liste',
];
$this->params['f'] = $f;
$this->params['list'] = $list;
// Twig template
$tplfile = 'apprenant/cerfa_list.html.twig';
return $this->render($tplfile, $this->params);
}
/**
* @Route("/{id}/cerfa", name="cerfa")
*/
public function CERFAAction(Request $request): Response
{
if (!($params = $this->cerfa_params($request)))
die('Paramètres invalides');
extract($params);
//var_dump($session); die();
$cerfa = $this->getCERFA();
$data = $cerfa->cerfa_mapping($id, $customer_id);
$mapping = $data['mapping'];
$cat_list = $data['cat_list'];
$html = '<table style="width: 100%;" border="0" cellpadding="1">';
$cat = '';
$group = '';
foreach($mapping as $name=>$field) {
if (!empty($field['cat']) && $field['cat'] != $cat) {
if ($cat)
$html .= '<tr><td colspan="3"><hr /></td></tr></tbody>';
$cat = $field['cat'];
$html .= '<tr><th>'.$cat_list[$cat]['label'].'</th></tr>';
$html .= '<tbody border="1" style="border: 1px solid black;">';
}
if (!empty($field['group']) && $field['group'] != $group) {
$group = $field['group'];
$html .= '<tr><th>'.$group.'</th></tr>';
}
// Mise en page particulière
if (!empty($field['noauto']))
continue;
$html .= '<tr>';
$html .= '<td class="label"><label for="'.$name.'">'.$field['label'].'</label>';
$html .= '<td>';
$options = [];
if (!empty($field['checkbox_to_radio']))
$options['checkbox_to_radio'] = true;
if ($field['type']=='group') {
foreach($field['list'] as $ename=>$efield) {
if (!is_numeric($ename))
$html .= $this->field_format($ename, $efield, $options);
else
$html .= $efield['info'];
}
}
else
$html .= $this->field_format($name, $field, $options);
$html .= '</td>';
if (!empty($field['help'])) {
$html .= '<td><div class="help_container"><div class="help_icon">?</div><div class="help">'.$field['help'].'</div></div></td>';
}
$html .= '</tr>';
}
$html .= '</tbody></table>';
// History
$repo = $this->em->getRepository('App\\Entity\\CERFA');
$histo = $repo->findBy(['apprenant'=>$id, 'session'=>$session_id]);
//var_dump($histo); die();
$this->params();
$this->params['page']['head']['title'] = 'Formulaire Cerfa '.$apprenant;
$this->params['page']['subtitle'] = 'CERFA '.$apprenant.' pour '.$session;
$this->params['page']['breadcrumbs'][] = [
'route' => static::REF.'_list',
'label' => 'Liste',
];
$this->params['form'] = $html;
$this->params['data'] = $data;
$this->params['cerfa_pdf_url'] = $this->generateUrl('apprenant_cerfa_pdf', ['id'=>$id, 'customer_id'=>$customer_id]);
$this->params['cerfa_save_url'] = $this->generateUrl('apprenant_cerfa_save', ['id'=>$id, 'customer_id'=>$customer_id]);
$this->params['cerfa_api_update_url'] = $this->generateUrl('apprenant_cerfa_api_update', ['id'=>$id, 'customer_id'=>$customer_id]);;
$this->params['cerfa_resync_urls'] = [
['Apprenant', $this->generateUrl('apprenant_api_sync', ['id'=>$data['trainee']['id']])],
['Entreprise', $this->generateUrl('entreprise_api_sync', ['id'=>$data['company']['id']])],
['Session', $this->generateUrl('session_api_sync', ['id'=>$data['session']['id']])],
['Programme', $this->generateUrl('formation_programme_api_sync', ['id'=>$data['program']['id']])],
];
$this->params['cerfa_linked_urls'] = [
['Apprenant', $this->generateUrl('apprenant_read', ['id'=>$apprenant->getID()])],
['Entreprise', $this->generateUrl('entreprise_read', ['id'=>$company->getID()])],
['Customer', $this->generateUrl('entreprise_read', ['id'=>$customer->getID()])],
['Session', $this->generateUrl('session_read', ['id'=>$session->getID()])],
['Programme', $this->generateUrl('formation_programme_read', ['id'=>$program->getID()])],
];
$this->params['cerfa_histo'] = $histo;
// Twig template
$tplfile = 'apprenant/cerfa_form.html.twig';
return $this->render($tplfile, $this->params);
}
/**
* Enregiostre les données à jour dans Digiforma
*
* @Route("/{id}/cerfa_api_update", name="cerfa_api_update")
*/
public function CERFAAPIUpdateAction(Request $request, HttpClientInterface $client): Response
{
if (!($params = $this->cerfa_params($request)))
return new JsonResponse(['r'=>false, 'msg'=>'Paramètres invalides']);
extract($params);
if(empty($u_data))
return new JsonResponse(['r'=>false, 'msg'=>'Missing user data']);
// Mapping
$cerfa = $this->getCERFA();
$mdata = $cerfa->cerfa_mapping($id, $customer_id, $u_data);
//var_dump($mdata['d_data']); die();
//var_dump($u_data, $mdata['mapping']); die();
//var_dump($mdata['mapping']['apprenant_dernierdiplome']['list']['apprenant_dernierdiplome_code']['values']); die();
$rdata = [];
$l = [
'apprenant' => ['updateTrainee', 'traineeInput', 'trainee', 'Apprenant'],
'company' => ['updateCompany', 'companyInput', 'company', 'Entreprise'],
'customer' => ['updateCustomer', 'customerInput', 'customer', 'SessionCustomer'],
'session' => ['updateTrainingSession', 'trainingSessionInput', 'session', 'Session'],
'program' => ['updateProgram', 'programInput', 'program', 'FormationProgramme'],
];
$ok = true;
foreach($mdata['d_data'] as $type=>$data) {
if(!isset($l[$type]))
continue;
$query = <<<'GRAPHQL'
mutation {
\$mutationName(id: \$id, \$inputName: {
\$data
}) {
id
}
}
GRAPHQL;
$dataText = [];
foreach($data as $name=>$value){
if (is_array($value)) {
$valueText = [];
if ($name=='customFields') {
foreach($value as $ename=>$evalue) {
$valueText[] .= '{field: "'.$ename.'", value: "'.(is_array($evalue) ?(!empty($evalue['digi'] ?$evalue['digi'] :$evalue['label'])) :$evalue).'"}';
}
$dataText[] .= $name.': ['."\r\n".implode("\r\n", $valueText)."\r\n".']';
}
else {
foreach($value as $ename=>$evalue) {
$valueText[] .= $ename.': '.$this->digi_value($evalue);
}
$dataText[] .= $name.': {'."\r\n".implode("\r\n", $valueText)."\r\n".'}';
}
}
else {
$dataText[] .= $name.': '.$this->digi_value($value);
}
}
if (empty($dataText))
continue;
$query = str_replace(['\$mutationName', '\$inputName', '\$id', '\$data'], [$l[$type][0], $l[$type][1], $mdata[$l[$type][2]]['id'], implode("\r\n", $dataText)], $query);
//echo '<pre>'.$query.'</pre>';
$repo = $this->em->getRepository('App\\Entity\\'.$l[$type][3]);
$res = $repo->api_query($query, ['user' => 'dunglas']);
if (!$rok = !empty($res['data'][$l[$type][0]]['id']))
$ok = false;
//var_dump($res);
$rdata[] = [$type, $query, $res, $rok];
}
return new JsonResponse(['r'=>$ok, 'data'=>$rdata]);
}
public function digi_value($value)
{
if (is_bool($value))
return $value ?'true' :'false';
elseif (is_int($value) || is_float($value))
return ''.$value;
else
return '"'.$value.'"';
}
public function getCERFA()
{
$classname = '\\App\\Classes\\CERFA_10103_'.static::CERFA_PDF_NUM;
$cerfa = new $classname($this->em);
return $cerfa;
}
/**
* Enregistre les données mises à jour localement
*
* @Route("/{id}/cerfa_save", name="cerfa_save")
*/
public function CERFASaveAction(Request $request, HttpClientInterface $client): Response
{
if (!($params = $this->cerfa_params($request)))
die('Paramètres invalides');
extract($params);
if(empty($u_data))
die('Missing user data');
// Mapping
$cerfa = $this->getCERFA();
$mdata = $cerfa->cerfa_mapping($id, $customer_id, $u_data);
$o_data = $mdata['o_data'];
//var_dump($o_data); die();
// Enregistrement des données du CERFA en local
$object = new \App\Entity\CERFA();
$object->setSession($session);
$object->setApprenant($apprenant);
$object->setData(json_encode($u_data));
$this->em->persist($object);
// Apprenant
$apprenant->setCERFAData($o_data['apprenant']);
$this->em->persist($apprenant);
// Company
$company->setCERFAData($o_data['company']);
$this->em->persist($company);
// Customer
$customer->setCERFAData($o_data['customer']);
$this->em->persist($customer);
// Session
$session->setCERFAData($o_data['session']);
$this->em->persist($session);
// Program
if (!empty($program)) {
$program->setCERFAData($o_data['program']);
$this->em->persist($program);
}
$this->em->flush();
// Save cerfa related informations into digiforma
//$html = '';
return new JsonResponse(['r'=>true]);
}
/**
* @Route("/{id}/cerfa_pdf", name="cerfa_pdf")
*/
public function CERFAPDFAction(Request $request): Response
{
if (!($params = $this->cerfa_params($request)))
die('Paramètres invalides');
extract($params);
// Mapping
$cerfa = $this->getCERFA();
$mdata = $cerfa->cerfa_mapping($id, $customer_id);
$mapping = $mdata['mapping'];
$pdf_data = [];
//var_dump($request->request->all()); die();
foreach($mapping as $name=>&$field) {
if ($field['type']=='group') {
foreach($field['list'] as $ename=>&$efield) {
if (!empty($efield['pdf_name'])) {
$value = $request->request->get($ename);
if (!is_null($value) && $value != '') {
$efield['value'] = $value;
if (!empty($efield['type'])) {
if ($efield['type']=='date')
$efield['value'] = implode('/', array_reverse(explode('-', $efield['value'])));
}
$pdf_data[$efield['pdf_name']] = $efield['value'];
}
}
}
unset($efield);
}
else {
if (!empty($field['pdf_name'])) {
$value = $request->request->get($name);
if (!is_null($value) && $value != '')
$field['value'] = $value;
if (!empty($field['type'])) {
if ($field['type']=='date')
$field['value'] = implode('/', array_reverse(explode('-', $field['value'])));
}
$pdf_data[$field['pdf_name']] = $field['value'];
}
}
}
unset($field);
// PDF
$folder = 'cerfa_filled';
$pdf = new GeneratePdf('cerfa/'.$cerfa->getFilename(), $folder);
$filename = 'cerfa-'.$id.'-'.$session_id.'.pdf';
$ret = $pdf->generate($filename, $pdf_data);
if ($ret !== true) {
return new JsonResponse($pdf_data);
//var_dump($ret);
}
return (new BinaryFileResponse('../data/'.$folder.'/'.$filename, Response::HTTP_OK))
->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'cerfa-'.$id.'-'.$session_id.'-'.$apprenant.'.pdf');
}
/**
* Request analysis to retrieve all CERFA data
* @return []|boolean
*/
public function cerfa_params(Request $request)
{
$id = $request->attributes->get('id');
$apprenant = $this->em->getRepository('App\\Entity\\Apprenant')->find($id);
if (empty($apprenant)) {
throw $this->createNotFoundException('Missing Trainee');
return false;
}
if ($customer_id = $request->query->get('customer_id')) {
$customer = $this->em->getRepository('App\\Entity\\SessionCustomer')->find($customer_id);
$session = $customer->getSession();
$session_id = $session->getID();
}
elseif ($session_id = $request->query->get('session_id'))
{
if ($session = $this->em->getRepository('App\\Entity\\Session')->find($session_id)) {
foreach($session->getCustomers() as $session_customer) {
//var_dump($session_customer);
if ($session_customer->getApprenants()->contains($apprenant)) {
$customer = $session_customer;
$customer_id = $customer->getID();
break;
}
}
}
}
else {
throw $this->createNotFoundException('Missing Session/Customer');
return false;
}
if (empty($customer))
//die('Customer invalide');
return false;
// Données complémentaires
$program = $session->getProgramme();
if (empty($program)) {
throw $this->createNotFoundException('Missing Program');
return false;
}
$company = $customer->getEntreprise();
if (empty($company)) {
throw $this->createNotFoundException('Missing Company');
return false;
}
// User data
$u_data = [];
if (!empty($sdata = $request->get('data'))) {
//var_dump($_POST);
foreach($sdata as $v) {
$u_data[$v['name']] = $v['value'];
}
}
return [
'id' => $id,
'apprenant' => $apprenant,
'customer' => $customer,
'customer_id' => $customer_id,
'session' => $session,
'session_id' => $session_id,
'company' => $company,
'program' => $program,
'u_data' => $u_data,
];
}
/**
* API Setter/Modifier
*/
protected function apisettel($row)
{
if (!empty($row['phone'])) {
return str_replace(' ', '', $row['phone']);
}
return $row['phone'];
}
}