<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use App\Entity\Commission;
use App\Entity\Customer;
use App\Entity\Device;
use App\Entity\Motif;
use App\Entity\NanoEntrepreneur;
use App\Entity\Network;
use App\Entity\NetworkComment;
use App\Entity\NetworkDevice;
use App\Entity\NetworkHistoric;
use App\Entity\ReadOnly;
use App\Entity\Task;
use App\Entity\Users;
use App\Form\Type\CommissionFormType;
use App\Form\Type\CommissionNanoEntrepreneurFormType;
use App\Form\Type\NetworkFormType;
use App\Manager\NetworkManager;
use App\Manager\RequestParamsManager;
use App\Manager\RoleManager;
use App\Manager\SynchroOdooManager;
use App\Manager\ZoneManager;
use Doctrine\ORM\EntityManagerInterface;
use Knp\Component\Pager\Paginator;
use App\Processor\ProjectWorkflowProcessor;
use Doctrine\ORM\EntityManager;
use PHPExcel_Shared_Date;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpFoundation\StreamedResponse;
use App\Annotation\IgnoreSoftDelete;
use Knp\Component\Pager\PaginatorInterface;
use App\Entity\Zone;
use Doctrine\ORM\QueryBuilder;
use Doctrine\ORM\Tools\Pagination\Paginator as PaginationPaginator;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Knp\Snappy\Pdf;
use Symfony\Component\DependencyInjection\ContainerInterface;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
class NetworkController extends AbstractController
{
private $oNetworkManager;
private $zoneManager;
private $entityManager;
private $requestParamsManager;
private $paginator;
private $_em;
private $oSynchroOdoo;
private $translatorInterface;
private $networkManager;
/**
* @var ContainerInterface
*/
protected $container;
public function __construct(
NetworkManager $oNetworkManager,
ZoneManager $zoneManager,
RequestParamsManager $requestParamsManager,
EntityManagerInterface $em,
SynchroOdooManager $oSynchroOdoo,
ContainerInterface $container,
AuthorizationCheckerInterface $authorizationChecker,
TranslatorInterface $translatorInterface,
EntityManagerInterface $entityManager,
$networkManager = null
) {
$this->oSynchroOdoo = $oSynchroOdoo;
$this->oNetworkManager = $oNetworkManager;
$this->zoneManager = $zoneManager;
$this->requestParamsManager = $requestParamsManager;
$this->_em = $em;
$this->container = $container;
$this->authorizationChecker = $authorizationChecker;
$this->translatorInterface = $translatorInterface;
$this->entityManager = $entityManager;
$this->networkManager = $networkManager;
}
private function setAccessZoneParams(&$queryParams = [])
{
if (!$this->authorizationChecker->isGranted('ROLE_SUPER_ADMIN')) {
$currentUser = $this->container->get('security.token_storage')->getToken()->getUser();
$queryParams['filtered_by_user_zone'] = true;
$queryParams['user_id'] = $currentUser->getId();
$queryParams['zones'] = [];
foreach ($currentUser->getZone() as $zone) {
array_push($queryParams['zones'], $zone->getId());
}
if (
$this->authorizationChecker->isGranted('ROLE_EQUIPE') ||
$this->authorizationChecker->isGranted('ROLE_ADMIN')
) {
$queryParams['access_child_zone'] = true;
}
}
}
/**
* @param EntityManager $em
* @return Response
*/
public function listAction(EntityManager $em, Request $request, TranslatorInterface $translatorInterface, PaginatorInterface $paginatorInterface)
{
$this->denyAccessUnlessGranted(RoleManager::ROLE_ENTREPRENEUR, $this->getUser());
$queryParams['status'] = Network::STATUS_NETWORK;
if (!$this->isGranted(RoleManager::ROLE_EQUIPE, $this->getUser())) {
$queryParams['owner'] = $this->getUser();
}
if ($request->isXmlHttpRequest()) {
$queryParams = array_merge($queryParams, $this->requestParamsManager->initQueryParams($request));
$this->setAccessZoneParams($queryParams);
$networks = $em->getRepository('App\Entity\Network')->searchQuery($queryParams);
$this->paginator = $paginatorInterface;
$networks = $this->paginator->paginate(
$networks, /* query NOT result */
$request->query->getInt('page', 1)/*page number*/,
$request->query->getInt('limit', 25)/*limit per page*/,
array('wrap-queries' => true)
);
// foreach ($networks as $net) {
// return print_r($net);
// break;
// }
$table = $this->renderView(
"@App/Network/table.html.twig",
array(
'networks' => $networks
)
);
$response = new Response(json_encode([
'table' => $table,
]));
$response->headers->set('Content-Type', 'application/json');
return $response;
}
$zonesTypes['zones'] = $this->zoneManager->getAllZoneType();
$zonesTypes['types'] = ['TYPE_ZONE'];
$allDistrict = $this->zoneManager->getAllDistrict();
$district = $request->query->get('district_id');
$nanoEntrepneneur = $request->query->get('ne_id');
$limits = [10, 25, 50, 100];
return $this->render('@App/Network/list.html.twig', [
'isXmlHttpRequest' => false,
'pageTitle' => $translatorInterface->trans('Nano-Grids'),
'types' => $zonesTypes['types'],
'zones' => $zonesTypes['zones'],
'limits' => $limits,
'district_id' => $district ? $district : false,
'ne_id' => $nanoEntrepneneur ? $nanoEntrepneneur : false,
'districts' => $allDistrict
]);
}
public function mapAction()
{
if (!$this->isGranted(RoleManager::ROLE_ENTREPRENEUR, $this->getUser())) {
$this->addFlash('error', 'You are not authorized to access this section');
return $this->redirectToRoute('app.client.list');
}
$queryParams = [];
$em = $this->container->get('doctrine')->getManager();
if (!$this->isGranted(RoleManager::ROLE_EQUIPE, $this->getUser())) {
$queryParams = ['owner' => $this->getUser(), 'status' => 'network'];
} else {
$queryParams = ['status' => 'network'];
}
$networks = $em->getRepository('App\Entity\Network')->findBy($queryParams);
$validCustomer = [];
//Customers with coordinates are considered valid
foreach ($networks as $network) {
$customers = $network->getCustomers();
foreach ($customers as $customer) {
if ($customer->getPicturePath()) {
$img = $this->getParameter('customer_picture_dir') . $customer->getId()
. DIRECTORY_SEPARATOR . $customer->getPicturePath();
} elseif ($customer->getBuilding()->getPicturePath()) {
$img = $this->getParameter('building_picture_dir') . $customer->getBuilding()->getId()
. DIRECTORY_SEPARATOR . $customer->getBuilding()->getPicturePath();
} else {
$img = null;
}
if ($customer->getLocalizationLat() && $customer->getLocalizationLong()) {
$validCustomer[] = [
'status' => $customer->getWorkflowState() === 'validated' ? 'Client' : 'Prospect',
'id' => $customer->getId(),
'lat' => $customer->getLocalizationLat(),
'lng' => $customer->getLocalizationLong(),
'name' => $customer->getFullName(),
'prospectNumber' => $customer->isClient() ? $customer->getCustomNumber() : $customer->getProspectNumber(),
'totalEstimation' => $customer->getTotalPriceEstimation(),
'offer' => $customer->getOffer() ? $customer->getOffer()->getTitle() : null,
'paidFees' => $customer->hasPaidInstallationFees(),
'wall' => $customer->getBuilding()->getWallType() ?: 'N/A',
'roof' => $customer->getBuilding()->getRoofType() ?: 'N/A',
'usage' => $customer->getBuilding()->getUsage() ?: 'N/A',
'img' => $img,
'numClient' => $customer->getCustomNumber(),
'numProspect' => $customer->getProspectNumber()
];
}
}
}
return $this->render('Network/map.html.twig', [
'pageTitle' => 'Nano-' . $translatorInterface->trans('Grid'),
'customers' => $validCustomer,
'networks' => [],
]);
}
/**
* @param Network $network
* @param EntityManager $em
* @return JsonResponse
* @throws \Doctrine\ORM\ORMException
*/
public function getDevicesAction(Network $network, EntityManager $em)
{
$networkDevices = $em->getRepository(Device::class)->getByNetwork($network);
$devices = [];
/** @var Device $networkDevice */
foreach ($networkDevices as $networkDevice) {
$devices[] = [
'id' => $networkDevice->getId(),
'name' => $networkDevice->getName(),
];
}
return new JsonResponse($devices);
}
/**
* @param Network $network
* @param EntityManager $em
* @param Request $request
* @return Response
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function editAction(Network $network, EntityManager $em, Request $request, LoggerInterface $logger, ProjectWorkflowProcessor $processor, TranslatorInterface $translatorInterface)
{
$this->denyAccessUnlessGranted(RoleManager::ROLE_ENTREPRENEUR, $this->getUser());
$form = $this->createForm(NetworkFormType::class, $network, array("user" => $this->getUser(), "removed" => $network->getDeviceDeleted(), "numberNetwork" => $network->getNetworkNumber()));
$form->handleRequest($request);
$zone = $network->getZone();
$user = $this->getUser();
$oReadOnly = $em->getRepository('App\Entity\ReadOnly')->findBy(
array(
'zone' => $zone,
'user' => $user,
)
);
if (!empty($oReadOnly) && is_array($oReadOnly) && !$this->isGranted(RoleManager::ROLE_ADMIN)) {
$this->addFlash('error', $translatorInterface->trans('You cannot edit this nano-grid'));
return $this->redirectToRoute('app.network.list');
}
if ($form->isSubmitted() && $form->isValid()) {
$session = $request->getSession();
if ($session->get('added_customer')) {
$session->remove('added_customer');
}
try {
/*$em->persist($network);
*/
$this->oNetworkManager->updateCustomerZone($network);
$em->flush();
$this->addFlash('success', $translatorInterface->trans('The nano-grid was successfully modified'));
return $this->redirectToRoute('app.network.list');
} catch (\Exception $e) {
$this->addFlash('error', $translatorInterface->trans('An error occurred, please try again'));
$logger->error($e->getMessage(), [__CLASS__ => __FUNCTION__]);
}
}
$transition = Network::TRANSITION_VALIDATE_FINAL_DECISION;
$networkHistoricRepo = $em->getRepository("App\Entity\NetworkHistoric");
$aoNetworkHistoric = $networkHistoricRepo->findBy(array("statut" => $transition, "network" => $network));
$aCustomers = $this->getListCustomer($network, $translatorInterface);
$returnData = [];
$networkId = $network->getId();
$commentData = $em->getRepository("App\Entity\NetworkComment")
->findBy(['owner' => $networkId], ['id' => 'DESC']);
foreach ($commentData as $comment) {
$returnData[] = [
'owner' => $comment->getOwner()->getId(),
'writer' => [
'id' => $comment->getWriter()->getId(),
'name' => $comment->getWriter()->getFirstname() . ' ' . $comment->getWriter()->getLastname()
],
'content' => $comment->getContent(),
'dateCreation' => $comment->getDateCreation()->format('c'),
];
}
return $this->render('@App/Network/form.html.twig', [
'pageTitle' => $translatorInterface->trans('Editing a Nano-grid'),
'network' => $network,
'form' => $form->createView(),
'networkHistorics' => $aoNetworkHistoric,
'customers' => $aCustomers,
'networkComments' => $returnData,
'history' => $network->getDeviceDeleted()
]);
}
private function getListCustomer($networks, TranslatorInterface $translatorInterface)
{
$this->addFlash('error', $translatorInterface->trans('You are not authorized to access this section'));
if (!$this->isGranted(RoleManager::ROLE_ENTREPRENEUR, $this->getUser())) {
$this->addFlash('error', $translatorInterface->trans('You are not authorized to access this section'));
return $this->redirectToRoute('app.client.list');
}
$validCustomers = [];
//Customers with coordinates are considered valid
$customers = $networks->getCustomers();
foreach ($customers as $customer) {
if ($customer->getPicturePath()) {
$img = $this->getParameter('customer_picture_dir') . $customer->getId()
. DIRECTORY_SEPARATOR . $customer->getPicturePath();
} elseif ($customer->getBuilding()->getPicturePath()) {
$img = $this->getParameter('building_picture_dir') . $customer->getBuilding()->getId()
. DIRECTORY_SEPARATOR . $customer->getBuilding()->getPicturePath();
} else {
$img = null;
}
if ($customer->getLocalizationLat() && $customer->getLocalizationLong()) {
$validCustomers[] = [
'status' => $customer->getWorkflowState() === 'validated' ? 'Client' : 'Prospect',
'id' => $customer->getId(),
'lat' => $customer->getLocalizationLat(),
'lng' => $customer->getLocalizationLong(),
'name' => $customer->getFullName(),
'prospectNumber' => $customer->isClient() ? $customer->getCustomNumber() : $customer->getProspectNumber(),
'totalEstimation' => $customer->getTotalPriceEstimation(),
'offer' => $customer->getOffer() ? $customer->getOffer()->getTitle() : null,
'paidFees' => $customer->hasPaidInstallationFees(),
'wall' => $customer->getBuilding()->getWallType() ?: 'N/A',
'roof' => $customer->getBuilding()->getRoofType() ?: 'N/A',
'usage' => $customer->getBuilding()->getUsage() ?: 'N/A',
'img' => $img,
];
}
}
return $validCustomers;
}
/**
* @param Network $network
* @return Response
*/
public function showAction(Network $network)
{
return $this->render('@App/Network/_show_modal.html.twig', [
'network' => $network,
]);
}
/**
* @param EntityManager $em
* @param Network $network
* @return JsonResponse
*/
public function updateNetworkLocationAction(NetworkManager $manager, Request $request, Network $network, TranslatorInterface $translatorInterface)
{
// TODO gestion des roles
$user = $this->getUser();
$canMove = $this->isGranted(RoleManager::ROLE_EQUIPE, $user);
if (!$this->isGranted(RoleManager::ROLE_ENTREPRENEUR, $user)) {
return new JsonResponse([], Response::HTTP_FORBIDDEN);
}
$status = Response::HTTP_OK;
$msg = "%s a été mise à jour";
$statusText = 'ok';
$data = $request->request->all();
if ($canMove) {
try {
$ret = $manager->updateLocation($data, $network);
if (!$ret && $canMove) {
$msg = "%s 'a pas été mise à jour";
$status = Response::HTTP_BAD_REQUEST;
}
} catch (\Exception $e) {
$status = Response::HTTP_BAD_REQUEST;
$statusText = 'ko';
$message = $translatorInterface->trans('An error occurred, please try again');
}
} else {
$msg = $translatorInterface->trans('The request to move') . " %s " . $translatorInterface->trans('has been sent');
$manager->addMoveRequest($network, $user, $data);
}
$message = sprintf($msg, $network->getName());
$toReturn = [
'status' => $statusText,
'message' => $message,
'canMove' => $canMove,
];
return new JsonResponse($toReturn, $status);
}
/**
* @param EntityManager $em
* @return Response
*/
public function commissionListAction(EntityManagerInterface $em, TranslatorInterface $translator, Request $request)
{
$this->denyAccessUnlessGranted(RoleManager::ROLE_ENTREPRENEUR, $this->getUser());
$em->getFilters()->disable('softdeleteable');
// 🔹 Récupération des paramètres GET
$page = max(1, (int) $request->query->get('page', 1));
$limit = (int) $request->query->get('limit', 25);
$offset = ($page - 1) * $limit;
$nanoReseau = trim($request->query->get('nanoReseau', ''));
$nanoEntrepreneur = trim($request->query->get('nanoEntrepreneur', ''));
$district = trim($request->query->get('district', ''));
$dateFrom = $request->query->get('d1');
$dateTo = $request->query->get('d2');
// 🔹 Requête principale
$qb = $em->getRepository(Network::class)->createQueryBuilder('n')
->leftJoin('n.owner', 'o')
->leftJoin('n.zone', 'z')
->where('n.status = :status')
->setParameter('status', Network::STATUS_NETWORK)
->orderBy('n.id', 'ASC');
// 🔹 Requête COUNT séparée
$countQb = $em->getRepository(Network::class)->createQueryBuilder('n')
->select('COUNT(n.id)')
->leftJoin('n.owner', 'o')
->leftJoin('n.zone', 'z')
->where('n.status = :status')
->setParameter('status', Network::STATUS_NETWORK);
// 🔸 Appliquer les filtres aux deux requêtes
$this->applyFilters($qb, $nanoReseau, $nanoEntrepreneur, $district, $dateFrom, $dateTo);
$this->applyFilters($countQb, $nanoReseau, $nanoEntrepreneur, $district, $dateFrom, $dateTo);
// 🔹 Comptage total
$totalItems = (int) $countQb->getQuery()->getSingleScalarResult();
$totalPages = ceil($totalItems / $limit);
// 🔹 Application de la pagination à la requête principale
$qb->setFirstResult($offset)->setMaxResults($limit);
$results = $qb->getQuery()->getResult();
// 🔹 Formatage des données
$aNetworks = [];
foreach ($results as $network) {
$aCommissionEntrepreneurs = $network->getCommissionEntrepreneurs();
$aNanoEntrepreneurs = $network->getNanoEntrepreneurs();
if (!empty($aNanoEntrepreneurs)) {
$aNetworks = array_merge(
$aNetworks,
$this->oNetworkManager->getCommissionForEntrepreneurs($aNanoEntrepreneurs, $network)
);
}
if (empty($aNanoEntrepreneurs) && empty($aCommissionEntrepreneurs)) {
$aNetworks[] = [
'networkId' => $network->getId(),
'networkNumber' => $network->getNetworkNumber(),
'owner' => $network->getOwner()->getFirstname() . ' ' . $network->getOwner()->getLastname(),
'entrepreneurStartDate' => $network->getDateStartService(),
'entrepreneurEndDate' => 'actif',
'commissionStartDate' => $network->getDateStartService(),
'commissionEndDate' => 'actif',
'commission' => $network->getCommissionPercentage(),
'zone' => $network->getZone(),
'network' => $network
];
}
}
$districts = $em->getRepository(Zone::class)->getDistrict();
return $this->render('@App/Network/commissionList.html.twig', [
'networks' => $aNetworks,
'pageTitle' => 'Nano-' . $translator->trans('Grid'),
'districts' => $districts,
'currentPage' => $page,
'totalPages' => $totalPages,
'limit' => $limit,
'totalItems' => $totalItems,
'filters' => [
'nanoReseau' => $nanoReseau,
'nanoEntrepreneur' => $nanoEntrepreneur,
'district' => $district,
'd1' => $dateFrom,
'd2' => $dateTo,
],
]);
}
/**
* 🔸 Applique les filtres aux QueryBuilder
*/
private function applyFilters(QueryBuilder $qb, string $nanoReseau, string $nanoEntrepreneur, string $district, ?string $dateFrom, ?string $dateTo): void
{
// 🔸 Filtre par numéro de NanoGrid
if ($nanoReseau !== '') {
$qb->andWhere('CAST(n.networkNumber AS TEXT) LIKE :nanoReseau')
->setParameter('nanoReseau', '%' . $nanoReseau . '%');
}
// 🔸 Filtre par entrepreneur (nom complet)
if ($nanoEntrepreneur !== '') {
$qb->andWhere('LOWER(CONCAT(o.firstname, \' \', o.lastname)) LIKE :entrepreneur')
->setParameter('entrepreneur', '%' . mb_strtolower($nanoEntrepreneur) . '%');
}
// 🔸 Filtre par district - CORRIGÉ pour matcher "Zone XXXX"
if ($district !== '') {
$decodedDistrict = urldecode($district);
// Si le district commence par "District ", on le remplace par "Zone "
$searchTerm = $decodedDistrict;
if (str_starts_with($searchTerm, 'District ')) {
$searchTerm = str_replace('District ', 'Zone ', $searchTerm);
}
if (is_numeric($searchTerm)) {
$qb->andWhere('z.id = :districtId')
->setParameter('districtId', (int)$searchTerm);
} else {
// Recherche partielle sur le nom complet de la zone
$qb->andWhere('LOWER(z.name) LIKE :districtName')
->setParameter('districtName', '%' . strtolower($searchTerm) . '%');
}
}
// 🔸 Filtre par période
if ($dateFrom && $dateTo) {
$from = \DateTime::createFromFormat('d/m/Y', $dateFrom);
$to = \DateTime::createFromFormat('d/m/Y', $dateTo);
if ($from && $to) {
$to->setTime(23, 59, 59);
$qb->andWhere('n.dateStartService BETWEEN :from AND :to')
->setParameter('from', $from)
->setParameter('to', $to);
}
}
}
/**
* @param Network $network
* @param EntityManager $em
* @param Request $request
* @return Response
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function commissionEditAction(Network $network, EntityManager $em, Request $request, LoggerInterface $logger, TranslatorInterface $translatorInterface)
{
$form = $this->createForm(CommissionNanoEntrepreneurFormType::class, $network);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/*$uow = $em->getUnitOfWork();
$uow->computeChangeSets();*/
foreach ($network->getNanoEntrepreneurs() as $nanoEntrepreneur) {
$this->oNetworkManager->updateTransactionRecordsNanoEntrepreneur($nanoEntrepreneur, $em);
}
foreach ($network->getCommissionEntrepreneurs() as $commission) {
$this->oNetworkManager->updateTransactionRecordsCommission($commission, $em);
}
try {
/** @var Customer $customer */
foreach ($network->getCustomers() as $customer) {
$customer->setCreator($network->getOwner());
}
$em->flush();
$this->addFlash('success', $translatorInterface->trans('Successful change of commission'));
return $this->redirectToRoute('app.commission.list');
} catch (\Exception $e) {
$this->addFlash('error', $translatorInterface->trans('An error occurred, please try again'));
$logger->error($e->getMessage(), [__CLASS__ => __FUNCTION__]);
}
}
return $this->render('@App/Network/commissionForm.html.twig', [
'pageTitle' => $translatorInterface->trans('Change of commission and nano-entrepreneur'),
'network' => $network,
'commissionForm' => $form->createView(),
]);
}
/**
* @param Request $request
* @param EntityManager $em
* @param Network $network
* @param LoggerInterface $logger
* @param TranslatorInterface $translatorInterface
* @return JsonResponse
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function deleteAction(
Request $request,
EntityManagerInterface $em,
Network $network,
LoggerInterface $logger,
TranslatorInterface $translatorInterface
) {
if (!$this->isGranted(RoleManager::ROLE_ADMIN, $this->getUser())) {
return new JsonResponse([
'status' => 'Error',
'message' => $translatorInterface->trans('Access refused'),
], 403);
}
$data = $request->request->get('data');
$data = json_decode($data, true);
if (json_last_error() !== JSON_ERROR_NONE || !is_array($data) || empty($data)) {
return new JsonResponse([
'status' => 'KO',
'message' => 'JSON invalide ou vide'
], 400);
}
// Construction des données à retourner ou utiliser
$nanoEntrepreneurs = '';
if (!empty($network->getNanoEntrepreneurs())) {
$nanoEntrepreneurs = $network->getNanoEntrepreneurs()[0]->getOwner()->getFirstname() . ' ' . $network->getNanoEntrepreneurs()[0]->getOwner()->getLastName();
} else {
$nanoEntrepreneurs = $network->getOwner()->getFirstname() . ' ' . $network->getOwner()->getLastName();
}
$devices = [];
foreach ($network->getDevices() as $device) {
if (empty($device->getUserDelete())) {
$devices[] = [
'name' => $device->getDevice()->getName(),
'deviceCount' => $device->getDeviceCount(),
];
}
}
$dataToUse = [
'networkNumber' => $network->getNetworkNumber(),
'devices' => $devices,
'zone' => $network->getZone(),
'nanoEntrepreneurs' => $nanoEntrepreneurs,
'dateStartService' => $network->getDateStartService(),
];
try {
$aAllCustomers = $network->getCustomers()->toArray();
$firstItem = $data[0] ?? [
"datesup" => null,
"comment" => null,
];
$extraData = [
'dateUninstall' => $firstItem['datesup'] ?? null,
'comment' => $firstItem['comment'] ?? null,
];
$this->oNetworkManager->createHistoricDeletion($network, $extraData, $dataToUse);
$em->remove($network);
$em->flush();
$this->disableCustomerNetwork($aAllCustomers);
} catch (\Exception $e) {
$logger->error($e->getMessage(), [__CLASS__ => __FUNCTION__]);
return new JsonResponse([
'status' => 'KO',
'message' => $e->getMessage()
], 400);
}
return new JsonResponse([
'status' => 'OK'
], 200);
}
public function disableCustomerNetwork($aAllCustomers)
{
foreach ($aAllCustomers as $oCustomer) {
try {
$oCustomer->setNetwork(null);
$oCustomer->setSlotNumber(null);
$oCustomer->setStatus(Customer::STATUS_PROSPECT);
$oCustomer->setDateJoinNetwork(null);
$oCustomer->setCustomNumber(null);
$oCustomer->setDateRemoveFromNetwork(new \DateTime());
$this->_em->persist($oCustomer);
$this->_em->flush();
$this->oSynchroOdoo->disabledClient($oCustomer);
} catch (\Exception $e) {
}
};
}
public function updateCustomersThatNetworkDeleted(EntityManager $em)
{
$customers = $em->getRepository(Network::class)->findCustomersWithDeletedNetworks('2019-01-01');
foreach ($customers as $customer) {
$customer = $em->getRepository(Customer::class)->find($customer['id']);
$customer->setNetwork(null);
$customer->setSlotNumber(null);
$em->persist($customer);
$em->flush();
}
return (count($customers));
}
/**
* @param EntityManager $em
* @param Device $customer
* @param Network $network
* @return JsonResponse
*/
public function removeDeviceAction(EntityManager $em, Request $request, TranslatorInterface $translatorInterface)
{
$dateDeletion = $request->get('dateDeletion');
$motif = $request->get('motif');
$deviceNetworkId = $request->get('deviceNetworkId');
try {
if (!$motif) {
throw new \Exception("Le motif est obligatoire");
}
$networkDevice = $em->getRepository(NetworkDevice::class)
->find($deviceNetworkId);
$networkDevice->setDateDeletion(new \DateTime($dateDeletion));
$networkDevice->setDateRealDeletion(new \DateTime());
$networkDevice->setMotifDeletion(NetworkDevice::DEVICE_DELETION_MOTIF[$motif]);
$networkDevice->setUserDelete($this->getUser());
//$networkDevice->setDevice(null);
//$em->persist($networkDevice);
$em->flush();
$toReturn = [
'status' => 'ok',
'message' => $translatorInterface->trans('the material was successfully removed'),
];
} catch (\Exception $e) {
$toReturn = [
'status' => 'ko',
'message' => $translatorInterface->trans('An error occurred, please try again')
];
}
return new JsonResponse($toReturn);
}
/**
* @param EntityManager $em
* @param Device $customer
* @param Network $network
* @return JsonResponse
*/
public function addDeviceAction(EntityManager $em, Request $request, TranslatorInterface $translatorInterface)
{
try {
if (is_array($data = $request->get('data'))) {
foreach ($data as $aDevice) {
$dateCreation = \DateTime::createFromFormat('Y-m-d', $aDevice['dateCreation']);
$device = $em->getRepository(Device::class)
->findOneBy([
'id' => (int) $aDevice['deviceId']
]);
$network = $em->getRepository(Network::class)
->findOneBy([
'id' => (int) $aDevice['networkId']
]);
$motif = $aDevice['motif'] ? $em->getRepository(Motif::class)
->findOneBy([
'id' => (int) $aDevice['motif']
]) : null;
$networkDevice = new NetworkDevice();
$networkDevice->setDevice($device)
->setNetwork($network)
->setDeviceCount((int) $aDevice['deviceCount'])
->setDateCreation(!empty($dateCreation) ? $dateCreation : new \DateTime())
->setUserCreate($this->getUser());
if ($motif) {
$networkDevice->setMotif($motif);
}
$em->persist($networkDevice);
$em->flush();
$toReturn = [
'status' => 200,
'message' => $translatorInterface->trans('the material has been added successfully'),
];
}
}
} catch (\Exception $e) {
$toReturn = [
'status' => 400,
'message' => $translatorInterface->trans('An error occurred, please try again')
];
}
return new JsonResponse($toReturn);
}
public function getAllEntrepreneurAction(EntityManager $em)
{
$aReturn = [];
$aResponse = [];
$aoEntrepreneur = $em->getRepository('App\Entity\Users')->getAllEntrepreneurs();
foreach ($aoEntrepreneur as $entrepreneur) {
$aReturn['id'] = $entrepreneur->getId();
$aReturn['firstname'] = $entrepreneur->getFirstname();
$aReturn['lastname'] = $entrepreneur->getLastname();
$aResponse[] = $aReturn;
}
return new JsonResponse($aResponse);
}
public function getServiceAction(Network $network)
{
$data = $network->getDateStartService();
return new JsonResponse($data->format("Y-m-d"));
}
public function updateNanoentrepreneurCommissionAction(EntityManager $em)
{
$aNetwork = $em->getRepository('App\Entity\Network')->getNoArrayNC();
foreach ($aNetwork as $oNetwork) {
$param['commissions'] = array(
'startDate' => $oNetwork->getDateStartService(),
'endDate' => null,
'commission' => $oNetwork->getCommissionPercentage()
);
$param['nanoEntrepreneur'] = array(
'startDate' => $oNetwork->getDateStartService(),
'endDate' => null,
'owner' => $oNetwork->getOwner()->getId()
);
$param['id'] = $oNetwork->getId();
$em->getRepository('App\Entity\Network')->updateNanoentrepreneurCommission($param);
}
return new Response("ok");
}
public function migrationNanoEntrepreneurCommissionFromArrayToEntityAction(EntityManager $em)
{
$aNetwork = $em->getRepository('App\Entity\Network')->findAll();
foreach ($aNetwork as $oNetwork) {
$commissions = $oNetwork->getCommissions();
$nanoEntrepreneurs = $oNetwork->getNanoEntrepreneur();
$commissionE = $em->getRepository("App\Entity\Commission")->findOneByNetwork($oNetwork);
$nanoEntrepreneurE = $em->getRepository("App\Entity\NanoEntrepreneur")->findOneByNetwork($oNetwork);
if (count($commissions) > 0 && !$commissionE) {
foreach ($commissions as $commission) {
$oCommission = new Commission();
$oCommission->setStartDate($commission['startDate'] === null ? $oNetwork->getDateCreation() : $commission['startDate']);
$oCommission->setEndDate($commission['endDate']);
$oCommission->setCommission($commission['commission'] !== null ? $commission['commission'] : 0);
$oCommission->setNetwork($oNetwork);
$em->persist($oCommission);
}
}
if (count($nanoEntrepreneurs) > 0 && !$nanoEntrepreneurE) {
foreach ($nanoEntrepreneurs as $nanoEntrepreneur) {
$oNanoEntrepreneur = new NanoEntrepreneur();
$oNanoEntrepreneur->setStartDate($nanoEntrepreneur['startDate'] === null ? $oNetwork->getDateCreation() : $nanoEntrepreneur['startDate']);
$oNanoEntrepreneur->setEndDate($nanoEntrepreneur['endDate']);
$oNanoEntrepreneur->setOwner($em->getRepository('App\Entity\Users')->findOneById($nanoEntrepreneur['owner']));
$oNanoEntrepreneur->setNetwork($oNetwork);
$em->persist($oNanoEntrepreneur);
}
}
}
$em->flush();
return new Response("ok");
}
/**
* @param EntityManager $em
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function historicDeletedNetworkAction(Request $request)
{
$params['action'] = 'remove';
$this->setAccessZoneParams($params);
$networkHistorics = $this->getDoctrine()->getRepository(NetworkHistoric::class)
->getNetworkDeleteHistoricByuserzone($params);
$allDistrict = $this->getDoctrine()->getRepository("App\Entity\Zone")->getDistrict();
return $this->render('Network/historicDeletion.html.twig', [
'networkHistorics' => $networkHistorics,
"districts" => $allDistrict
]);
}
public function generateExcelNetworkAction(Request $request)
{
$queryParams = $this->requestParamsManager->initQueryParams($request);
$queryParams['status'] = Network::STATUS_NETWORK;
$networks = $this->_em->getRepository(Network::class)->searchQuery($queryParams)->getQuery()->getResult();
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setTitle("Liste nano-réseaux");
$i = 1;
$sheet->setCellValue('A' . $i, "Nano-Réseau")->getStyle('A1')->getFont()->setBold(true);
$sheet->setCellValue('B' . $i, "Zone")->getStyle('B1')->getFont()->setBold(true);
$sheet->setCellValue('C' . $i, "District")->getStyle('C1')->getFont()->setBold(true);
$sheet->setCellValue('D' . $i, "Nano-Entrepreneur")->getStyle('D1')->getFont()->setBold(true);
$sheet->setCellValue('E' . $i, "Nombre de clients")->getStyle('E1')->getFont()->setBold(true);
$sheet->setCellValue('F' . $i, "Clients")->getStyle('F1')->getFont()->setBold(true);
$sheet->setCellValue('G' . $i, "Matériels")->getStyle('G1')->getFont()->setBold(true);
$sheet->setCellValue('H' . $i, "Puissance (W)")->getStyle('H1')->getFont()->setBold(true);
$sheet->setCellValue('I' . $i, "Capacité de stockage (Ah)")->getStyle('I1')->getFont()->setBold(true);
$sheet->setCellValue('J' . $i, "Tension (V)")->getStyle('J1')->getFont()->setBold(true);
$sheet->setCellValue('K' . $i, "Date de mise en service")->getStyle('K1')->getFont()->setBold(true);
$sheet->setCellValue('L' . $i, "Date de la dernière maintenance")->getStyle('L1')->getFont()->setBold(true);
$sheet->setCellValue('M' . $i, "Date de la dernière relève")->getStyle('M1')->getFont()->setBold(true);
foreach ($networks as $network) {
$i++;
$CustomersString = null;
$DevicesString = null;
$district = 'N/A';
if ($network->getZone()) {
$district = $network->getZone();
for ($j = 0; $j < 4; $j++) {
$district = $district->getParent();
if ($district->getLevel() === 2)
break;
}
}
foreach ($customers = $network->getCustomers() as $customer) {
$CustomersString .= $customer->getCustomNumber() . ' - ' . $customer->getFirstname() . ' - ' . $customer->getOffer()->getTitle() . ' | ';
}
foreach ($devices = $network->getDevices() as $device) {
if (!$device->getUserDelete()) {
$DevicesString .= $device->getDevice()->getName() . ' - ' . $device->getDeviceCount() . ' | ';
}
}
$sheet->setCellValue('A' . $i, $network->getNetworkNumber());
$sheet->setCellValue('B' . $i, $network->getZone()->getName());
$sheet->setCellValue('C' . $i, $district);
$currentDate = new \DateTime();
// foreach ($network->getNanoEntrepreneurs() as $nanoEntrepreneur) {
// if ($currentDate->format('Y-m-d') >= $nanoEntrepreneur->getStartDate()->format('Y-m-d')
// && ($nanoEntrepreneur->getEndDate() == null || $currentDate->format('Y-m-d') <= $nanoEntrepreneur->getEndDate()->format('Y-m-d'))) {
// $sheet->setCellValue('D'.$i, $nanoEntrepreneur->getOwner()->getFirstname()." ".$nanoEntrepreneur->getOwner()->getLastname());
// break;
// }
// $sheet->setCellValue('D'.$i, $network->getOwner()->getFirstname().' '.$network->getOwner()->getLastname());
// break;
// }
$nanoEntrepreneurName = '';
if (!empty($network->getNanoEntrepreneurs()) && !is_null($network->getNanoEntrepreneurs()[0])) {
$nanoEntrepreneurName = $network->getNanoEntrepreneurs()[0]->getOwner()->getFirstname() . " " . $network->getNanoEntrepreneurs()[0]->getOwner()->getLastname();
} else {
$nanoEntrepreneurName = $network->getOwner()->getFirstname() . " " . $network->getOwner()->getLastName();
}
$sheet->setCellValue('D' . $i, $nanoEntrepreneurName);
$sheet->setCellValue('E' . $i, count($customers));
$sheet->setCellValue('F' . $i, $CustomersString);
$sheet->setCellValue('G' . $i, $DevicesString);
$sheet->setCellValue('H' . $i, $network->getPuissance($devices));
$sheet->setCellValue('I' . $i, $network->getCapaciteStockage($devices));
$sheet->setCellValue('J' . $i, $network->getTotalvoltage());
$dateStartService = null;
if (!is_null($network->getDateStartService())) {
$dateStartService = $network->getDateStartService();
$sheet->setCellValue('K' . $i, \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($network->getDateStartService()->format('d/m/Y')))
->getStyle('K' . $i)
->getNumberFormat()
->setFormatCode('dd/mm/yyyy');
}
$sheet->setCellValue('L' . $i, $network->getInterventions()[0] && $network->getInterventions()[0]->getType() == Task::TYPE_MAINTENANCE ?
\PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($network->getInterventions()[0]->getDateIntervention()) : '')
->getStyle('L' . $i)
->getNumberFormat()
->setFormatCode('dd/mm/yyyy');
$sheet->setCellValue('M' . $i, $network->getInterventions()[0] && $network->getInterventions()[0]->getType() == Task::TYPE_RECORD ?
\PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($network->getInterventions()[0]->getDateIntervention()) : '')
->getStyle('M' . $i)
->getNumberFormat()
->setFormatCode('dd/mm/yyyy');
$this->_em->detach($network);
}
$writer = new Xlsx($spreadsheet);
$response = new StreamedResponse(
function () use ($writer) {
$writer->save('php://output');
}
);
$dispositionHeader = $response->headers->makeDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
'PhpExcelFileSample.xls'
);
foreach (range('A', 'M') as $columnID) {
$sheet->getColumnDimension($columnID)
->setAutoSize(true);
}
$response->headers->set('Content-Type', 'text/vnd.ms-excel; charset=utf-8');
$response->headers->set('Pragma', 'public');
$response->headers->set('Cache-Control', 'maxage=1');
$response->headers->set('Content-Disposition', $dispositionHeader);
return $response;
}
public function generatePdfNetworkAction(Request $request, Pdf $pdf)
{
$queryParams = $this->requestParamsManager->initQueryParams($request);
$queryParams['status'] = Network::STATUS_NETWORK;
$networks = $this->_em->getRepository(Network::class)->searchQuery($queryParams)->getQuery()->getResult();
$network = $this->renderView(
'@App/Network/pdf.html.twig',
[
'networks' => $networks,
'pageTitle' => 'Liste Nano-' . $translatorInterface->trans('Grid'),
]
);
$snappy = $pdf;
$filename = 'Liste_nano-réseaux_' . (new \DateTime('now'))->format('YmdHi');
return new Response(
$snappy->getOutputFromHtml(
$network,
array(
'encoding' => 'utf-8',
)
),
200,
array(
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'inline; filename="' . $filename . '.pdf"'
)
);
}
public function generateCsvNetworkAction(Request $request, TranslatorInterface $translatorInterface)
{
$queryParams = $this->requestParamsManager->initQueryParams($request);
$queryParams['status'] = Network::STATUS_NETWORK;
$networks = $this->_em->getRepository(Network::class)->searchQuery($queryParams)->getQuery()->getResult();
$fileName = "statistiques_clients" . (new \DateTime('now'))->format('YmdHi') . ".csv";
$response = new StreamedResponse();
$response->setCallback(function () use ($networks, $translatorInterface) {
$handle = fopen('php://output', 'w+');
$aTitle = array(
$translatorInterface->trans('Number of Nano-Network'),
'Zone',
'District',
'Nano-Entrepreneur',
$translatorInterface->trans('Number of Customer'),
$translatorInterface->trans('Customers'),
$translatorInterface->trans('Equipments'),
$translatorInterface->trans('Power') . ' (W)',
$translatorInterface->trans('Storage capacity') . ' (Ah)',
$translatorInterface->trans('Voltage') . ' (V)',
$translatorInterface->trans('Commissioning date'),
$translatorInterface->trans('Last maintenance date'),
$translatorInterface->trans('Last Data collection')
);
$aTitle = array_map("utf8_decode", $aTitle);
fputcsv($handle, $aTitle, ';');
$currentDate = new \DateTime();
foreach ($networks as $index => $network) {
$district = 'N/A';
if ($network->getZone()) {
$district = $network->getZone();
for ($j = 0; $j < 4; $j++) {
$district = $district->getParent();
if ($district->getLevel() === 2)
break;
}
}
// foreach ($network->getNanoEntrepreneurs() as $nanoEntrepreneur) {
// if ($currentDate->format('Y-m-d') >= $nanoEntrepreneur->getStartDate()->format('Y-m-d')
// && ($nanoEntrepreneur->getEndDate() == null || $currentDate->format('Y-m-d') <= $nanoEntrepreneur->getEndDate()->format('Y-m-d'))) {
// $entrepreneur = $nanoEntrepreneur->getOwner()->getFirstname();
// break;
// }
// $entrepreneur = $network->getCustomers()->getNetwork()->getOwner()->getFirstname();
// break;
// }
$entrepreneur = '';
if (!empty($network->getNanoEntrepreneurs()) && !is_null($network->getNanoEntrepreneurs()[0])) {
$entrepreneur = $network->getNanoEntrepreneurs()[0]->getOwner()->getFirstname() . " " . $network->getNanoEntrepreneurs()[0]->getOwner()->getLastname();
} else {
$entrepreneur = $network->getOwner()->getFirstname() . " " . $network->getOwner()->getLastName();
}
$CustomersString = null;
$DevicesString = null;
foreach ($customers = $network->getCustomers() as $customer) {
$CustomersString .= $customer->getCustomNumber() . ' - ' . $customer->getFirstname() . ' - ' . $customer->getOffer()->getTitle() . ' | ';
}
foreach ($devices = $network->getDevices() as $device) {
if (!$device->getUserDelete()) {
$DevicesString .= $device->getDevice()->getName() . ' - ' . $device->getDeviceCount() . ' | ';
}
}
$dateStartService = null;
if ($network->getDateStartService()) {
$dateStartService = $network->getDateStartService()->format('d/m/Y');
}
// $entrepreneur = $network->getCustomers()->getNetwork()->getOwner()->getFirstname();
$aBody = array(
$network->getNetworkNumber(),
$network->getZone()->getName(),
$district,
$entrepreneur, //$entrepreneur
count($customers),
$CustomersString,
$DevicesString,
$network->getPuissance($devices),
$network->getCapaciteStockage($devices),
$network->getTotalvoltage(),
$dateStartService,
$network->getInterventions()[0] && $network->getInterventions()[0]->getType() == Task::TYPE_MAINTENANCE ?
$network->getInterventions()[0]->getDateIntervention()->format('d/m/Y') : '',
$network->getInterventions()[0] && $network->getInterventions()[0]->getType() == Task::TYPE_RECORD ?
$network->getInterventions()[0]->getDateIntervention()->format('d/m/Y') : ''
);
$aBody = array_map("utf8_decode", $aBody);
fputcsv($handle, $aBody, ';');
$this->_em->detach($network);
}
fclose($handle);
});
$response->setStatusCode(200);
$response->headers->set('Content-Type', 'text/csv; charset=utf-8', 'application/force-download');
$response->headers->set('Content-Disposition', 'attachment; filename=' . $fileName);
return $response;
}
/**
* @param Request $request
* @param EntityManagerInterface $em
* @return JsonResponse|RedirectResponse|Response
*/
public function saveCommentAction(Request $request, EntityManagerInterface $em)
{
$data = json_decode($request->getContent(), true);
$networkId = $data["network_id"];
$userId = $data["user_id"];
$content = $data["content"];
$commentData = [];
$returnData = [];
try {
//$network = $em->getRepository('App\Entity\Network')->find($networkId); ('App\Entity\Customer')->find($customerId);
$network = $em->getRepository('App\Entity\Network')->find($networkId);
$user = $em->getRepository('App\Entity\Users')->find($userId);
if ($network && $user) {
$networkComment = new NetworkComment();
$networkComment->setOwner($network);
$networkComment->setWriter($user);
$networkComment->setContent($content);
$em->persist($networkComment);
$em->flush();
}
$commentData = $em->getRepository("App\Entity\NetworkComment")
->findBy(['owner' => $networkId], ['id' => 'DESC']);
foreach ($commentData as $comment) {
$returnData[] = [
'owner' => $comment->getOwner()->getId(),
'writer' => [
'id' => $comment->getWriter()->getId(),
'name' => $comment->getWriter()->getFirstname() . ' ' . $comment->getWriter()->getLastname()
],
'content' => $comment->getContent(),
'dateCreation' => $comment->getDateCreation()->format('c'),
];
}
} catch (\RuntimeException $exception) {
return new JsonResponse([
'status' => 'KO',
'message' => $exception->getMessage()
], $exception->getCode());
}
return new JsonResponse([
'status' => 'OK',
'data' => $returnData,
], 200);
}
/**
* @param Request $request
* @param EntityManagerInterface $em
* @return JsonResponse|RedirectResponse|Response
*/
public function listCommentAction(Request $request, EntityManagerInterface $em, Network $network)
{
$commentData = $em->getRepository("App\Entity\NetworkComment")
->findBy(['owner' => $network->getId()], ['id' => 'DESC']);
$returnData = [];
foreach ($commentData as $comment) {
$returnData[] = [
'owner' => $comment->getOwner()->getId(),
'writer' => [
'id' => $comment->getWriter()->getId(),
'name' => $comment->getWriter()->getFirstname() . ' ' . $comment->getWriter()->getLastname()
],
'content' => $comment->getContent(),
'dateCreation' => $comment->getDateCreation()->format('c'),
];
}
return new JsonResponse([
'status' => 'OK',
'data' => $returnData,
], 200);
}
public function export(Request $request, EntityManagerInterface $entityManager): Response
{
$this->denyAccessUnlessGranted(RoleManager::ROLE_ENTREPRENEUR, $this->getUser());
$format = $request->query->get('format', 'csv');
// Récupération simple de tous les réseaux
$networks = $entityManager->getRepository(Network::class)
->findAll();
$records = [];
foreach ($networks as $network) {
$owner = $network->getOwner();
$records[] = [
'networkId' => $network->getId(),
'networkNumber' => $network->getNetworkNumber(),
'owner' => $owner ? $owner->getFirstname() . ' ' . $owner->getLastname() : 'N/A',
'entrepreneurStartDate' => $network->getDateStartService(),
'entrepreneurEndDate' => 'actif',
'commissionStartDate' => $network->getDateStartService(),
'commissionEndDate' => 'actif',
'commission' => $network->getCommissionPercentage(),
'zone' => $network->getZone(),
'district' => $this->getDistrictName($network->getZone())
];
}
// Si toujours vide, utilisez les données de test
if (empty($records)) {
$records = $this->getTestData();
}
switch ($format) {
case 'xlsx':
return $this->exportExcel($records);
case 'pdf':
return $this->exportPdf($records);
default:
return $this->exportCsv($records);
}
}
private function getDistrictName($zone)
{
if (!$zone) {
return 'N/A';
}
$currentZone = $zone;
for ($i = 0; $i < 6; $i++) {
if ($currentZone && $currentZone->getLevel() == 2) {
return $currentZone->getName();
}
if ($currentZone && $currentZone->getParent()) {
$currentZone = $currentZone->getParent();
} else {
break;
}
}
return 'N/A';
}
private function exportCsv(array $records): Response
{
$response = new StreamedResponse(function () use ($records) {
$handle = fopen('php://output', 'w+');
// Optional BOM for Excel/Excel-like programs:
// fwrite($handle, "\xEF\xBB\xBF");
fputcsv($handle, [
'Numéro NanoGrid',
'Nano-Entrepreneur',
'District',
'Date début Nano-Entrepreneur',
'Date fin Nano-Entrepreneur',
'Commission (%)',
'Date début commission',
'Date fin commission'
], ';');
foreach ($records as $record) {
fputcsv($handle, [
$record['networkNumber'] ?? '',
$record['owner'] ?? '',
$record['district'] ?? '',
($record['entrepreneurStartDate'] ?? null) instanceof \DateTime ? $record['entrepreneurStartDate']->format('d/m/Y') : '',
($record['entrepreneurEndDate'] ?? '') == 'actif' ? 'Actif' : (($record['entrepreneurEndDate'] ?? null) instanceof \DateTime ? $record['entrepreneurEndDate']->format('d/m/Y') : ''),
$record['commission'] ?? '',
($record['commissionStartDate'] ?? null) instanceof \DateTime ? $record['commissionStartDate']->format('d/m/Y') : '',
($record['commissionEndDate'] ?? '') == 'actif' ? 'Actif' : (($record['commissionEndDate'] ?? null) instanceof \DateTime ? $record['commissionEndDate']->format('d/m/Y') : '')
], ';');
}
fclose($handle);
});
$disposition = $response->headers->makeDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
'commissions.csv'
);
$response->headers->set('Content-Type', 'text/csv; charset=utf-8');
$response->headers->set('Content-Disposition', $disposition);
return $response;
}
private function exportExcel(array $records): Response
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$headers = [
'Numéro NanoGrid',
'Nano-Entrepreneur',
'District',
'Date début Nano-Entrepreneur',
'Date fin Nano-Entrepreneur',
'Commission (%)',
'Date début commission',
'Date fin commission'
];
$sheet->fromArray([$headers], null, 'A1');
$row = 2;
foreach ($records as $record) {
$sheet->fromArray([[
$record['networkNumber'] ?? '',
$record['owner'] ?? '',
$record['district'] ?? '',
($record['entrepreneurStartDate'] ?? null) instanceof \DateTime ? $record['entrepreneurStartDate']->format('d/m/Y') : '',
($record['entrepreneurEndDate'] ?? '') == 'actif' ? 'Actif' : (($record['entrepreneurEndDate'] ?? null) instanceof \DateTime ? $record['entrepreneurEndDate']->format('d/m/Y') : ''),
$record['commission'] ?? '',
($record['commissionStartDate'] ?? null) instanceof \DateTime ? $record['commissionStartDate']->format('d/m/Y') : '',
($record['commissionEndDate'] ?? '') == 'actif' ? 'Actif' : (($record['commissionEndDate'] ?? null) instanceof \DateTime ? $record['commissionEndDate']->format('d/m/Y') : '')
]], null, 'A' . $row++);
}
// Style pour les en-têtes
$headerStyle = [
'font' => ['bold' => true],
'fill' => [
'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
'startColor' => ['argb' => 'FFE6E6FA']
]
];
$sheet->getStyle('A1:H1')->applyFromArray($headerStyle);
// Auto-size columns
foreach (range('A', 'H') as $column) {
$sheet->getColumnDimension($column)->setAutoSize(true);
}
$writer = new Xlsx($spreadsheet);
$response = new StreamedResponse(function () use ($writer) {
$writer->save('php://output');
});
$disposition = $response->headers->makeDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
'commissions.xlsx'
);
$response->headers->set('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
$response->headers->set('Content-Disposition', $disposition);
return $response;
}
private function exportPdf(array $records): Response
{
set_time_limit(600);
// Limiter les enregistrements pour le PDF
if (count($records) > 20000) {
$records = array_slice($records, 0, 20000);
}
$pdf = new \TCPDF('L', PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
$pdf->SetCreator('Your App');
$pdf->SetAuthor('Your App');
$pdf->SetTitle('Liste des Commissions');
$pdf->SetSubject('Commissions');
$pdf->SetKeywords('commissions, PDF');
$pdf->setHeaderFont([PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN]);
$pdf->setFooterFont([PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA]);
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
$pdf->SetMargins(10, 15, 10);
$pdf->SetHeaderMargin(5);
$pdf->SetFooterMargin(10);
$pdf->SetAutoPageBreak(true, 15);
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
$pdf->SetFont('helvetica', '', 8);
$pdf->AddPage();
// Titre
$pdf->SetFont('helvetica', 'B', 12);
$pdf->Cell(0, 10, 'Liste des Commissions', 0, 1, 'C');
$pdf->SetFont('helvetica', '', 8);
$pdf->Ln(5);
// En-têtes du tableau
$headers = ['NG Number', 'Entrepreneur', 'District', 'Début Entrep.', 'Fin Entrep.', 'Commission', 'Début Comm.', 'Fin Comm.'];
// Largeurs des colonnes
$widths = [20, 30, 25, 20, 20, 15, 20, 20];
// En-têtes
$pdf->SetFillColor(240, 240, 240);
$pdf->SetFont('helvetica', 'B', 7);
foreach ($headers as $i => $header) {
$pdf->Cell($widths[$i], 6, $header, 1, 0, 'C', true);
}
$pdf->Ln();
// Données
$pdf->SetFont('helvetica', '', 6);
$pdf->SetFillColor(255, 255, 255);
foreach ($records as $record) {
$data = [
$record['networkNumber'] ?? '',
$record['owner'] ?? '',
$record['district'] ?? '',
($record['entrepreneurStartDate'] ?? null) instanceof \DateTime ? $record['entrepreneurStartDate']->format('d/m/Y') : '',
($record['entrepreneurEndDate'] ?? '') == 'actif' ? 'Actif' : (($record['entrepreneurEndDate'] ?? null) instanceof \DateTime ? $record['entrepreneurEndDate']->format('d/m/Y') : ''),
$record['commission'] ?? '',
($record['commissionStartDate'] ?? null) instanceof \DateTime ? $record['commissionStartDate']->format('d/m/Y') : '',
($record['commissionEndDate'] ?? '') == 'actif' ? 'Actif' : (($record['commissionEndDate'] ?? null) instanceof \DateTime ? $record['commissionEndDate']->format('d/m/Y') : '')
];
foreach ($data as $i => $value) {
$pdf->Cell($widths[$i], 5, $value, 1, 0, 'C');
}
$pdf->Ln();
// Ajouter une nouvelle page si nécessaire
if ($pdf->GetY() > 180) {
$pdf->AddPage();
// Réafficher les en-têtes
$pdf->SetFont('helvetica', 'B', 7);
foreach ($headers as $i => $header) {
$pdf->Cell($widths[$i], 6, $header, 1, 0, 'C', true);
}
$pdf->Ln();
$pdf->SetFont('helvetica', '', 6);
}
}
return new Response($pdf->Output('commissions.pdf', 'S'), 200, [
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename="commissions.pdf"'
]);
}
}