<?php
namespace App\Controller\Paie;
use Mpdf\Mpdf;
use App\Entity\Lrib;
use App\Entity\PPiece;
use App\Entity\PDevise;
use App\Entity\PStatut;
use App\Entity\PDossier;
use App\Entity\Probleme;
use App\Entity\LContract;
use App\Entity\PPaiement;
use App\Entity\Prubrique;
use App\Entity\Tbulletin;
use App\Entity\PBordereau;
use App\Entity\TbulletinLg;
use App\Entity\PnatureContract;
use App\Controller\ApiController;
use App\Entity\InjectRemuneration;
use App\Service\CalculPaieService;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as Reader;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
#[Route('/paie/indeminite')]
class IndeminiteController extends AbstractController
{
private $em;
private $calculPaieService;
private $api;
public function __construct(ManagerRegistry $doctrine, CalculPaieService $calculPaieService, ApiController $api)
{
$this->em = $doctrine->getManager();
$this->calculPaieService = $calculPaieService;
$this->api = $api;
}
#[Route('/', name: 'app_paie_indeminite')]
public function index(Request $request): Response
{
$dossier = $request->getSession()->get('dossier');
$operations = $this->api->check($this->getUser(), 'app_paie_indeminite', $this->em, $request);
if(!is_array($operations)) {
return $this->redirectToRoute('app_site');
}elseif(count($operations) == 0) {
return $this->render('includes/404.html.twig');
}
$dossiers = $this->em->getRepository(PDossier::class)->findBy(['active' => true]);
$paiements = $this->em->getRepository(PPaiement::class)->findBy(['active' => true]);
$devises = $this->em->getRepository(PDevise::class)->findBy(['active' => true]);
$elements = $this->em->getRepository(Prubrique::class)->findBy(['indeminite' => true, 'active' => true]);
$contracts = $this->em->getRepository(LContract::class)->findContractAndRib($dossier);
// dd($contracts);
return $this->render('paie/indeminite/index.html.twig', [
'operations' => $operations,
'paiements' => $paiements,
'devises' => $devises,
'elements' => $elements,
'contracts' => $contracts,
'dossiers' => $dossiers,
]);
}
#[Route('/app_paie_indeminite_add_rib', name: 'app_paie_indeminite_add_rib', options:['expose' => true])]
public function app_paie_indeminite_add_rib(Request $request): Response
{
$dossier = $request->getSession()->get('dossier');
$contract = $this->em->getRepository(LContract::class)->find($request->get('contract'));
if(!preg_match('/^[0-9]{24}$/', $request->get('rib'))) {
return new JsonResponse('RIB incorrect', 500);
}
$existRibActive = $this->em->getRepository(Lrib::class)->findOneBy(['contact_id' => $contract, 'active' => true]);
if($existRibActive) {
return new JsonResponse('RIB déja exist veuillez contacter l\'administrateur!', 500);
}
$rib = new Lrib();
$rib->setDesignation($request->get('rib'));
$rib->setContactId($contract);
$rib->setCreated(new \DateTime());
$this->em->persist($rib);
$this->em->flush();
$contracts = $this->em->getRepository(LContract::class)->findContractAndRib($dossier);
$data = "<option selected value=''>Choix employe</option>";
foreach ($contracts as $object) {
$data .="<option data-rib='".$object['rib']."' data-name='".$object['nom']. " " .$object['prenom']."' value='".$object['id']."'>".$object['nom']. " " .$object['prenom']."</option>";
}
return new JsonResponse(['rib' => $rib->getDesignation(), 'data' => $data]);
}
#[Route('/app_paie_indeminite_get_employe/{dossier}', name: 'app_paie_indeminite_get_employe', options:['expose' => true])]
public function app_paie_indeminite_get_employe(PDossier $dossier): Response
{
$contracts = $this->em->getRepository(LContract::class)->findContractAndRib($dossier);
$data = "<option selected value=''>Choix employe</option>";
foreach ($contracts as $object) {
$data .="<option data-dossier='".$object['abreviation']."' data-dossierid='".$object['dossier_id']."' data-type=".$object['type']." data-rib='".$object['rib']."' data-name='".$object['nom']. " " .$object['prenom']."' value='".$object['id']."'>".$object['nom']. " " .$object['prenom']."</option>";
}
return new JsonResponse(['data' => $data]);
}
#[Route('/app_paie_indeminite_import', name: 'app_paie_indeminite_import', options: ['expose' => true])]
public function app_paie_indeminite_import(Request $request): Response
{
// $dossier = $this->em->getRepository(PDossier::class)->find($request->get('dossier'));
// dd($request);
$reader = new Reader();
$spreadsheet = $reader->load($request->files->get('file'));
$worksheet = $spreadsheet->getActiveSheet();
$spreadSheetArys = $worksheet->toArray();
$paiement = $this->em->getRepository(PPaiement::class)->find($request->get('paiement'));
$devise = $this->em->getRepository(PDevise::class)->find($request->get('devise'));
unset($spreadSheetArys[0]);
$array = [];
$data = [];
// dd($spreadSheetArys);
$count = 0;
foreach ($spreadSheetArys as $key => $sheet) {
$element = $this->em->getRepository(Prubrique::class)->findOneBy(['id' => $sheet[7], 'indeminite' => true, 'active' => true]);
if(!$element) {
return new JsonResponse('Element introuvable à la ligne '.($key + 1).' !', 500);
}
$data [$key]['element']=$element->getId();
$contract = $this->em->getRepository(LContract::class)->findOneBy(['id' => $sheet[0], 'active' => true]);
if(!$contract) {
return new JsonResponse('Contrat introuvable à la ligne '.($key + 1).' !', 500);
}
$data [$key]['dossier']=$contract->getDossier()->getId();
// dd(strtolower($contract->getEmploye()->getCin()), strtolower($sheet[3]));
if(strtolower($contract->getEmploye()->getCin()) != strtolower($sheet[3])) {
return new JsonResponse('le contrat n\'appartient pas à ce cin '.($key + 1).' !', 500);
}
$rib = $this->em->getRepository(Lrib::class)->findOneBy(['contact_id' => $contract, 'code' => $sheet[4], 'active' => true]);
if($paiement->getId() == 1 && !preg_match('/^[0-9]{24}$/', $sheet[4]) && preg_match('/^[0-9\s]+$/', $sheet[4])) {
return new JsonResponse('RIB incorrect à la ligne '.($key + 1).' !', 500);
} elseif ($paiement->getId() == 1 && !$rib) {
return new JsonResponse('vous n\'avez aucun RIB lié a cette contrat à la ligne '.($key + 1).' !', 500);
}
elseif($paiement->getId() == 1 && $rib->getCode() != $sheet[4]) {
return new JsonResponse('Veuillez insérer un RIB lié au même contrat à la ligne '.($key + 1).' !', 500);
}
// Normalize the string by removing all types of whitespace, including non-breaking spaces and other non-standard characters
$montant = preg_replace('/[\p{Z}\s]+/u', '', $sheet[5]);
$montantMad = preg_replace('/[\p{Z}\s]+/u', '', $sheet[6]);
$montant = str_replace(',', '.', $montant);
$montantMad = str_replace(',', '.', $montantMad);
if(is_numeric($montant) === false || is_numeric($montantMad) === false) {
return new JsonResponse('Veuillez insérer un montant à la ligne '.($key + 1).' !', 500);
}
$searchedKey = $this->searchKeyByKeys($array, 'contract', $contract->getId(), 'element_id', $element->getId());
if(!is_null($searchedKey)) {
$array[$searchedKey]['montant'] += $montant;
$array[$searchedKey]['montantMad'] += $montantMad;
} else {
array_push($array, [
'contract' => $contract->getId(),
'name' => ucwords($contract->getEmploye()->getNom() . ' ' . $contract->getEmploye()->getPrenom()),
'montant' => $montant,
'montantMad' => $montantMad,
'element' => $element->getDesignation(),
'element_id' => $element->getId(),
'dossier_abreviation' => $contract->getDossier()->getAbreviation(),
'dossier_id' => $contract->getDossier()->getId(),
'rib' => $rib ? $rib->getCode() : '',
'type' => $contract->getPnatureContract()->getId()
]);
}
}
$data = array_unique(array_map('serialize', $data));
$data = array_map('unserialize', $data);
$data = array_values($data);
$periode = $this->calculPaieService->getPeriode();
foreach($data as $d){
$existingIndeminites = $this->em->getRepository(InjectRemuneration::class)
->createQueryBuilder('i')
->where('i.active = 1 ')
->andWhere('i.type = :type ')
->andWhere('i.periode = :periode')
->andWhere('i.devise = :devise')
->andWhere('i.dossier = :dossier')
->andWhere('i.rubrique = :rubrique')
->setParameter('type', 'indeminite')
->setParameter('periode', $periode)
->setParameter('devise', $devise)
->setParameter('dossier', $this->em->getRepository(PDossier::class)->find($d["dossier"]))
->setParameter('rubrique', $this->em->getRepository(Prubrique::class)->find($d["element"]))
->getQuery()
->getResult();
if($existingIndeminites){
return new JsonResponse(['message' => 'Les indeminites pour la rubrique '.$d["element"].' existe déjà pour le dossier '.$d["dossier"].' dans la periode '.$periode->getCode()]);
}
}
return new JsonResponse($array);
}
#[Route('/app_paie_indeminite_insert', name: 'app_paie_indeminite_insert', options: ['expose' => true])]
public function app_paie_indeminite_insert(Request $request): Response
{
$devise = $this->em->getRepository(PDevise::class)->find($request->get('devise'));
$paiement = $this->em->getRepository(PPaiement::class)->find($request->get('paiement'));
$observation = $request->get('observation');
$periode = $this->calculPaieService->getPeriode();
if($periode->IsValider()) {
return new JsonResponse('Periode est valider !', 500, [], JSON_UNESCAPED_UNICODE);
}
$indeminites = json_decode($request->get('indeminites'));
$netAPayer = $this->em->getRepository(Prubrique::class)->find(5);
$divers = $this->em->getRepository(Prubrique::class)->find(68);
$bordoreauIds = [];
$data=[];
$count=0;
foreach($indeminites as $key => $dossierKey) {
$dossier = $this->em->getRepository(PDossier::class)->find($key);
foreach($dossierKey as $key => $natureKey) {
$bordoreau = new PBordereau;
$bordoreau->setPiece($this->em->getRepository(PPiece::class)->find(6));
$bordoreau->setNatureContract($this->em->getRepository(PnatureContract::class)->find($key));
$bordoreau->setStatut(
$this->em->getRepository(PStatut::class)->find(1)
);
$this->em->persist($bordoreau);
$bordoreau->setPeriode($periode);
$bordoreau->setType('indeminite');
$bordoreau->setPaiement($paiement);
$bordoreau->setDevise($devise);
$bordoreau->setUserCreated($this->getUser());
$bordoreau->setObservation($observation);
$bordoreau->setDossier($dossier);
foreach ($natureKey as $key => $indeminite) {
$contract = $this->em->getRepository(LContract::class)->find($indeminite->contract);
$bulletin = new Tbulletin();
$bulletin->setDossier($dossier);
$bulletin->setDevise($devise);
$bulletin->setPaiement($paiement);
$bulletin->setObservation($observation);
$bulletin->setBordereau($bordoreau);
$bulletin->setContract($contract);
$bulletin->setPeriode($periode);
$bulletin->setPPiece(
$this->em->getRepository(PPiece::class)->find(3)
);
$this->em->persist($bulletin);
$bulletinDet = new TbulletinLg();
$bulletinDet->setBulletin($bulletin);
if($contract->getPnatureContract()->getType()->getId() == 1) {
$bulletinDet->setRubrique($netAPayer);
} else {
$bulletinDet->setRubrique($divers);
}
$bulletinDet->setSens(1);
$bulletinDet->setMontant($indeminite->montantMad);
$bulletinDet->setMontantDevise($indeminite->montant);
$this->em->persist($bulletinDet);
$bulletinDet = new TbulletinLg();
$bulletinDet->setBulletin($bulletin);
$bulletinDet->setRubrique($this->em->getRepository(Prubrique::class)->find($indeminite->element_id));
$bulletinDet->setSens(1);
$bulletinDet->setMontant($indeminite->montantMad);
$bulletinDet->setMontantDevise($indeminite->montant);
$this->em->persist($bulletinDet);
$count++;
$data [$count]['dossier']=$dossier->getId();
$data [$count]['element']=$indeminite->element_id;
}
$this->em->flush();
array_push($bordoreauIds, $bordoreau->getId());
}
}
$data = array_unique(array_map('serialize', $data));
$data = array_map('unserialize', $data);
$data = array_values($data);
// dd($data);
foreach($data as $d){
$InjectRemuneration = new InjectRemuneration();
$InjectRemuneration->setDossier( $this->em->getRepository(PDossier::class)->find($d["dossier"]));
$InjectRemuneration->setDevise($devise);
$InjectRemuneration->setRubrique($this->em->getRepository(Prubrique::class)->find($d["element"]));
$InjectRemuneration->setPeriode($periode);
$InjectRemuneration->setActive(1);
$InjectRemuneration->setType('indeminite');
$InjectRemuneration->setDesignation($request->get('fileIndeminites'));
$this->em->persist($InjectRemuneration);
}
$this->em->flush();
$bordoreauIds = array_unique($bordoreauIds);
if(count($bordoreauIds) > 0) {
$request->request->add(['bordoreauIds' => json_encode($bordoreauIds)]);
}
return new JsonResponse('Bien Enregistrer!');
}
#[Route('/app_paie_indeminite_list/{periode}', name: 'app_paie_indeminite_list', options: ['expose' => true])]
public function app_paie_indeminite_list(Request $request, $periode): Response
{
$date = new \DateTime($periode);
$periode = $this->calculPaieService->getPeriode($date->format('mY'));
$draw = $request->query->get('draw');
$start = $request->query->get('start') ?? 0;
$length = $request->query->get('length') ?? 10;
$search = $request->query->all('search')["value"];
$orderColumnIndex = $request->query->all('order')[0]['column'];
$orderColumn = $request->query->all("columns")[$orderColumnIndex]['name'];
$orderDir = $request->query->all('order')[0]['dir'] ?? 'asc';
$dossier = $request->getSession()->get('dossier');
$queryBuilder = $this->em->createQueryBuilder()
->select('b.code as bulletin, b.id as bulletin_id, contract.id as id, contract.code as contract_code, p.nom as nom, p.matricule as matricule , p.prenom')
->from(LContract::class, 'contract')
->innerJoin('contract.employe', 'p')
->innerJoin('contract.bulletins', 'b')
->innerJoin('b.piece', 'piece')
// ->Where('contract.active = 1')
->Where('b.dossier = :dossier')
->andWhere('b.dossier = :dossier')
->andWhere('b.periode = :periode')
->andWhere('piece.id = 3')
->andWhere('b.active = 1')
->setParameter('dossier', $dossier)
->setParameter('periode', $periode);
if (!empty($search)) {
$queryBuilder->andWhere('(contract.code LIKE :search OR b.code LIKE :search OR p.matricule LIKE :search OR p.nom LIKE :search OR p.prenom LIKE :search)')
->setParameter('search', "%$search%");
}
if (!empty($orderColumn)) {
$queryBuilder->orderBy("$orderColumn", $orderDir);
}
$filteredRecords = count($queryBuilder->getQuery()->getResult());
// Paginate results
$queryBuilder->setFirstResult($start)
->setMaxResults($length)
->orderBy('b.id', 'DESC');
$results = $queryBuilder->getQuery()->getResult();
// dd($results);
foreach ($results as $key => $contract) {
$results[$key]['DT_RowId'] = $contract['id'];
$results[$key]['nombreJourTravails'] = "-";
$results[$key]['salaire'] = '<p style="text-align: right !important; margin:0 !important">'.number_format($this->em->getRepository(Tbulletin::class)->getNetAPaye($contract['bulletin_id']), 2, ',' , ' ').'</p>';
$results[$key]['problemes'] = $this->em->getRepository(Probleme::class)->checkIfTheresProblemes($periode, $contract['id']);
}
// dd($results);
$totalRecords = $this->em->createQueryBuilder()
->select('COUNT(d.id)')
->from(LContract::class, 'd')
->innerJoin('d.bulletins', 'bulletins')
->innerJoin('bulletins.piece', 'piece')
->Where('d.active = 1')
->andWhere('bulletins.dossier = :dossier')
->andWhere('piece.id = 3')
->andWhere('bulletins.periode = :periode')
->setParameter('dossier', $dossier)
->setParameter('periode', $periode)
->getQuery()
->getSingleScalarResult();
return new JsonResponse([
'draw' => $draw,
'recordsTotal' => $totalRecords,
'recordsFiltered' => $filteredRecords,
'data' => $results,
]);
}
function hasMoreThanTwoDecimals($number) {
// Convert the number to a string to handle both integers and floats
$numberStr = strval($number);
// Use a regular expression to check if the number has more than two decimals
// The pattern matches a dot (decimal point), followed by at most two digits
return preg_match('/\.\d{3,}/', $numberStr) === 1;
}
function searchKeyByKeys($array, $key1, $value1, $key2, $value2) {
foreach ($array as $key => $item) {
if ($item[$key1] == $value1 && $item[$key2] == $value2) {
return $key;
}
}
return null; // Return null if not found
}
}