<?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\Pemploye;
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\TypRemuneration;
use App\Entity\PnatureContract;
use App\Controller\ApiController;
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\HttpFoundation\File\Exception\AccessDeniedException;
#[Route('/paie/honoraire')]
class HonoraireController 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_honoraire')]
public function index(Request $request): Response
{
$operations = $this->api->check($this->getUser(), 'app_paie_honoraire', $this->em, $request);
if(!is_array($operations)) {
return $this->redirectToRoute('app_site');
}elseif(count($operations) == 0) {
return $this->render('includes/404.html.twig');
}
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]);
$elementHonoraires = $this->em->getRepository(Prubrique::class)->findBy(['honoraire' => true, 'active' => true]);
$natures = $this->em->getRepository(PnatureContract::class)->findBy(['type' => $this->em->getRepository(TypRemuneration::class)->findBy(['id' => [3, 5]])]);
return $this->render('paie/honoraire/index.html.twig', [
'operations' => $operations,
'natures' => $natures,
'paiements' => $paiements,
'dossiers' => $dossiers,
'devises' => $devises,
'elementHonoraires' => $elementHonoraires,
]);
}
#[Route('/app_paie_honoraire_import/{paiement}', name: 'app_paie_honoraire_import', options: ['expose' => true])]
public function app_paie_honoraire_import(Request $request, PPaiement $paiement): Response
{
// $dossier = $this->em->getRepository(PDossier::class)->find($request->get('dossier'));
$reader = new Reader();
$spreadsheet = $reader->load($request->files->get('file'));
$worksheet = $spreadsheet->getActiveSheet();
$spreadSheetArys = $worksheet->toArray();
unset($spreadSheetArys[0]);
$array = [];
// dd($spreadSheetArys);
$count = 0;
foreach ($spreadSheetArys as $key => $sheet) {
$element = $this->em->getRepository(Prubrique::class)->findOneBy(['id' => $sheet[11], 'honoraire' => true, 'active' => true]);
if(!$element) {
return new JsonResponse('Element introuvable à la ligne '.($key + 1).' !', 500);
}
$contract = $this->em->getRepository(LContract::class)->findOneBy(['id' => $sheet[0],'active' => true]);
if(!$contract) {
return new JsonResponse('Contrat introuvable à la ligne '.($key + 1).' !', 500);
}
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, 'active' => true]);
// dd($rib->getCode(), $sheet[4]);
// if($paiement->getDesignation() == "virement" && !preg_match('/^[0-9]{24}$/', $sheet[4])) {
if($paiement->getDesignation() == "virement" && strlen($sheet[4]) < 24 && preg_match('/^[0-9\s]+$/', $sheet[4])) {
return new JsonResponse('RIB incorrect à la ligne '.($key + 1).' !', 500);
} elseif ($paiement->getDesignation() == "virement" && !$rib) {
return new JsonResponse('vous n\'avez aucun RIB lié a cette contrat à la ligne '.($key + 1).' !', 500);
}
elseif($paiement->getDesignation() == "virement" && $rib->getCode() != $sheet[4]) {
return new JsonResponse('Veuillez insérer un RIB lié au même contrat à la ligne '.($key + 1).' !', 500);
}
$count++;
for ($i=5; $i < 11 ; $i++) {
if($this->hasMoreThanTwoDecimals($sheet[$i])) {
return new JsonResponse('Vous disposez d\'un montant contenant plus de 2 décimales à la ligne '.($key + 1).' !', 500);
}
}
$montant = preg_replace('/[\p{Z}\s]+/u', '', $sheet[5]);
$montant_mad = preg_replace('/[\p{Z}\s]+/u', '', $sheet[6]);
$brute = preg_replace('/[\p{Z}\s]+/u', '', $sheet[7]);
$brute_mad = preg_replace('/[\p{Z}\s]+/u', '', $sheet[8]);
$ir = preg_replace('/[\p{Z}\s]+/u', '', $sheet[9]);
$ir_mad = preg_replace('/[\p{Z}\s]+/u', '', $sheet[10]);
$montant = str_replace(',', '.', $montant);
$montant_mad = str_replace(',', '.', $montant_mad);
$brute = str_replace(',', '.', $brute);
$brute_mad = str_replace(',', '.', $brute_mad);
$ir = str_replace(',', '.', $ir);
$ir_mad = str_replace(',', '.', $ir_mad);
if($ir < 0 or $brute < 0 or $montant < 0) {
return new JsonResponse('Vous un montant négatif à la ligne '.($key + 1).' !', 500);
}
if(number_format(($brute - $ir) - $montant, 2) != 0 or number_format(($brute_mad - $ir_mad) - $montant_mad, 2) != 0) {
return new JsonResponse('Vous un écart à la ligne '.($key + 1).' !', 500);
}
$searchedKey = $this->searchKeyByKeys($array, 'contract_id', $contract->getId(), 'element_id', $element->getId());
// dump($searchedKey);
if(!is_null($searchedKey)) {
$array[$searchedKey]['montant'] += $montant;
$array[$searchedKey]['montant_mad'] += $montant_mad;
$array[$searchedKey]['brute'] += $brute;
$array[$searchedKey]['brute_mad'] += $brute_mad;
$array[$searchedKey]['ir'] += $ir;
$array[$searchedKey]['ir_mad'] += $ir_mad;
} else {
array_push($array, [
'id' => $count,
'nom' => $contract->getEmploye()->getNom(),
'nature_contract' => $contract->getPnatureContract()->getId(),
'prenom' => $contract->getEmploye()->getPrenom(),
'contract_id' => $contract->getId(),
'dossier_id' => $contract->getDossier()->getId(),
'dossier' => $contract->getDossier()->getAbreviation(),
'montant' => $montant,
'montant_mad' => $montant_mad,
'brute' => $brute,
'brute_mad' => $brute_mad,
'ir' => $ir,
'ir_mad' => $ir_mad,
'element_id' => $element->getId(),
'element' => $element->getDesignation(),
'rib' => $rib ? $rib->getCode() : '',
]);
}
}
return new JsonResponse($array);
}
#[Route('/app_paie_honoraire_insert', name: 'app_paie_honoraire_insert', options: ['expose' => true])]
public function app_paie_honoraire_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);
}
$honoraires = json_decode($request->get('honoraires'));
$returnueIR = $this->em->getRepository(Prubrique::class)->find(43);
$divers = $this->em->getRepository(Prubrique::class)->find(68);
$bordoreauIds = [];
// dd($honoraires);
foreach($honoraires as $key => $dossierKey) {
$dossier = $this->em->getRepository(PDossier::class)->find($key);
// dd($dossier);
foreach ($dossierKey as $key => $natureKey) {
$bordoreau = new PBordereau;
$bordoreau->setPiece($this->em->getRepository(PPiece::class)->find(5));
$bordoreau->setDevise($devise);
$bordoreau->setStatut(
$this->em->getRepository(PStatut::class)->find(1)
);
$bordoreau->setPeriode($periode);
$bordoreau->setType('honoraire');
$bordoreau->setPaiement($paiement);
$bordoreau->setNatureContract($this->em->getRepository(PnatureContract::class)->find($key));
$bordoreau->setUserCreated($this->getUser());
$bordoreau->setObservation($observation);
$bordoreau->setDossier($dossier);
$this->em->persist($bordoreau);
foreach ($natureKey as $key => $honoraire) {
// dd($honoraire);
$bulletin = new Tbulletin();
$bulletin->setDossier($dossier);
$bulletin->setDevise($devise);
$bulletin->setPPiece(
$this->em->getRepository(PPiece::class)->find(2)
);
$bulletin->setPaiement($paiement);
$bulletin->setObservation($observation);
$bulletin->setBordereau($bordoreau);
$bulletin->setContract(
$this->em->getRepository(LContract::class)->find($honoraire->contract_id)
);
$bulletin->setPeriode($periode);
$this->em->persist($bulletin);
if($honoraire->ir > 0) {
$bulletinDetRetunueIr = new TbulletinLg();
$bulletinDetRetunueIr->setBulletin($bulletin);
$bulletinDetRetunueIr->setRubrique($returnueIR);
$bulletinDetRetunueIr->setSens(-1);
$bulletinDetRetunueIr->setMontant($honoraire->ir_mad);
$bulletinDetRetunueIr->setMontantDevise($honoraire->ir);
$this->em->persist($bulletinDetRetunueIr);
}
$bulletinDetDivers = new TbulletinLg();
$bulletinDetDivers->setBulletin($bulletin);
$bulletinDetDivers->setRubrique($divers);
$bulletinDetDivers->setSens(1);
$bulletinDetDivers->setMontant($honoraire->montant_mad);
$bulletinDetDivers->setMontantDevise($honoraire->montant);
$this->em->persist($bulletinDetDivers);
$bulletinDet = new TbulletinLg();
$bulletinDet->setBulletin($bulletin);
$bulletinDet->setRubrique($this->em->getRepository(Prubrique::class)->find($honoraire->element_id));
$bulletinDet->setSens(1);
$bulletinDet->setMontant($honoraire->brute_mad);
$bulletinDet->setMontantDevise($honoraire->brute);
$this->em->persist($bulletinDet);
}
$this->em->flush();
array_push($bordoreauIds, $bordoreau->getId());
}
}
$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_honoraire_list/{periode}', name: 'app_paie_honoraire_list', options: ['expose' => true])]
public function app_paie_honoraire_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.dossier = :dossier')
->andWhere('b.dossier = :dossier')
->andWhere('b.periode = :periode')
->andWhere('piece.id = 2')
->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) {
// dd('amine');
// if($contract['id'] == 1301) {
// dd($this->em->getRepository(PArretTravailLg::class)->getNombreJoursArret($contract['id'], $periode));
// }
$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)->getNetAPayeByDevise($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 = 2')
->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
}
}