<?php
namespace App\Service;
use App\Entity\OperationSearch;
use Doctrine\ORM\QueryBuilder;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Tools\Pagination\Paginator;
use Symfony\Component\HttpFoundation\Request;
use App\Entity\RefGroupe;
use App\Utils\LibreOfficeWrapper\LibreOffice;
use App\Entity\PersonnelSearch;
use App\Entity\RefFonction;
use App\Entity\RefTypeOperationPaie;
use App\Entity\TblOperationPaie;
use App\Entity\TblPersonnel;
use App\Repository\RefTypeOperationPaieRepository;
use App\Repository\TblOperationPaieRepository;
use App\Repository\TblOperationTravailRepository;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use PhpOffice\PhpWord\TemplateProcessor;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\Security\Core\Security;
use alhimik1986\PhpExcelTemplator\params\ExcelParam;
use App\Entity\RefTypeOperationTravail;
use App\Entity\TblOperationTravail;
use DateTime;
class OperationTravailService
{
/**
* @var EntityManagerInterface $em
*/
private $em;
/**
* @var TblOperationTravailRepository $repository
*/
private $repository;
/**
* @var TblOperationPaieRepository $repositoryPaie
*/
private $repositoryPaie;
/**
* @var RefTypeOperationPaieRepository $repositoryTypePaie
*/
private $repositoryTypePaie;
/**
* @var OperationPaieService $paieService
*/
private $paieService;
/**
* @var UrlGeneratorInterface $router
*/
private $router;
/**
* @var SessionInterface $session
*/
private $session;
/**
* @var ChiffreEnLettreService $chiffreToLettreService
*/
private $chiffreToLettreService;
public function __construct(
EntityManagerInterface $em,
Security $security,
TblOperationTravailRepository $repository,
TblOperationPaieRepository $repositoryPaie,
RefTypeOperationPaieRepository $repositoryTypePaie,
OperationPaieService $paieService,
UrlGeneratorInterface $router,
SessionInterface $session,
ChiffreEnLettreService $chiffreToLettreService,
$template_personnel_opperationPaie_dir,
$template_personnel_opperationPaie_generer_dir
) {
$this->em = $em;
$this->security = $security;
$this->repository = $repository;
$this->repositoryPaie = $repositoryPaie;
$this->repositoryTypePaie = $repositoryTypePaie;
$this->paieService = $paieService;
$this->router = $router;
$this->session = $session;
$this->chiffreToLettreService = $chiffreToLettreService;
$this->template_personnel_opperationPaie_dir= $template_personnel_opperationPaie_dir;
$this->template_personnel_opperationPaie_generer_dir = $template_personnel_opperationPaie_generer_dir;
}
public function getOperationAjax(Request $request, $params)
{
if ($request->getMethod() == 'POST') {
$draw = intval($request->request->get('draw'));
$start = $request->request->get('start');
$length = $request->request->get('length');
$search = $request->request->get('search');
$orders = $request->request->get('order');
$columns = $request->request->get('columns');
} else {
$draw = intval($request->get('draw'));
$start = $request->get('start');
$length = $request->get('length');
$search = $request->get('search');
$orders = $request->get('order');
$columns = $request->get('columns');
}
if ($orders) {
foreach ($orders as $key => $order) {
$orders[$key]['name'] = $columns[$order['column']]['name'];
}
}
$operationQb = $this->getOperationQb($params);
$operationQb = $this->filtersDatatable($operationQb, $orders, $search, $params);
$operationQbCount = clone $operationQb;
$count = $this->getCountOperations($operationQbCount);
$operations = $this->paginateDatatable($operationQb, $start, $length);
$data = ($params["paie"] || $params["resultats-paie"]) ? $this->getDataPaieForDatatable($operations, 'toArrayDatatable') : $this->getDataPointageForDatatable($operations, 'toArrayDatatable');
return [
'draw' => $draw,
'recordsTotal' => $count,
'recordsFiltered' => $count,
'data' => $data
];
}
private function getDataPaieForDatatable($paies, $funcDisplay)
{
$data = [];
foreach ($paies as $paie) {
$urlEdit = $this->router->generate('app_operation_paie_edit', [
'id' => $paie->getId(),
]);
$data[] = $paie->{$funcDisplay}($urlEdit);
}
return $data;
}
private function getDataPointageForDatatable($operations, $funcDisplay)
{
$data = [];
foreach ($operations as $operation) {
$urlEdit = $this->router->generate('app_tbl_operation_travail_edit', [
'id' => $operation->getId(),
]);
$data[] = $operation->{$funcDisplay}($urlEdit);
}
return $data;
}
public function getDataForPointageCalendar($personnel = null)
{
$data = [];
$params = [
"paie" =>false,
"pointage" =>true,
"resultats-paie"=>false,
"resultats-pointage"=>false,
];
$operations = $this->getOperationQb($params)
->getQuery()
->getResult();
foreach ($operations as $operation) {
$data[]= [
'start' => $operation->getDateOperation()->format('Y-m-d'),
'title' => $operation->getPersonnel() .' (' . $operation->getTypeOperationTravail() . ': '. $operation->getMontantTJM() * $operation->getDureeOperationTravail()->getValeurJour() . ' DH)',
'textColor' => 'black',
'extendedProps'=> [
'id'=> $operation->getId()
]
];
}
return $data;
}
public function getDataForPaieCalendar($personnel = null)
{
$data = [];
$params = [
"paie" =>true,
"pointage" =>false,
"resultats-paie"=>false,
"resultats-pointage"=>false,
];
$operations = $this->getOperationQb($params)
->getQuery()
->getResult();
foreach ($operations as $operation) {
$data[]= [
'start' => $operation->getDate()->format('Y-m-d'),
'title' => $operation->getPersonnel() .' : '.$operation->getMontant() .'DH',
'textColor' => 'black',
'extendedProps'=> [
'id'=> $operation->getId()
]
];
}
return $data;
}
public function getMontantDataForPaieCalendar($personnel = null, $groupe = null , $dateDebut = null , $dateFin = null)
{
$data[]= [
'montantTotal' => $this->paieService->getMontantTotal($personnel, $groupe, $dateDebut , $dateFin ),
'montantAvance' => $this->paieService->getMontantAvance($personnel, $groupe, $dateDebut , $dateFin ),
'montantPaye' => $this->paieService->getMontantPaye($personnel, $groupe, $dateDebut , $dateFin),
'montantRestePaye' => $this->paieService->getMontantRestePayer($personnel, $groupe , $dateDebut , $dateFin)
]
;
return $data;
}
private function getCountOperations(QueryBuilder $qb)
{
return (int)$qb->select('COUNT(o)')
->getQuery()
->getSingleScalarResult();
}
private function paginateDatatable(QueryBuilder $qb, $start, $length)
{
$query = $qb->getQuery();
$query->setFirstResult($start)
->setMaxResults($length);
return new Paginator($query);
}
private function getOperationQb($params)
{
$operationQb = ($params["paie"] ? $this->repositoryPaie : $this->repository)->createQueryBuilder('o')
->where('o.deletedAt is NULL');
$operationQb = $this->searchWihSessionForOperation($operationQb, $params);
return $operationQb;
}
private function searchWihSessionForOperation(QueryBuilder $qb, $params)
{
$operationSearch = $this->getSessionForSearch($params);
if (!$operationSearch instanceof OperationSearch) {
$operationSearch = new operationSearch();
}
$qb = $this->repository->searchWithSession($qb, $operationSearch,$params);
return $qb;
}
private function filtersDatatable(QueryBuilder $qb, $orders, $search, $params)
{
return ($params["paie"] ? $this->repositoryPaie : $this->repository)->filterDatatable($qb, $orders, $search);
}
public function getSessionForSearch($params)
{
$searchSession = ($params["paie"] || $params["resultats-paie"] || $params["resultats-pointage"]) ? $this->session->get('operationPaieSearch') : $this->session->get('operationSearch');
return $searchSession;
}
public function setOperationSearchForm()
{
$operationSearch = new OperationSearch();
$operationSearchSession = $this->session->get('operationSearch');
if ($operationSearchSession) {
if ($operationSearchSession->personnel) {
$personnel = $this->em->getRepository(TblPersonnel::class)->find($operationSearchSession->personnel->getId());
$operationSearch->personnel = $personnel;
}
if ($operationSearchSession->groupe) {
$groupe = $this->em->getRepository(RefGroupe::class)->find($operationSearchSession->groupe->getId());
$operationSearch->groupe = $groupe;
}
if ($operationSearchSession->dateDebut) {
$operationSearch->dateDebut = $operationSearchSession->dateDebut;
}
if ($operationSearchSession->dateFin) {
$operationSearch->dateFin = $operationSearchSession->dateFin;
}
}
return $operationSearch;
}
public function setOperationSearchPaieForm($isResultats = false)
{
$operationSearch = new OperationSearch();
$operationSearchSession = $this->session->get('operationPaieSearch');
if(!$isResultats){
//pour le moment afficher que les avances dans calendar
$typeOperation = $this->em->getRepository(RefTypeOperationPaie::class)->find(RefTypeOperationPaie::AVANCE);
$operationSearch->typeOperation = $typeOperation;
}
if ($operationSearchSession) {
if ($operationSearchSession->personnel ) {
$personnel = $this->em->getRepository(TblPersonnel::class)->find($operationSearchSession->personnel->getId());
$operationSearch->personnel = $personnel;
}
if ($operationSearchSession->groupe) {
$groupe = $this->em->getRepository(RefGroupe::class)->find($operationSearchSession->groupe->getId());
$operationSearch->groupe = $groupe;
}
if ($operationSearchSession->typeOperationTravail) {
$typeOperationTravail = $this->em->getRepository(RefTypeOperationTravail::class)->find($operationSearchSession->typeOperationTravail->getId());
$operationSearch->typeOperationTravail = $typeOperationTravail;
}
if ($operationSearchSession->dateDebut) {
$operationSearch->dateDebut = $operationSearchSession->dateDebut;
}
if ($operationSearchSession->dateFin) {
$operationSearch->dateFin = $operationSearchSession->dateFin;
}
}
return $operationSearch;
}
public function setTypeOperationPaie(TblOperationPaie $tblOperationPaie, $typePaie = RefTypeOperationPaie::AVANCE)
{
if(!$tblOperationPaie->getTypeOperation()){
$typePaie = $this->repositoryTypePaie->find(intval($typePaie));
$tblOperationPaie->setTypeOperation($typePaie);
}
return $tblOperationPaie;
}
public function filltblOperationPaieTemplatePdf(TblPersonnel $personnel, $dateDebut , $dateFin )
{
$params = $this->getParamsOperationPaieTemplate($personnel, $dateDebut , $dateFin);
$fileName=$personnel->getNom().'-'.(new DateTime())->format('d-m-Y');
$outputFile = $this->template_personnel_opperationPaie_generer_dir.$fileName.'.docx';
$outputFilePdf = $this->template_personnel_opperationPaie_generer_dir.$fileName.'.pdf';
$templateFileDocx = $this->template_personnel_opperationPaie_dir.'template-justificatif-paie.docx';
$templatePersonnel = new TemplateProcessor($templateFileDocx);
$operationTravails = $this->em->getRepository(TblOperationTravail::class)->getOperationsByDate($personnel, $dateDebut , $dateFin );
$nbrLigne = count($operationTravails) > 0 ? count($operationTravails) : 1 ;
$templatePersonnel->cloneRow('datepointage',$nbrLigne);
if($operationTravails){
foreach($operationTravails as $key => $tblOperationTravail)
{
$templatePersonnel->setValue('datepointage#'.($key+1), $tblOperationTravail->getDateOperation()->format('d/m/Y'));
$templatePersonnel->setValue('nbr_heures#'.($key+1), $tblOperationTravail->getDureeOperationTravail());
$templatePersonnel->setValue('typeoperation#'.($key+1), $tblOperationTravail->getTypeOperationTravail()->getTypeOperation());
$templatePersonnel->setValue('total#'.($key+1), number_format($tblOperationTravail->getMontantTJM()*$tblOperationTravail->getDureeOperationTravail()->getValeurJour(), 2, ',', ' '));
}
$templatePersonnel->setValue('dateFinPaiement', strval( $dateFin ? $dateFin->format('d/m/Y') : $tblOperationTravail->getDateOperation()->format('d/m/Y') )) ;
}else{
$templatePersonnel->setValue('datepointage#1', "--");
$templatePersonnel->setValue('nbr_heures#1', "--");
$templatePersonnel->setValue('typeoperation#1', "--");
$templatePersonnel->setValue('total#1', "--");
$templatePersonnel->setValue('dateFinPaiement', (new DateTime())->format('d/m/Y'));
}
$templatePersonnel->setValue('montantTotal', number_format($this->paieService->getMontantTotalPointage($personnel, null, $dateDebut , $dateFin), 2, ',', ' '));
$templatePersonnel->setValue('heuresTotal', $this->paieService->getHeuresTotal($personnel, $dateDebut , $dateFin ));
$operationPaie = $this->em->getRepository(TblOperationPaie::class)->getOperationsPaieByDate($personnel, $dateDebut , $dateFin );
$nbrLigneOP = count($operationPaie) > 0 ? count($operationPaie) : 1 ;
$templatePersonnel->cloneRow('date',$nbrLigneOP);
if($operationPaie){
foreach($operationPaie as $key => $tblOperationPaie)
{
$templatePersonnel->setValue('date#'.($key+1), $tblOperationPaie->getDate()->format('d/m/Y'));
$templatePersonnel->setValue('type_paiement#'.($key+1), $tblOperationPaie->getTypeOperation());
$templatePersonnel->setValue('nbr_travailler#'.($key+1), number_format($tblOperationPaie->getMontant(), 2, ',', ' '));
$templatePersonnel->setValue('montantAvance', number_format(($this->paieService->getMontantAvance($personnel, null, $dateDebut , $dateFin) + $this->paieService->getMontantPaye($personnel, null, $dateDebut , $dateFin)), 2, ',', ' '));
}
}else{
$templatePersonnel->setValue('date#1', "--");
$templatePersonnel->setValue('type_paiement#1', "--");
$templatePersonnel->setValue('nbr_travailler#1', "--");
$templatePersonnel->setValue('montantAvance', "--");
}
foreach($params as $index => $param)
{
$index = trim($index,"{}");
$templatePersonnel->setValue($index, $param->value);
}
$templatePersonnel->setValue('montantRestePaye', number_format( $this->paieService->getMontantRestePayer($personnel , null, $dateDebut , $dateFin), 2, ',', ' '));
$templatePersonnel->setValue('montanttotal', number_format( $this->paieService-> getMontantTotal( $personnel , null, $dateDebut , $dateFin ), 2, ',', ' '));
$templatePersonnel->saveAs($outputFile);
$libreOffice = new LibreOffice('dev');
$libreOffice->convert_docx_to_pdf($outputFile, $outputFilePdf);
unlink($outputFile);
$response = new BinaryFileResponse($outputFilePdf);
$response->deleteFileAfterSend(true);
$response->headers->set('Content-Type', 'application/pdf');
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_INLINE);
return $response;
}
public function getParamsOperationPaieTemplate(TblPersonnel $personnel , $dateDebut , $dateFin )
{
$params = [
'{nomPrenomPersonnel}' => new ExcelParam(CellSetterStringValue::class, $personnel),
'{codeRHPersonnel}' => new ExcelParam(CellSetterStringValue::class, strval($personnel->getCodeRh())),
'{dateDebutPaiement}' => new ExcelParam(CellSetterStringValue::class, strval($dateDebut ? $dateDebut->format('d/m/Y') : $personnel->getCreatedAt()->format('d/m/Y') ) ),
'{Adresse}' => new ExcelParam(CellSetterStringValue::class, strval($personnel->getVille())),
'{dateDuJour}' => new ExcelParam(CellSetterStringValue::class, (new DateTime())->format('d/m/Y')),
'{montantEnLettre}' => new ExcelParam(CellSetterStringValue::class, strtoupper( $this->chiffreToLettreService->Conversion($this->paieService->getMontantRestePayer($personnel,null, $dateDebut , $dateFin)))),
];
return $params;
}
}