src/Controller/DefaultController.php line 95

  1. <?php
  2. namespace App\Controller;
  3. use App\Document\TrapData;
  4. use App\Entity\Action;
  5. use App\Entity\Address;
  6. use App\Entity\Area;
  7. use App\Entity\Article;
  8. use App\Entity\ArticleCategory;
  9. use App\Entity\Contract;
  10. use App\Entity\Detergent;
  11. use App\Entity\GroundPlan;
  12. use App\Entity\GroundPlanTraps;
  13. use App\Entity\Log;
  14. use App\Entity\MediaObject;
  15. use App\Entity\Person;
  16. use App\Entity\Project;
  17. use App\Entity\Report;
  18. use App\Entity\Timesheet;
  19. use App\Entity\Trap;
  20. use App\Entity\TrapCategory;
  21. use App\Entity\TrapQuestion;
  22. use App\Entity\TrapScan;
  23. use App\Entity\TrapScanTrap;
  24. use App\Entity\User;
  25. use App\Message\XignalClient;
  26. use App\Service\SoapService;
  27. use Doctrine\ODM\MongoDB\DocumentManager;
  28. use Doctrine\ORM\EntityManagerInterface;
  29. use ErrorException;
  30. use Psr\Log\LoggerInterface;
  31. use Symfony\Bridge\Twig\Mime\TemplatedEmail;
  32. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  33. use Symfony\Component\HttpFoundation\BinaryFileResponse;
  34. use Symfony\Component\HttpFoundation\Request;
  35. use Symfony\Component\HttpFoundation\Response;
  36. use Symfony\Component\HttpClient\HttpClient;
  37. use Symfony\Component\HttpKernel\Exception\HttpException;
  38. use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
  39. use Symfony\Component\HttpKernel\KernelInterface;
  40. use Symfony\Component\Mailer\MailerInterface;
  41. use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
  42. use Symfony\Component\Routing\Annotation\Route;
  43. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  44. use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
  45. class DefaultController extends AbstractController
  46. {
  47.   private $logger;
  48.   private $em;
  49.   private $projectDir;
  50.   private $userPasswordHasher;
  51.   private $mailer;
  52.   private $soap;
  53.   private $documentManager;
  54.   private $xignalClient;
  55.   private $dm;
  56.   private $apiServer;
  57.   private $apiPort;
  58.   private $apiSlug;
  59.   private $apiUsername;
  60.   private $apiPassword;
  61.   private $parameterBag;
  62.   public function __construct(
  63.       $projectDir,
  64.       LoggerInterface $logger,
  65.       EntityManagerInterface $em,
  66.       UserPasswordHasherInterface $userPasswordHasher,
  67.       MailerInterface $mailer,
  68.       SoapService $soap,
  69.       DocumentManager $documentManager,
  70.       XignalClient $xignalClient,
  71.       DocumentManager $dm,
  72.       ParameterBagInterface $parameterBag
  73.   ) {
  74.       $this->logger $logger;
  75.       $this->em $em;
  76.       $this->projectDir $projectDir;
  77.       $this->userPasswordHasher $userPasswordHasher;
  78.       $this->mailer $mailer;
  79.       $this->soap $soap;
  80.       $this->documentManager $documentManager;
  81.       $this->xignalClient $xignalClient;
  82.       $this->dm $dm;
  83.       $this->parameterBag $parameterBag;
  84.       $this->apiServer $parameterBag->get('consolit_api_server');
  85.       $this->apiSlug $parameterBag->get('consolit_api_slug');
  86.       $this->apiUsername $parameterBag->get('consolit_api_username');
  87.       $this->apiPassword $parameterBag->get('consolit_api_password');
  88.   }
  89.   #[Route(path'/')]
  90.   public function home(): Response
  91.   {
  92.     return $this->render('base.html.twig');
  93.   }
  94.   /**
  95.    * Corrector for address names
  96.    */
  97.   #[Route('/corrector_address_names'name'corrector_address_names')]
  98.   public function correctorAddressNames(Request $request): Response
  99.   {
  100.     // Haal alle adressen op
  101.     $addresses $this->em->getRepository(Address::class)->findAll();
  102.     
  103.     // Resultaten bijhouden
  104.     $dryRunResults = [];
  105.     $totalFound 0;
  106.     
  107.     // Regex patroon voor adresherkenning
  108.     // Zoekt naar patronen zoals: "straat 123", "1234 AB", "Plaats", etc.
  109.     $addressPattern '/\s-\s.*(\d+[a-zA-Z]*\s|\d{4}\s?[A-Z]{2}|straat|weg|laan|plein|singel)/i';
  110.     
  111.     // Controleer alle adressen
  112.     foreach ($addresses as $address) {
  113.       $name $address->getName();
  114.       
  115.       // Controleer of de naam een streepje bevat
  116.       if ($name && strpos($name' - ') !== false) {
  117.         // Splits de naam op het eerste streepje
  118.         $parts explode(' - '$name2);
  119.         $afterDash $parts[1] ?? '';
  120.         
  121.         // Sla namen over met "stal" of "PLAEEN" (hoofdletterongevoelig) na het streepje
  122.         if (stripos($afterDash'stal') !== false || stripos($afterDash'PLAEEN') !== false) {
  123.           continue;
  124.         }
  125.         
  126.         $totalFound++;
  127.         $newName trim($parts[0]);
  128.         
  129.         // Controleer of het deel na het streepje op een adres lijkt
  130.         $isLikelyAddress preg_match($addressPattern$name);
  131.         
  132.         // Voeg toe aan resultaten
  133.         $dryRunResults[] = [
  134.           'id' => $address->getId(),
  135.           'uuid' => $address->getUuid(),
  136.           'oldName' => $name,
  137.           'newName' => $newName,
  138.           'isLikelyAddress' => $isLikelyAddress
  139.         ];
  140.       }
  141.     }
  142.     
  143.     // Voer de echte update uit als dit is bevestigd
  144.     if ($request->query->has('confirm') && $request->query->get('confirm') === 'true') {
  145.       $updatedCount 0;
  146.       
  147.       foreach ($dryRunResults as $result) {
  148.         $address $this->em->getRepository(Address::class)->find($result['id']);
  149.         if ($address) {
  150.           $address->setName($result['newName']);
  151.           $updatedCount++;
  152.         }
  153.       }
  154.       
  155.       $this->em->flush();
  156.       
  157.       $html '<html><body>';
  158.       $html .= '<h1>Adres Corrector - Live Run</h1>';
  159.       $html .= '<p>Aantal adressen bijgewerkt: ' $updatedCount ' van ' $totalFound '</p>';
  160.       $html .= '<p><a href="/corrector">Terug naar dry run</a></p>';
  161.       $html .= '</body></html>';
  162.       
  163.       return new Response($html);
  164.     }
  165.     
  166.     // Toon de dry run resultaten
  167.     $html '<html><body>';
  168.     $html .= '<h1>Adres Corrector - Dry Run</h1>';
  169.     $html .= '<p>Totaal aantal adressen met streepje gevonden: ' $totalFound '</p>';
  170.     
  171.     $html .= '<h2>Alle items (' count($dryRunResults) . ')</h2>';
  172.     $html .= '<table border="1" cellpadding="5" style="border-collapse: collapse;">';
  173.     $html .= '<tr><th>ID</th><th>Oude naam</th><th>Nieuwe naam</th><th>Lijkt op adres?</th></tr>';
  174.     
  175.     foreach ($dryRunResults as $result) {
  176.       $html .= '<tr>';
  177.       $html .= '<td>' $result['id'] . '</td>';
  178.       $html .= '<td>' htmlspecialchars($result['oldName']) . '</td>';
  179.       $html .= '<td>' htmlspecialchars($result['newName']) . '</td>';
  180.       $html .= '<td>' . ($result['isLikelyAddress'] ? 'Ja' '<strong style="color: red;">NEE</strong>') . '</td>';
  181.       $html .= '</tr>';
  182.     }
  183.     
  184.     $html .= '</table>';
  185.     
  186.     if (count($dryRunResults) > 0) {
  187.       $html .= '<p><a href="/corrector?confirm=true" style="background-color: #4CAF50; color: white; padding: 10px 20px; text-decoration: none; display: inline-block; margin-top: 20px;">Voer wijzigingen door</a></p>';
  188.     }
  189.     
  190.     $html .= '</body></html>';
  191.     
  192.     return new Response($html);
  193.   }
  194.   #[Route('/import_visit_frequency_and_last_visit'name'cron_import_visit_frequency_and_last_visit')]
  195.   public function importVisitFrequencyAndLastVisit(): Response
  196.   {
  197.     die(); // comment to enable import function
  198.     $csvFilePath 'visit_frequency.csv';
  199.     if (!file_exists($csvFilePath)) {
  200.       $this->logger->error("CSV-bestand niet gevonden op {$csvFilePath}");
  201.       return new Response("CSV-bestand niet gevonden."Response::HTTP_NOT_FOUND);
  202.     }
  203.     $handle fopen($csvFilePath'r');
  204.     if (!$handle) {
  205.       $this->logger->error("Kan CSV-bestand niet openen op {$csvFilePath}");
  206.       return new Response("Kan CSV-bestand niet openen."Response::HTTP_INTERNAL_SERVER_ERROR);
  207.     }
  208.     $updatedCount 0;
  209.     // Lees CSV regels
  210.     while (($data fgetcsv($handle1000';')) !== false) {
  211.       $projectId $data[16] ?? null;      // Projectkaart (kolom 17)
  212.       $eckId $data[17] ?? null;          // Onderdeel (kolom 18)
  213.       $visitFrequency $data[14] ?? null// Normweken (kolom 15)
  214.       $lastVisitDate $data[8] ?? null;   // Afgewerkt (kolom 9)
  215.       if (!$projectId || !$eckId || !is_numeric($visitFrequency) || stripos($data[3] ?? '''TEST TEST TEST') !== false) {
  216.         continue;
  217.       }
  218.       // Zoek adres op basis van Projectkaart en Onderdeel
  219.       $addresses $this->em->getRepository(Address::class)->createQueryBuilder('address')
  220.       ->leftJoin('address.project''project')
  221.       ->where('project.projectId = :projectId')
  222.       ->andWhere('address.eckId = :eckId')
  223.       ->andWhere('address.deletedAt IS NULL')
  224.       ->setParameter('projectId'$projectId)
  225.         ->setParameter('eckId'$eckId)
  226.         ->getQuery()
  227.         ->getResult();
  228.       if (count($addresses)) {
  229.         foreach ($addresses as $address) {
  230.           // Stel bezoekfrequentie in
  231.           $address->setVisitFrequency((int) $visitFrequency);
  232.           // Parse en stel laatste bezoekdatum in
  233.           if ($lastVisitDate) {
  234.             try {
  235.               $lastVisitDateObj \DateTime::createFromFormat('d-m-Y H:i'$lastVisitDate);
  236.               if ($lastVisitDateObj) {
  237.                 $address->setLastVisitDate($lastVisitDateObj);
  238.               }
  239.             } catch (\Exception $e) {
  240.               $this->logger->error("Ongeldige datum in CSV: {$lastVisitDate}");
  241.             }
  242.           }
  243.           $this->em->persist($address);
  244.           $updatedCount++;
  245.         }
  246.       }
  247.     }
  248.     fclose($handle);
  249.     $this->em->flush();
  250.     $this->logger->info("Import voltooid. {$updatedCount} adressen bijgewerkt.");
  251.     return new Response("Import voltooid. {$updatedCount} adressen bijgewerkt.");
  252.   }
  253.   /**
  254.    * Importeer adressen vanuit ObjectenContracten CSV bestanden
  255.    */
  256.   #[Route(path'/addressImporter')]
  257.   public function addressImporter(Request $request): Response
  258.   {
  259.     $csvFiles = [
  260.       => $this->projectDir 'ObjectenContracten.csv',
  261.       => $this->projectDir 'ObjectenContracten_essen.csv',
  262.     ];
  263.     $logs = [];
  264.     $csvData = [];
  265.     foreach ($csvFiles as $werkm => $filePath) {
  266.       if (!file_exists($filePath)) {
  267.         $logs[] = "<b>CSV-bestand niet gevonden:</b> {$filePath}";
  268.         continue;
  269.       }
  270.       $handle fopen($filePath'r');
  271.       if (!$handle) {
  272.         $logs[] = "<b>Kan CSV-bestand niet openen:</b> {$filePath}";
  273.         continue;
  274.       }
  275.       $header fgetcsv($handle0';');
  276.       // Zoek index van eerste kolom 'Onderdeel' (voor eckId)
  277.       $headerMap = [];
  278.       $eckIdIndex null;
  279.       foreach ($header as $idx => $col) {
  280.         $colName trim($col);
  281.         // Sla alleen de eerste 'Onderdeel' index op
  282.         if ($colName === 'Onderdeel' && $eckIdIndex === null) {
  283.           $eckIdIndex $idx;
  284.         }
  285.         $headerMap[$colName] = $idx;
  286.       }
  287.       $rowCount 0;
  288.       $sampleRows = [];
  289.       while (($data fgetcsv($handle0';')) !== false) {
  290.         $rowCount++;
  291.         // Gebruik per werkm de juiste indexen voor projectkaart en eckId
  292.         if ($werkm == 8) { // _essen
  293.           $projectkaart = isset($data[2]) ? trim($data[2]) : null;
  294.           $eckId = isset($data[3]) ? trim($data[3]) : null;
  295.         } else { // standaard
  296.           $projectkaart = isset($data[3]) ? trim($data[3]) : null;
  297.           $eckId = isset($data[4]) ? trim($data[4]) : null;
  298.         }
  299.         if ($projectkaart && $eckId) {
  300.           $csvData[$werkm][(string)$projectkaart][(string)$eckId] = $data;
  301.           if (count($sampleRows) < 3) {
  302.             $sampleRows[] = [
  303.               'projectkaart' => $projectkaart,
  304.               'eckId' => $eckId,
  305.               'row' => $data
  306.             ];
  307.           }
  308.         }
  309.       }
  310.       fclose($handle);
  311.       $logs[] = "CSV geladen: <code>{$filePath}</code>, regels ingelezen: <b>{$rowCount}</b>";
  312.       $logs[] = 'Keys voor werkm ' $werkm ': <code>' htmlspecialchars(json_encode(array_keys($csvData[$werkm] ?? []))) . '</code>';
  313.       $logs[] = 'Voorbeeld eerste 3 entries werkm ' $werkm ': <pre>' htmlspecialchars(print_r($sampleRowstrue)) . '</pre>';
  314.     }
  315.     // Find addresses with missing address data (street, housenumber, postal, city)
  316.     $addresses $this->em->getRepository(Address::class)->createQueryBuilder('address')
  317.       ->leftJoin('address.project''project')
  318.       ->where('address.deletedAt IS NULL')
  319.       ->andWhere('address.street IS NULL OR address.housenumber IS NULL OR address.postal IS NULL OR address.city IS NULL')
  320.       ->getQuery()
  321.       ->getResult();
  322.     $logs[] = 'Aantal adressen met ontbrekende data: <b>' count($addresses) . '</b>';
  323.     $updatedCount 0;
  324.     $batchSize 500;
  325.     // Inverted dry run: default is dry run, only execute if ?live=1
  326.     $dryRun $request->query->get('live''0') !== '1';
  327.     $overview = [];
  328.     foreach ($addresses as $address) {
  329.       $project $address->getProject();
  330.       if (!$project) {
  331.         $logs[] = 'Adres zonder project: <b>' . (method_exists($address'getId') ? $address->getId() : 'onbekend') . '</b>';
  332.         continue;
  333.       }
  334.       $werkm $project->getWerkm();
  335.       if (!isset($csvData[$werkm])) {
  336.         $logs[] = 'Geen CSV data voor werkm: <b>' $werkm '</b> (adres ID: <b>' . (method_exists($address'getId') ? $address->getId() : 'onbekend') . '</b>)';
  337.         continue;
  338.       }
  339.       $projectkaart = (string)trim($project->getProjectId());
  340.       $eckId $address->getEckId();
  341.       $eckIds method_exists($address'getEckIds') ? $address->getEckIds() : [];
  342.       $eckIdsList = [];
  343.       if ($eckId$eckIdsList[] = $eckId;
  344.       if (is_array($eckIds)) {
  345.         foreach ($eckIds as $eid) {
  346.           if ($eid && !in_array($eid$eckIdsListtrue)) {
  347.             $eckIdsList[] = $eid;
  348.           }
  349.         }
  350.       }
  351.       // alles als string getrimd
  352.       $eckIdsList array_map(function($v) { return (string)trim($v); }, $eckIdsList);
  353.       if (!$projectkaart || count($eckIdsList) === 0) {
  354.         $logs[] = 'Adres zonder projectkaart of eckId(s): <b>' . (method_exists($address'getId') ? $address->getId() : 'onbekend') . '</b>';
  355.         continue;
  356.       }
  357.       $row null;
  358.       $matchedEckId null;
  359.       foreach ($eckIdsList as $tryEckId) {
  360.         if (isset($csvData[$werkm][$projectkaart][$tryEckId])) {
  361.           $row $csvData[$werkm][$projectkaart][$tryEckId];
  362.           $matchedEckId $tryEckId;
  363.           break;
  364.         }
  365.       }
  366.       if (!$row) {
  367.         $logs[] = 'Geen match in CSV voor werkm: <b>' $werkm '</b>, projectkaart: <b>' htmlspecialchars($projectkaart) . '</b>, eckIds: <b>' htmlspecialchars(implode(", "$eckIdsList)) . '</b> (adres ID: <b>' . (method_exists($address'getId') ? $address->getId() : 'onbekend') . '</b>)';
  368.         $logs[] = 'Beschikbare projectkaarten voor werkm ' $werkm ': <code>' htmlspecialchars(json_encode(array_keys($csvData[$werkm] ?? []))) . '</code>';
  369.         $logs[] = 'Beschikbare eckIds voor projectkaart ' $projectkaart ': <code>' htmlspecialchars(json_encode(array_keys($csvData[$werkm][$projectkaart] ?? []))) . '</code>';
  370.         continue;
  371.       }
  372.       $logs[] = 'Match gevonden voor adres ID: <b>' . (method_exists($address'getId') ? $address->getId() : 'onbekend') . '</b> op projectkaart <b>' htmlspecialchars($projectkaart) . '</b> en eckId <b>' htmlspecialchars($matchedEckId) . '</b>';
  373.       $changed false;
  374.       $changes = [];
  375.       // Haal adresvelden op via juiste indexen per werkm
  376.       if ($werkm == 8) { // _essen
  377.         $streetIdx 15;
  378.         $housenumberIdx 16;
  379.         $postalIdx 17;
  380.         $cityIdx 18;
  381.       } else {
  382.         $streetIdx 16;
  383.         $housenumberIdx 17;
  384.         $postalIdx 18;
  385.         $cityIdx 19;
  386.       }
  387.       if (!$address->getStreet() && isset($row[$streetIdx]) && trim($row[$streetIdx])) {
  388.         $changes['street'] = trim($row[$streetIdx]);
  389.         if (!$dryRun$address->setStreet(trim($row[$streetIdx]));
  390.         $changed true;
  391.       }
  392.       if (!$address->getHousenumber() && isset($row[$housenumberIdx]) && trim($row[$housenumberIdx])) {
  393.         $parsedHousenumber $this->parseHousenumberToInt(trim($row[$housenumberIdx]));
  394.         $changes['housenumber'] = $parsedHousenumber;
  395.         if (!$dryRun$address->setHousenumber($parsedHousenumber);
  396.         $changed true;
  397.       }
  398.       if (!$address->getPostal() && isset($row[$postalIdx]) && trim($row[$postalIdx])) {
  399.         $changes['postal'] = trim($row[$postalIdx]);
  400.         if (!$dryRun$address->setPostal(trim($row[$postalIdx]));
  401.         $changed true;
  402.       }
  403.       if (!$address->getCity() && isset($row[$cityIdx]) && trim($row[$cityIdx])) {
  404.         $changes['city'] = trim($row[$cityIdx]);
  405.         if (!$dryRun$address->setCity(trim($row[$cityIdx]));
  406.         $changed true;
  407.       }
  408.       if ($changed) {
  409.         $updatedCount++;
  410.         // Add to overview for dry run or reporting
  411.         $overview[] = [
  412.           'addressId' => method_exists($address'getId') ? $address->getId() : null,
  413.           'projectkaart' => $projectkaart,
  414.           'eckId' => $eckId,
  415.           'changes' => $changes,
  416.         ];
  417.         if (!$dryRun) {
  418.           $this->em->persist($address);
  419.           if ($updatedCount $batchSize === 0) {
  420.             $this->em->flush();
  421.             $this->em->clear();
  422.           }
  423.         }
  424.       }
  425.     }
  426.     if (!$dryRun) {
  427.       $this->em->flush();
  428.       $this->em->clear();
  429.     }
  430.     $summary "Corrector " . ($dryRun "(dry run) " "") . "voltooid. {$updatedCount} adressen " . ($dryRun "zouden worden" "bijgewerkt") . ".";
  431.     $logs[] = '<b>' htmlspecialchars($summary) . '</b>';
  432.     // HTML output with all logs and overview
  433.     $html '<!DOCTYPE html><html><head><meta charset="utf-8"><title>Corrector Resultaat</title></head><body>';
  434.     $html .= '<h2>Corrector Resultaat</h2>';
  435.     $html .= '<ul>';
  436.     foreach ($logs as $log) {
  437.       $html .= '<li>' $log '</li>';
  438.     }
  439.     $html .= '</ul>';
  440.     if ($dryRun && count($overview)) {
  441.       $html .= '<h3>Wijzigingen die zouden worden uitgevoerd:</h3>';
  442.       $html .= '<table border="1" cellpadding="4" style="border-collapse:collapse"><tr><th>Address ID</th><th>Projectkaart</th><th>EckId</th><th>Changes</th></tr>';
  443.       foreach ($overview as $row) {
  444.         $html .= '<tr>';
  445.         $html .= '<td>' htmlspecialchars($row['addressId']) . '</td>';
  446.         $html .= '<td>' htmlspecialchars($row['projectkaart']) . '</td>';
  447.         $html .= '<td>' htmlspecialchars($row['eckId']) . '</td>';
  448.         $html .= '<td><pre>' htmlspecialchars(print_r($row['changes'], true)) . '</pre></td>';
  449.         $html .= '</tr>';
  450.       }
  451.       $html .= '</table>';
  452.     }
  453.     $html .= '</body></html>';
  454.     return new Response($html);
  455.   }
  456.   /**
  457.    * Parse a housenumber string to int (returns first integer found, or null if none found)
  458.    */
  459.   private function parseHousenumberToInt(?string $input): ?int
  460.   {
  461.     if (is_null($input) || $input === '') return null;
  462.     if (preg_match('/(\d+)/'$input$matches)) {
  463.       return (int)$matches[1];
  464.     }
  465.     return null;
  466.   }
  467.   #[Route(path'/adrescheck')]
  468.   public function adrescheck(): Response
  469.   {
  470.     $addresses $this->em->getRepository(Address::class)->createQueryBuilder('address')
  471.       ->leftJoin('address.project''project')
  472.       ->where('address.deletedAt IS NULL')
  473.       ->andWhere('address.street IS NULL OR address.housenumber IS NULL OR address.postal IS NULL OR address.city IS NULL')
  474.       ->getQuery()
  475.       ->getResult();
  476.     $html '<!DOCTYPE html><html><head><meta charset="utf-8"><title>Adressen met ontbrekende data</title></head><body>';
  477.     $html .= '<h2>Adressen met ontbrekende data</h2>';
  478.     $html .= '<table border="1" cellpadding="4" style="border-collapse:collapse">';
  479.     $html .= '<tr><th>Address ID</th><th>Projectkaart</th><th>EckId</th><th>Straat</th><th>Huisnummer</th><th>Postcode</th><th>Woonplaats</th></tr>';
  480.     foreach ($addresses as $address) {
  481.       $project $address->getProject();
  482.       $html .= '<tr>';
  483.       $html .= '<td>' htmlspecialchars(method_exists($address'getId') ? $address->getId() : '') . '</td>';
  484.       $html .= '<td>' htmlspecialchars($project && method_exists($project'getProjectId') ? $project->getProjectId() : '') . '</td>';
  485.       $html .= '<td>' htmlspecialchars(method_exists($address'getEckId') ? $address->getEckId() : '') . '</td>';
  486.       $html .= '<td>' htmlspecialchars($address->getStreet()) . '</td>';
  487.       $html .= '<td>' htmlspecialchars($address->getHousenumber()) . '</td>';
  488.       $html .= '<td>' htmlspecialchars($address->getPostal()) . '</td>';
  489.       $html .= '<td>' htmlspecialchars($address->getCity()) . '</td>';
  490.       $html .= '</tr>';
  491.     }
  492.     $html .= '</table>';
  493.     $html .= '<p>Totaal: <b>' count($addresses) . '</b> adressen met ontbrekende data.</p>';
  494.     $html .= '</body></html>';
  495.     return new Response($html);
  496.   }
  497.   #[Route(path'/corrector_report_scores')]
  498.   public function correctorReportScores(): Response
  499.   {
  500.     $isEnabled false;
  501.     $trapQuestions $this->em->getRepository(TrapQuestion::class)->findAll();
  502.     $questions = [];
  503.     foreach ($trapQuestions as $trapQuestion) {
  504.         if ($trapQuestion->isCountsForScore()) {
  505.             $questions[] = $trapQuestion->getId();
  506.         }
  507.     }
  508.     if (count($questions) < 1) {
  509.         return new Response('no questions');
  510.     }
  511.     $projects $this->em->getRepository(Project::class)->findAll();
  512.     if (!count($projects)) {
  513.       return new Response('no projects');
  514.     }
  515.     foreach ($projects as $project) {
  516.       $addresses $this->em->getRepository(Address::class)->findBy(['project' => $project->getId()]);
  517.       if (count($addresses) < 1) {
  518.         continue;
  519.       }
  520.       $i 0;
  521.       foreach ($addresses as $address) {
  522.           $reports $this->em->getRepository(Report::class)->findBy(['address' => $address->getId()]);
  523.           foreach ($reports as $report) {
  524.               $catches 0;
  525.               $trapScans $this->em->getRepository(TrapScan::class)->findBy(['report' => $report->getId()]);
  526.               if (count($trapScans) < 1) {
  527.                   continue;
  528.               }
  529.               foreach ($trapScans as $scan) {
  530.                   $trapData $this->dm->createQueryBuilder(TrapData::class)
  531.                       ->find()
  532.                       ->hydrate(false)
  533.                       ->field('trapScan')->equals($scan->getId())
  534.                       ->field('trapQuestion')->in($questions)
  535.                       ->getQuery()
  536.                       ->execute()
  537.                       ->toArray();
  538.                   if (count($trapData) < 1) {
  539.                       continue;
  540.                   }
  541.                   foreach ($trapData as $data) {
  542.                     if ($data['value'] && (int) $data['value'] > 0) {
  543.                       $catches $catches + (int) $data['value'];
  544.                     }
  545.                   }
  546.               }
  547.               if ($catches <= 1) {
  548.                 $score 'green';
  549.             }
  550.             if ($catches && $catches <= 3) {
  551.                 $score 'orange';
  552.             }
  553.             if ($catches 3) {
  554.                 $score 'red';
  555.             }
  556.             $report->setScore($score);
  557.             $this->em->persist($report);
  558.             $i++;
  559.             if ($isEnabled && ($i 500 == 0)) {
  560.               $this->em->flush();
  561.             }
  562.           }
  563.       }
  564.     }
  565.     if ($isEnabled) {
  566.       $this->em->flush();
  567.     }
  568.     return new Response('processed ' $i ' reports');
  569.   }
  570.   #[Route(path'/start_mqtt_client')]
  571.   public function startMqttClient(): Response
  572.   {
  573.     $this->xignalClient->init();
  574.     return $this->render('base.html.twig');
  575.   }
  576.   #[Route(path'/send_welcome_mail')]
  577.   public function sendWelcomeMail(): Response
  578.   {
  579.       exit('not enabled');
  580.       // TODO: Check for createdAt date to not process EVERY user
  581.       $users $this->em->getRepository(User::class)->findAll();
  582.       foreach ($users as $user) {
  583.           if (== count($user->getAddresses()) || == count($user->getProjects()) || in_array('ROLE_EMPLOYEE'$user->getRoles())) {
  584.               dump('skipping '.$user->getEmail());
  585.               continue;
  586.           }
  587.           // generate password
  588.           $comb 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
  589.           $pass = [];
  590.           $combLen strlen($comb) - 1;
  591.           for ($i 0$i 12; ++$i) {
  592.               $n rand(0$combLen);
  593.               $pass[] = $comb[$n];
  594.           }
  595.           $newPassword implode($pass);
  596.           // update password
  597.           $user->setPassword($this->userPasswordHasher->hashPassword($user$newPassword));
  598.           $user->eraseCredentials();
  599.           $user->setModifiedAt(new \DateTime());
  600.           $this->em->persist($user);
  601.           // send email
  602.           if (!filter_var($user->getEmail(), FILTER_VALIDATE_EMAIL)) {
  603.               dump('incorrect email '.$user->getEmail());
  604.               continue;
  605.           }
  606.           try {
  607.               $message = (new TemplatedEmail());
  608.               $message->sender('noreply@mailgun.vaneckbv.nl');
  609.             $message->replyTo('info@vaneckbv.nl');
  610.             $message->from('Van Eck Bedrijfshygiene <info@vaneckbv.nl>');
  611.               $message->addTo($user->getEmail());
  612.               $message->subject('Welkom in ons digitaal logboek');
  613.               $message->htmlTemplate('Email/welcome.html.twig');
  614.               $message->context([
  615.                   'user' => $user,
  616.                   'password' => $newPassword,
  617.               ]);
  618.               $this->mailer->send($message);
  619.           } catch (ServiceUnavailableHttpException $e) {
  620.               // throw new ServiceUnavailableHttpException('sending_email_failed');
  621.               dump($e->getMessage());
  622.           }
  623.       }
  624.       $this->em->flush();
  625.       return new Response('done');
  626.   }
  627.   #[Route(path'/send_2fa_mail')]
  628.   public function send2FAMail(): Response
  629.   {
  630.       exit('not enabled');
  631.       $users $this->em->getRepository(User::class)->findAll();
  632.       $message = (new TemplatedEmail());
  633.       $message->sender('noreply@mailgun.vaneckbv.nl');
  634.       $message->replyTo('info@vaneckbv.nl');
  635.       $message->from('Van Eck Bedrijfshygiene <info@vaneckbv.nl>');
  636.       $message->subject('Tweestapsverificatie vereist in het Digitale Logboek per 4 april 2023');
  637.       $message->htmlTemplate('Email/introducing_2fa.html.twig');
  638.       $count 0;
  639.       foreach ($users as $user) {
  640.           $count++;
  641.           if (== count($user->getAddresses()) || == count($user->getProjects()) || in_array('ROLE_EMPLOYEE'$user->getRoles())) {
  642.               continue;
  643.           }
  644.           $valid false;
  645.           foreach ($user->getAddresses() as $address) {
  646.             if ($address->getSoapUsername()) {
  647.               $valid true;
  648.             }
  649.           } 
  650.           foreach ($user->getProjects() as $project) {
  651.             if ($project->getSoapUsername()) {
  652.               $valid true;
  653.             }
  654.           }
  655.           if (!$valid) {
  656.             continue;
  657.           }
  658.           // send email
  659.           if (!filter_var($user->getEmail(), FILTER_VALIDATE_EMAIL)) {
  660.               continue;
  661.           }
  662.           try {
  663.               $message->to($user->getEmail());
  664.               $message->context([
  665.                   'user' => $user
  666.               ]);
  667.               $this->mailer->send($message);
  668.           } catch (ServiceUnavailableHttpException $e) {
  669.               // throw new ServiceUnavailableHttpException('sending_email_failed');
  670.               // dump($e->getMessage());
  671.           }
  672.           if(($count%100) == 0) {
  673.               sleep(1);
  674.           }
  675.       }
  676.       return new Response('done');
  677.   }
  678.     
  679.   #[Route(path'/remove_duplicate_areas'name'remove_duplicate_aras'methods: ['GET'])]
  680.   public function cronRemoveDuplicateAreas(Request $request): Response
  681.   {
  682.     exit('DISABLED. COMMENT FIRST LINE TO ENABLE.');
  683.     $addressId $request->query->get('address_id');
  684.     if (!$addressId) {
  685.       return new Response('no address_id provided');
  686.     }
  687.     $areas $this->em->getRepository(Area::class)->findBy(['address' => $addressId], []);
  688.     if (!count($areas)) {
  689.       return new Response('no areas found for address');
  690.     }
  691.     $areaToSet $areas[0];
  692.     foreach ($areas as $area) {
  693.       if ($area->getId() === $areaToSet->getId() || $area->getName() !== $areaToSet->getName()) { // also check if is duplicate by name
  694.         continue;
  695.       }
  696.       $traps $this->em->getRepository(Trap::class)->findBy(['area' => $area->getId()]);
  697.       foreach ($traps as $trap) {
  698.           $trap->setArea($areaToSet);
  699.           $this->em->persist($trap);
  700.       }
  701.       $this->em->remove($area);
  702.       $trapData $this->documentManager->getRepository(TrapData::class)->findBy(['area' => $area->getId()]);
  703.       foreach ($trapData as $data) {
  704.           $data->setArea($areaToSet->getId());
  705.           $this->documentManager->persist($data);
  706.       }
  707.       $this->documentManager->flush();
  708.       $this->em->flush();
  709.     }
  710.     return new Response('done');
  711. }
  712. #[Route(path'/remove_duplicate_traps'name'remove_duplicate_traps'methods: ['GET'])]
  713. public function cronRemoveDuplicateTraps(Request $request): Response
  714. {
  715.   // Activeren middels $isLive wanneer er nieuwe dubbele lokazen in de DB staan, vooraf controleren of het script werkt.
  716.   /////////
  717.   $isLive false;
  718.   /////////
  719.   $addresses $this->em->getRepository(Address::class)->findBy([], []);
  720.   foreach ($addresses as $address) {
  721.     $trapNumbers = [];
  722.     $trapsR $this->em->getRepository(Trap::class)->findBy(['address' => $address->getId()]);
  723.     $traps = [];
  724.     foreach ($trapsR as $trap) {
  725.       if ($trap->getArchivedAt() || $trap->getDeletedAt() || !$trap->getArea()) {
  726.         continue;
  727.       }
  728.       $traps[] = $trap;
  729.       $trapNumbers[] = $trap->getIndentificatie() . '_' . ($trap->getArea() ? $trap->getArea()->getId() : '_no_area');
  730.     }
  731.     $duplicates array_count_values($trapNumbers);
  732.     $duplicates array_diff($duplicates, [1]); // only keep duplicates
  733.     $seenFirst = [];
  734.     $withTrapData = [];
  735.     foreach ($duplicates as $trapNumber => $n) {
  736.       foreach ($traps as $trap) {
  737.         if ($trap->getIndentificatie() . '_' . ($trap->getArea() ? $trap->getArea()->getId() : '_no_area') != $trapNumber) {
  738.           continue;
  739.         }
  740.         if (in_array($trap->getIndentificatie() . '_' . ($trap->getArea() ? $trap->getArea()->getId() : '_no_area'), $seenFirst)) {
  741.           $trapData $this->documentManager->getRepository(TrapData::class)->findBy(['trap' => $trap->getId()]);
  742.           if (!count($trapData)) {
  743.             $this->em->remove($trap);
  744.             $groundPlanTrap $this->em->getRepository(GroundPlanTraps::class)->findOneBy(['trap' => $trap->getId()]);
  745.             if ($groundPlanTrap) {
  746.               $this->em->remove($groundPlanTrap);
  747.             }
  748.             echo 'Deleting ID #' $trap->getId() . ' with indentificatie ' $trap->getIndentificatie() . ' (' $trap->getArea()->getName() . ' - ' $trap->getArea()->getAddress()->getName() .' - ' $trap->getArea()->getAddress()->getProject()->getName() . ')<br /><br />';
  749.           } else {
  750.             echo 'Skipping ID #' $trap->getId() . ' with indentificatie ' $trap->getIndentificatie() . ' (' $trap->getArea()->getName() . ' - ' $trap->getArea()->getAddress()->getName() .' - ' $trap->getArea()->getAddress()->getProject()->getName() . ') - Has trapData - Trying to set trapData to sibling<br />';
  751.             try {
  752.               $siblingTraps $this->em->createQueryBuilder()
  753.                 ->from(Trap::class, 't')
  754.                 ->select('t')
  755.                 ->where('t.number = :number')
  756.                 ->andWhere('t.indentificatie = :indentificatie')
  757.                 ->andWhere('t.area = :area')
  758.                 ->andWhere('t.id <> :id')
  759.                 ->andWhere('t.deletedAt IS NULL')
  760.                 ->setParameter('number'$trap->getNumber())
  761.                 ->setParameter('indentificatie'$trap->getIndentificatie())
  762.                 ->setParameter('area'$trap->getArea())
  763.                 ->setParameter('id'$trap->getId())
  764.                 ->getQuery()
  765.                 ->getResult();
  766.               if (count($siblingTraps)) {
  767.                 foreach ($siblingTraps as $siblingTrap) {
  768.                   $siblingTrapData $this->documentManager->getRepository(TrapData::class)->findOneBy(['trap' => $siblingTrap->getId()]);
  769.                   if (!$siblingTrapData) {
  770.                     echo '-- Sibling with trap ID #' $siblingTrap->getId() . ' has no associated trapData, deleting this trap object instead<br />';
  771.                     $this->em->remove($siblingTrap);
  772.                     $groundPlanTrap $this->em->getRepository(GroundPlanTraps::class)->findOneBy(['trap' => $siblingTrap->getId()]);
  773.                     if ($groundPlanTrap) {
  774.                       $this->em->remove($groundPlanTrap);
  775.                     }
  776.                     echo '-- Deleting ID #' $siblingTrap->getId() . ' with indentificatie ' $siblingTrap->getIndentificatie() . ' (' $siblingTrap->getArea()->getName() . ' - ' $siblingTrap->getArea()->getAddress()->getName() .' - ' $siblingTrap->getArea()->getAddress()->getProject()->getName() . ')<br /><br />';
  777.                   } else {
  778.                     foreach ($trapData as $data) {
  779.                       $data->setTrap($siblingTrap->getId());
  780.                       $this->documentManager->persist($data);
  781.                     }
  782.                     if ($isLive) {
  783.                       $this->documentManager->flush();
  784.                     }
  785.                     echo '-- Reset trapData to trap ID #' $siblingTrap->getId() . '<br />';
  786.                     $this->em->remove($trap);
  787.                     $groundPlanTrap $this->em->getRepository(GroundPlanTraps::class)->findOneBy(['trap' => $trap->getId()]);
  788.                     if ($groundPlanTrap) {
  789.                       $this->em->remove($groundPlanTrap);
  790.                     }
  791.                     echo '-- Deleting ID #' $trap->getId() . ' with indentificatie ' $trap->getIndentificatie() . ' (' $trap->getArea()->getName() . ' - ' $trap->getArea()->getAddress()->getName() .' - ' $trap->getArea()->getAddress()->getProject()->getName() . ')<br /><br />';
  792.                   }
  793.                 }
  794.               } else {
  795.                 echo '-- No sibling traps found for indentificatie ' $trap->getIndentificatie() . ')<br /><br />';
  796.               }
  797.             } catch (\Exception $e) {
  798.               echo '!!-- Error looking for sibling for trap ' $trap->getId() . ': <i>' $e->getMessage() . '</i><br /><br />';
  799.             }
  800.           }
  801.           continue;
  802.         }
  803.         $seenFirst[] = $trap->getIndentificatie() . '_' . ($trap->getArea() ? $trap->getArea()->getId() : '_no_area');
  804.       }
  805.     }
  806.   }
  807.   if ($isLive) {
  808.     $this->em->flush();
  809.   }
  810.   return new Response('done');
  811. }
  812.   #[Route(path'/lokazen_check')]
  813.   public function lokazenCheck(): Response
  814.   {
  815.       /*
  816.       $addressIds = [ 5536, 5539, 5540, 4550, 4551 ];
  817.       $queryBuilder = $this->em->createQueryBuilder()
  818.         ->from(Trap::class, 't')
  819.         ->select('t')
  820.         ->where('v.address IN :addressIds')
  821.         ->setParameter('addressIds', $addressIds);
  822.       $traps = $queryBuilder->getQuery()->getResult();
  823.       foreach ($traps as $trap) {
  824.         if ($trap->getArea()->getAddress() !== $trap->getAddress()) {
  825.           // location exists for the real address?
  826.           $area = $this->em->getRepository(Area::class)->findBy(['address' => $trap->getAddress(), 'name' => $trap->getArea()->getName()]);
  827.           if ($area) {
  828.             $trap->setArea($area);
  829.           } else {
  830.             $area = new Area();
  831.             $area->setAddress($trap->getAddress());
  832.             $area->setName($trap->getArea()->getName());
  833.             $this->em->persist($area);
  834.           }
  835.           $trap->setArea($area);
  836.           $this->em->persist($trap);
  837.           //$this->em->flush();
  838.         }
  839.       }
  840.       */
  841.       return new Response('done');
  842.   }
  843.   #[Route(path'/csv_import')]
  844.   public function csvImport(): Response
  845.   {
  846.     // TODO: 9-11 LIJKT GEREED VOOR IMPORT HYGIENE
  847.       $werkm 2;
  848.       $isLive false;
  849.       $i 0;
  850.       $counter 0;
  851.       $counter2 0;
  852.       $counter3 0;
  853.       $trapcats = [];
  854.       $errors = [];
  855.       $res $this->em->getRepository(TrapCategory::class)->findAll();
  856.       foreach ($res as $v) {
  857.           $trapcats[$v->getCode()] = $v;
  858.       }
  859.       $eckIds = [];
  860.       $addresses $this->em->getRepository(Address::class)->findBy([], []);
  861.       foreach ($addresses as $address) {
  862.         if ($address->getProject()->getWerkm() === $werkm) {
  863.           $eckIds[$address->getEckId()] = $address;
  864.           echo $address->getId() . ' - ';
  865.         }
  866.       }
  867.       $areas = [];
  868.       $groundPlans = [];
  869.       if (($handle fopen('20231025_Objectenvaneck_H.csv''r')) !== false) {
  870.           while (($cols fgetcsv($handlenull';')) !== false) {
  871.               $cols array_map('utf8_encode'$cols);
  872.               if (== $i) {
  873.                   foreach ($cols as $k => $v) {
  874.                       $lookup[$v] = $k;
  875.                   }
  876.               }
  877.               /*
  878.       //
  879.               // OBJECT MI LOGIN/PASS UPDATEN
  880.       //
  881.               if ($i > 0) {
  882.                   if ('A' == substr($cols[2], 0, 1)) {
  883.                       continue;
  884.                   }
  885.                   $projectId = $cols[$lookup['Projectkaart']];
  886.                   $addressId = $cols[$lookup['Onderdeel']];
  887.                   // find or create project
  888.                   $project = $this->em->getRepository(Project::class)->findOneBy(['projectId' => $projectId]);
  889.                   if (!$project) {
  890.                       continue;
  891.                   }
  892.                   $address = $this->em->getRepository(Address::class)->findOneBy(['project' => $project, 'eckId' => $addressId]);
  893.                   if ($address) {
  894.                       if ($cols[$lookup['inlog_debiteur']] && $cols[$lookup['ww_debiteur']]) {
  895.                           $project = $address->getProject();
  896.                           $project->setSoapUsername($cols[$lookup['inlog_debiteur']]);
  897.                           $project->setSoapPassword($cols[$lookup['ww_debiteur']]);
  898.                           $this->em->persist($project);
  899.                       }
  900.                       if ($cols[$lookup['inlog']] && $cols[$lookup['ww']]) {
  901.                           $address->setSoapUsername($cols[$lookup['inlog']]);
  902.                           $address->setSoapPassword($cols[$lookup['ww']]);
  903.                           $this->em->persist($address);
  904.                       }
  905.                   }
  906.                   if (0 == $i % 1000) {
  907.                       $this->em->flush();
  908.                   }
  909.                   ++$i;
  910.               }
  911.               */
  912.               /*
  913.               //
  914.               // OBJECT CONTACT UPDATEN
  915.               //
  916.               if ($i > 0) {
  917.                 if (substr($cols[2], 0, 1) == 'A') {
  918.                   continue;
  919.                 }
  920.                 if ($cols[$lookup['Telecomsoort']] != 'E-mail') {
  921.                   continue;
  922.                 }
  923.                 $projectId = $cols[current($lookup)];
  924.                 // find or create project
  925.                 $project = $this->em->getRepository(Project::class)->findOneBy(['projectId' => $projectId]);
  926.                 if ($project) {
  927.                   if ($cols[$lookup['Nummer']] && strpos($cols[$lookup['Nummer']], '@') !== false) {
  928.                     $project->setEmail($cols[$lookup['Nummer']]);
  929.                   }
  930.                   if ($cols[$lookup['E-mail']] && strpos($cols[$lookup['E-mail']], '@') !== false) {
  931.                     $project->setEmail($cols[$lookup['E-mail']]);
  932.                   }
  933.                   $this->em->persist($project);
  934.                 }
  935.                 if($i % 4000 ==0) {
  936.                   $this->em->flush();
  937.                 }
  938.                 $i++;
  939.               }
  940.               */
  941.       //
  942.               // LOKAZEN UIT OUDE DATABASE
  943.       //
  944.               /*
  945.               if ($i > 0) {
  946.                 $project = $this->em->getRepository(Project::class)->findBy(['projectId' => $cols[$lookup['project_id']]]);
  947.                 if (count($project) == 0) {
  948.                   continue;
  949.                 } else {
  950.                   $project = $project[0];
  951.                 }
  952.                 $address = $this->em->getRepository(Address::class)->findBy([ 'project' => $project->getId(), 'eckId' => $cols[$lookup['eck_id']] ]);
  953.                 if (count($address) == 0) {
  954.                   continue;
  955.                 } else {
  956.                   $address = $address[0];
  957.                 }
  958.                 if (array_key_exists($address->getId().$cols[$lookup['name']], $areas)) {
  959.                   $area = $areas[$address->getId().$cols[$lookup['name']]];
  960.                 } else {
  961.                   $area = $this->em->getRepository(Area::class)->findBy([ 'address' => $address->getId(), 'name' => $cols[$lookup['name']] ]);
  962.                   if (count($area) == 0) {
  963.                     $area = new Area();
  964.                     $area->setName($cols[$lookup['name']]);
  965.                     $area->setAddress($address);
  966.                     $this->em->persist($area);
  967.                     $counter3++;
  968.                   } else {
  969.                     $area = $area[0];
  970.                   }
  971.                 }
  972.                 $areas[$address->getId().$cols[$lookup['name']]] = $area;
  973.                 if (array_key_exists($address->getId().$cols[$lookup['name']], $groundPlans)) {
  974.                   $groundPlan = $groundPlans[$address->getId().$cols[$lookup['name']]];
  975.                 } else {
  976.                   $groundPlan = $this->em->getRepository(GroundPlan::class)->findBy([ 'area' => $area->getId() ]);
  977.                   if (count($groundPlan) == 0) {
  978.                     $media = new MediaObject();
  979.                     $media->setUploadTimestamp(new \DateTime());
  980.                     $media->setFileName($area->getName());
  981.                     $uri = str_replace('/uploads', '/media/2021/07', $cols[$lookup['map']]);
  982.                     $media->setUri($uri);
  983.                     $this->em->persist($media);
  984.                     $groundPlan = new GroundPlan();
  985.                     $groundPlan->setImage($media);
  986.                     $groundPlan->setArea($area);
  987.                     $groundPlan->setDate(new \DateTime());
  988.                     $groundPlan->setName($cols[$lookup['name']]);
  989.                     $this->em->persist($groundPlan);
  990.                     $counter2++;
  991.                   } else {
  992.                     $groundPlan = $groundPlan[0];
  993.                     // re-set all media objects to current uri if first batch went wrong due to MediaObjectAddedListener
  994.                     //$uri = str_replace('/uploads', '/media/2021/07', $cols[$lookup['map']]);
  995.                     //$media = $groundPlan->getImage();
  996.                     //if ($media->getUri() !== $uri) {
  997.                       //$media->setUri($uri);
  998.                       //$this->em->persist($media);
  999.                     //}
  1000.                   }
  1001.                 }
  1002.                 $groundPlans[$address->getId().$cols[$lookup['name']]] = $groundPlan;
  1003.                 if (!array_key_exists($cols[$lookup['klasse']], $trapcats)) {
  1004.                   $trapCat = new TrapCategory();
  1005.                   $trapCat->setName($cols[$lookup['klasse']]);
  1006.                   $trapCat->setCode($cols[$lookup['klasse']]);
  1007.                   $this->em->persist($trapCat);
  1008.                   $this->em->flush();
  1009.                   $trapCat[$cols[$lookup['klasse']]] = $trapCat->getId();
  1010.                 }
  1011.                 $trap = $this->em->getRepository(Trap::class)->findBy([ 'indentificatie' => $cols[$lookup['indentificatie']], 'number' => $cols[$lookup['lokaas_id']], 'address' => $address->getId() ]);
  1012.                 if (count($trap) == 0) {
  1013.                   $trap = new Trap();
  1014.                   $trap->setCategory($trapcats[$cols[$lookup['klasse']]]);
  1015.                   $trap->setIndentificatie($cols[$lookup['indentificatie']]);
  1016.                   $trap->setNumber($cols[$lookup['lokaas_id']]);
  1017.                   $trap->setArea($area);
  1018.                   $trap->setAddress($address);
  1019.                   $trap->setLocation($cols[$lookup['locatie']]);
  1020.                   $this->em->persist($trap);
  1021.                   $groundPlanTrap = new GroundPlanTraps();
  1022.                   $groundPlanTrap->setGroundPlan($groundPlan);
  1023.                   $groundPlanTrap->setPosX($cols[$lookup['pos_x']]);
  1024.                   $groundPlanTrap->setPosY($cols[$lookup['pos_y']]);
  1025.                   $this->em->persist($groundPlanTrap);
  1026.                   $groundPlan->addTrap($groundPlanTrap);
  1027.                   $trap->addGroundPlan($groundPlanTrap);
  1028.                   $counter++;
  1029.                 }
  1030.                 if($i % 4000 ==0) {
  1031.                   $this->em->flush();
  1032.                 }
  1033.               }
  1034.               $i++;
  1035.               */
  1036.               //
  1037.               // OBJECTEN
  1038.               //
  1039.               if ($i 0) {
  1040.                 if (substr($cols[2], 01) == 'A') {
  1041.                   continue;
  1042.                 }
  1043.                 $projectId $cols[current($lookup)];
  1044.                 // find or create contract
  1045.                 $contract $this->em->getRepository(Contract::class)->findBy(['name' => $cols[$lookup['Naam debiteur']]]);
  1046.                 if (count($contract) == 0) {
  1047.                   $contract = new Contract();
  1048.                   $contract->setCreatedAt(new \DateTime());
  1049.                   $contract->setName(htmlentities($cols[$lookup['Naam debiteur']]));
  1050.                   $contract->setContractId(intval($cols[$lookup['Debiteurnr.']]));
  1051.                   //dump('-------- NEW CONTRACT:');
  1052.                   //dump($contract);
  1053.                   $this->em->persist($contract);
  1054.                   if ($isLive) {
  1055.                     $this->em->flush();
  1056.                   }
  1057.                 } else {
  1058.                   $contract $contract[0];
  1059.                   //dump($contract);
  1060.                 }
  1061.                 // find or create project
  1062.                 $project $this->em->getRepository(Project::class)->findBy(['projectId' => $projectId]);
  1063.                 if (count($project) == 0) {
  1064.                   $project = new Project();
  1065.                   $project->setCreatedAt(new \DateTime());
  1066.                   $project->setContract($contract);
  1067.                   $project->setProjectId(intval($projectId));
  1068.                   if ($cols[$lookup['Naam object']]) {
  1069.                     $project->setName(htmlentities($cols[$lookup['Naam object']]));
  1070.                   } else {
  1071.                     $project->setName($contract->getName());
  1072.                   }
  1073.                   $project->setEmail($cols[$lookup['Nummer']]);
  1074.                   $project->setWerkm($werkm);
  1075.                   $project->setStreet(htmlentities(ucfirst(strtolower($cols[$lookup['Adres 1']]))));
  1076.                   $project->setHousenumber(intval($cols[$lookup['Huisnr.']]));
  1077.                   $project->setPostal(strtoupper($cols[$lookup['Postcode']]));
  1078.                   $project->setCity(htmlentities(ucfirst(strtolower($cols[$lookup['Woonplaats']]))));
  1079.                   $project->setCountry(strtolower($cols[$lookup['Land']]));
  1080.                   //dump('-------- NEW PROJECT:');
  1081.                   //dump($project);
  1082.                   $this->em->persist($project);
  1083.                   if ($isLive) {
  1084.                     $this->em->flush();
  1085.                   }
  1086.                 } else {
  1087.                   $project $project[0];
  1088.                   //dump($project);
  1089.                 }
  1090.                 if (array_key_exists(intval($cols[1]), $eckIds)) {
  1091.                   $address $eckIds[intval($cols[1])];
  1092.                   if ($address->getId()) {
  1093.                     echo $address->getId() . ': ' $address->getStreet() . ' ' $address->getHousenumber() . '<br />';
  1094.                   }
  1095.                   //dump(intval($cols[1]));
  1096.                   //dump($address);
  1097.                 } else {
  1098.                   // create address
  1099.                   $address = new Address();
  1100.                   $address->setCreatedAt(new \DateTime());
  1101.                   $address->setName(htmlentities($cols[$lookup['Omschrijving']]));
  1102.                   $address->setProject($project);
  1103.                   $address->setEckId(intval($cols[1]));
  1104.                   $address->setContract(strtoupper(preg_replace('/[0-9]+/'''$cols[2])));
  1105.                   if ($cols[$lookup['Adres 2']] && strlen((string) $cols[$lookup['Adres 2']] > 0)) {
  1106.                     $address->setStreet(ucfirst(htmlentities(strtolower($cols[$lookup['Adres 2']]))));
  1107.                   } else {
  1108.                     $address->setStreet(ucfirst(htmlentities(strtolower($cols[$lookup['Adres 1']]))));
  1109.                   }
  1110.                   $address->setHousenumber(intval($cols[$lookup['Huisnr.']]));
  1111.                   $address->setPostal(strtoupper($cols[$lookup['Postcode']]));
  1112.                   $address->setCity(htmlentities(ucfirst(strtolower($cols[$lookup['Woonplaats']]))));
  1113.                   $address->setCountry(substr(strtolower($cols[$lookup['Land']]), 02));
  1114.                   $address->setShowTrapAlert(false);
  1115.                   $address->setShowMap(false);
  1116.                   $address->setEmail(strtolower(trim($cols[$lookup['E-mail']])));
  1117.                   //dump('-------- NEW ADDRESS:');
  1118.                   //dump($address);
  1119.                   $this->em->persist($address);
  1120.                   $eckIds[intval($cols[1])] = $address;
  1121.                   echo 'NIEUW' ': ' $address->getStreet() . ' ' $address->getHousenumber() . '<br />';
  1122.                 }
  1123.                 // find or create user
  1124.                 if (strtolower(trim($cols[$lookup['E-mail']]))) {
  1125.                   $user $this->em->getRepository(User::class)->findBy(['email' => strtolower(trim($cols[$lookup['E-mail']]))]);
  1126.                   if (count($user) == 0) {
  1127.                     $user = new User();
  1128.                     $user->setCreatedAt(new \DateTime());
  1129.                     $user->setEmail(strtolower(trim($cols[$lookup['E-mail']])));
  1130.                     $user->setPassword(
  1131.                       $this->userPasswordHasher->hashPassword($user'Eck123')
  1132.                     );
  1133.                     $user->setLocale(substr(strtolower(trim($cols[$lookup['Land']])), 02));
  1134.                     $user->setRoles(['ROLE_CUSTOMER']);
  1135.                     $person = new Person();
  1136.                     if (strpos(strtolower(htmlentities($cols[$lookup['Contactpersoon']])), 'dhr') !== false) {
  1137.                       $person->setGender('m');
  1138.                     }
  1139.                     if (strpos(strtolower(htmlentities($cols[$lookup['Contactpersoon']])), 'mw') !== false || strpos(strtolower(htmlentities($cols[$lookup['Contactpersoon']])), 'mevr') !== false) {
  1140.                       $person->setGender('f');
  1141.                     }
  1142.                     $name htmlentities($cols[$lookup['Contactpersoon']]);
  1143.                     $name str_replace('Dhr'''$name);
  1144.                     $name str_replace('Dhr '''$name);
  1145.                     $name str_replace('Dhr.'''$name);
  1146.                     $name str_replace('Mw'''$name);
  1147.                     $name str_replace('Mw '''$name);
  1148.                     $name str_replace('Mw.'''$name);
  1149.                     $name explode(' '$name2);
  1150.                     $person->setFirstname($name[0]);
  1151.                     if (array_key_exists(1$name)) {
  1152.                       $person->setLastname($name[1]);
  1153.                     }
  1154.                     $person->setPhone($cols[$lookup['Telefoon']]);
  1155.                     $person->setEmail(strtolower(trim($cols[$lookup['E-mail']])));
  1156.                     $this->em->persist($person);
  1157.                     $user->setPerson($person);
  1158.                     //dump('-------- NEW USER:');
  1159.                     //dump($user);
  1160.                     $this->em->persist($user);
  1161.                     if ($isLive) {
  1162.                       $this->em->flush();
  1163.                     }
  1164.                   } else {
  1165.                     $user $user[0];
  1166.                     //dump($user->getId());
  1167.                   }
  1168.                   $projectAdded false;
  1169.                   foreach ($user->getProjects() as $project) {
  1170.                     if ($project->getId() === $address->getProject()->getId()) {
  1171.                       $projectAdded true;
  1172.                     }
  1173.                   }
  1174.                   if (!$projectAdded) {
  1175.                     $user->addProject($project);
  1176.                     if ($isLive) {
  1177.                       $this->em->flush();
  1178.                     }
  1179.                   }
  1180.                   $user->addAddress($address);
  1181.                   $this->em->persist($user);
  1182.                 }
  1183.               }
  1184.               if($i 1000 == 0) {
  1185.                 if ($isLive) {
  1186.                   $this->em->flush();
  1187.                 }
  1188.               }
  1189.               $i++;
  1190.               /*
  1191.               //
  1192.               // SOAP USERNAME + PASSWORDS
  1193.               //
  1194.               if ($i > 0) {
  1195.                 $projectId = $cols[0];
  1196.                 $eckId = $cols[9];
  1197.                 $pUser = $cols[5];
  1198.                 $pPass = $cols[6];
  1199.                 $aUser = $cols[7];
  1200.                 $aPass = $cols[8];
  1201.                 $project = [];
  1202.                 $address = [];
  1203.                 $project = $this->em->getRepository(Project::class)->findBy(['projectId' => $projectId]);
  1204.                 if (count($project) == 0) {
  1205.                   continue;
  1206.                 }
  1207.                 $project = $project[0];
  1208.                 if ($pUser && $pPass) {
  1209.                   $project->setSoapUsername($pUser);
  1210.                   $project->setSoapPassword($pPass);
  1211.                   $this->em->persist($project);
  1212.                   $this->em->flush();
  1213.                 }
  1214.                 if ($aUser && $aPass) {
  1215.                   $address = $this->em->getRepository(Address::class)->findBy(['project' => $project->getId(), 'eckId' => $eckId ]);
  1216.                   if (count($address) == 0) {
  1217.                     continue;
  1218.                   }
  1219.                   $address = $address[0];
  1220.                   $address->setSoapUsername($aUser);
  1221.                   $address->setSoapPassword($aPass);
  1222.                   $this->em->persist($address);
  1223.                   $this->em->flush();
  1224.                 }
  1225.               }
  1226.               if($i % 400 ==0) {
  1227.                 $this->em->flush();
  1228.               }
  1229.               $i++;
  1230.               */
  1231.               /*
  1232.               //
  1233.               // ACTIES
  1234.               //
  1235.               if ($i > 0) {
  1236.                 try {
  1237.                   $projectId = $cols[0];
  1238.                   $eckId = $cols[1];
  1239.                   $projects = $this->em->getRepository(Project::class)->findBy(['projectId' => $projectId]);
  1240.                   if (count($projects) == 0) {
  1241.                     array_push($errors, 'Project not found: '.$projectId.' on row '.$i);
  1242.                     continue;
  1243.                   }
  1244.                   $project = $projects[0];
  1245.                   $addresses = $this->em->getRepository(Address::class)->findBy(['project' => $project->getId(), 'eckId' => $eckId ]);
  1246.                   if (count($addresses) == 0) {
  1247.                     array_push($errors, 'Address not found: '.$eckId.', for project: '.$project->getName().' on row '.$i);
  1248.                     continue;
  1249.                   }
  1250.                   $address = $addresses[0];
  1251.                   $a = new Action();
  1252.                   $createdAt = new \DateTime('now');
  1253.                   try {
  1254.                     $createdAt = new \DateTime($cols[3]);
  1255.                   } catch(\Exception $e){}
  1256.                   try {
  1257.                     $a->setCreatedAt($createdAt);
  1258.                   } catch(\Exception $e){}
  1259.                   $a->setAddress($address);
  1260.                   $areaCustom = $cols[11];
  1261.                   $area = $this->em->getRepository(Area::class)->findBy(['name' => $areaCustom, 'address' => $address->getId() ]);
  1262.                   if (count($area) > 0) {
  1263.                     $a->setArea($area[0]);
  1264.                   } else {
  1265.                     $a->setAreaCustom(htmlspecialchars($areaCustom));
  1266.                   }
  1267.                   $a->setTitle(htmlspecialchars(strlen($cols[5]) > 50 ? substr($cols[5],0,50)."..." : $cols[5]));
  1268.                   $closedAt = null;
  1269.                   try {
  1270.                     $closedAt = new \DateTime($cols[8]);
  1271.                   } catch(\Exception $e){}
  1272.                   try {
  1273.                     $a->setClosedAt($cols[7] == 'True' ? $closedAt : null);
  1274.                   } catch(\Exception $e){}
  1275.                   $a->setDescription(htmlspecialchars($cols[5]));
  1276.                   $a->setMiRegel($cols[2]);
  1277.                   $a->setPriority('low');
  1278.                   $a->setStatus($cols[7] == 'True' ? 'afgemeld' : 'open');
  1279.                   $a->setType('actie');
  1280.                   switch ($cols[6]) {
  1281.                     case 'L':
  1282.                       $a->setOwner('Van Eck');
  1283.                       break;
  1284.                     case 'D':
  1285.                       $a->setOwner('Derde');
  1286.                       break;
  1287.                     case 'K':
  1288.                       $a->setOwner('Klant');
  1289.                       break;
  1290.                   }
  1291.                   $this->em->persist($a);
  1292.                   //$this->em->flush();
  1293.               } catch(\Exception $e) {
  1294.                   array_push($errors, $e);
  1295.                 }
  1296.               }
  1297.               if($i % 2000 ==0) {
  1298.                 $this->em->flush();
  1299.               }
  1300.               */
  1301.               /*
  1302.               //
  1303.               // USERS
  1304.               //
  1305.               if ($i > 0) {
  1306.                 $person = new Person();
  1307.                 $person->setFirstname($cols[$lookup['firstname']]);
  1308.                 $person->setLastname($cols[$lookup['lastname']]);
  1309.                 $person->setHoursWeek($cols[$lookup['uren_week']] ? $cols[$lookup['uren_week']] : null);
  1310.                 $person->setHoursDay($cols[$lookup['uren_day']] ? $cols[$lookup['uren_day']] : null);
  1311.                 $this->em->persist($person);
  1312.                 $user = new User();
  1313.                 $user->setPerson($person);
  1314.                 $user->setEmail($cols[$lookup['email']]);
  1315.                 $user->setPassword(
  1316.                   $this->userPasswordHasher->hashPassword($user, 'Eck173!')
  1317.                 );
  1318.                 $user->setLocale('nl');
  1319.                 $user->setRoles(['ROLE_EMPLOYEE']);
  1320.                 $this->em->persist($user);
  1321.               }
  1322.               if($i % 2000 ==0) {
  1323.                 $this->em->flush();
  1324.               }
  1325.               */
  1326.               /*
  1327.               //
  1328.               // TIMESHEETS
  1329.               //
  1330.               if ($i > 0) {
  1331.                 $user = $this->em->getRepository(User::class)->findBy(['email' => $cols[$lookup['email']]]);
  1332.                 if (count($user) == 0) {
  1333.                   continue;
  1334.                 }
  1335.                 $existing = $this->em->getRepository(Timesheet::class)->findBy(['start' => new \DateTime($cols[$lookup['start']]), 'end' => new \DateTime($cols[$lookup['end']]), 'user' => $user[0]->getId()]);
  1336.                 if ($existing) {
  1337.                   continue;
  1338.                 }
  1339.                 $timesheet = new Timesheet();
  1340.                 $timesheet->setUser($user[0]);
  1341.                 $timesheet->setDescription($cols[$lookup['description']]);
  1342.                 $timesheet->setStart(new \DateTime($cols[$lookup['start']]));
  1343.                 $timesheet->setEnd(new \DateTime($cols[$lookup['end']]));
  1344.                 $timesheet->setTotalHours($cols[$lookup['total_hours']]);
  1345.                 $timesheet->setTotalMinutes($cols[$lookup['total_minutes']]);
  1346.                 $timesheet->setLocation($cols[$lookup['location']]);
  1347.                 $timesheet->setStatus($cols[$lookup['status']]);
  1348.                 $timesheet->setOvernachting($cols[$lookup['overnachting']] ? $cols[$lookup['overnachting']] : null);
  1349.                 $timesheet->setBedrijfsauto($cols[$lookup['bedrijfsauto']] ? $cols[$lookup['bedrijfsauto']] : null);
  1350.                 $timesheet->setBreak($cols[$lookup['break']] ? $cols[$lookup['break']] : null);
  1351.                 $timesheet->setCreatedAt(new \DateTime($cols[$lookup['created_at']]));
  1352.                 $timesheet->setType($cols[$lookup['type']]);
  1353.                 $this->em->persist($timesheet);
  1354.               }
  1355.               if($i % 500 ==0) {
  1356.                 $this->em->flush();
  1357.               }
  1358.               */
  1359.               ++$i;
  1360.           }
  1361.           //dump($errors);
  1362.       }
  1363.       // dump($areas);
  1364.       // dump($groundPlans);
  1365.       // dump($counter);
  1366.       // dump($counter2);
  1367.       // dump($counter3);
  1368.       if ($isLive) {
  1369.         $this->em->flush();
  1370.       }
  1371.       fclose($handle);
  1372.       return new Response('done');
  1373.   }
  1374.   #[Route(path'/fetch_media'name'fetch_media')]
  1375.   public function fetchMedia(Request $requestKernelInterface $kernel): Response
  1376.   {
  1377.       $data json_decode($request->getContent(), true);
  1378.       if (!$data || ($data && !$data['contentUrl'])) {
  1379.           $data['contentUrl'] = $request->query->get('contentUrl');
  1380.           if (!$data) {
  1381.               throw new HttpException(404'no contentUrl parameter was received');
  1382.           }
  1383.       }
  1384.       $rootDir $kernel->getProjectDir();
  1385.       $file $rootDir.'/public'.$data['contentUrl'];
  1386.       if (!file_exists($file)) {
  1387.           throw new HttpException(404'requested file url not found on server');
  1388.       }
  1389.       return new BinaryFileResponse($file);
  1390.   }
  1391.   #[Route(path'/fetch_visit_rapport'name'fetch_visit_rapport')]
  1392.   public function fetchVisitRapport(Request $request)
  1393.   {
  1394.       $data json_decode($request->getContent(), true);
  1395.       if (!$data || ($data && (!$data['address'] || !$data['storing']))) {
  1396.           $data['address'] = $request->query->get('address');
  1397.           $data['storing'] = $request->query->get('storing');
  1398.           if (!$data || ($data && (!$data['address'] || !$data['storing']))) {
  1399.               throw new HttpException(404'no address or storing parameter was received');
  1400.           }
  1401.       }
  1402.       $address $this->em->getRepository(Address::class)->findOneBy(['uuid' => $data['address']]);
  1403.       $method 'GetServiceRapport';
  1404.       $werkm $address->getProject()->getWerkm() ? $address->getProject()->getWerkm() : 0;
  1405.       $operationBody = [
  1406.           'Werkm' => $werkm,
  1407.           'Storing' => $data['storing'],
  1408.       ];
  1409.       $result $this->soap->callSoap($method$operationBody$werkm);
  1410.       if (!$result->Result) {
  1411.           throw new HttpException(404'requested file url not found on server');
  1412.       }
  1413.       return new Response($result->Rapport);
  1414.   }
  1415.   #[Route(path'/fetch_document_bestand'name'fetch_document_bestand')]
  1416.   public function fetchDocument(Request $request)
  1417.   {
  1418.       $data json_decode($request->getContent(), true);
  1419.       if (!$data || ($data && (!$data['address'] || !$data['type']))) {
  1420.           $data['address'] = $request->query->get('address');
  1421.           $data['type'] = $request->query->get('type');
  1422.           $data['artikelnummer'] = $request->query->get('artikelnummer');
  1423.           $data['bestandnaam'] = $request->query->get('bestandnaam');
  1424.           $data['onderdeel'] = $request->query->get('onderdeel');
  1425.           $data['werknemer'] = $request->query->get('werknemer');
  1426.           if (!$data || ($data && (!$data['address'] || !$data['type']))) {
  1427.               throw new HttpException(404'no type parameter was received');
  1428.           }
  1429.       }
  1430.       $method $data['type'];
  1431.       $address $this->em->getRepository(Address::class)->findOneBy(['uuid' => $data['address']]);
  1432.       $werkm $address->getProject()->getWerkm() ? $address->getProject()->getWerkm() : 0;
  1433.       switch ($data['type']) {
  1434.           case 'GetBestandenProduct':
  1435.               $operationBody = [
  1436.                 'Werkm' => $werkm,
  1437.                 'Artikelnummer' => $data['artikelnummer'],
  1438.                 'Bestanden' => '[]',
  1439.               ];
  1440.               $result $this->soap->callSoap($method$operationBody$werkm);
  1441.               $res = [];
  1442.               if ($result->Bestanden && property_exists($result->Bestanden'string')) {
  1443.                   $res = (array) $result->Bestanden->string;
  1444.               }
  1445.               return new Response(json_encode($res));
  1446.               break;
  1447.           case 'GetBestandProduct':
  1448.               $operationBody = [
  1449.                 'Werkm' => $werkm,
  1450.                 'Artikelnummer' => $data['artikelnummer'],
  1451.                 'Bestandnaam' => $data['bestandnaam'],
  1452.                 'Bestand' => '[]',
  1453.               ];
  1454.               $result $this->soap->callSoap($method$operationBody$werkm);
  1455.               return new Response($result->Bestand);
  1456.               break;
  1457.           case 'GetBestandenWerknemer':
  1458.               $operationBody = [
  1459.                 'Werkm' => $werkm,
  1460.                 'Werknemer' => $data['werknemer'],
  1461.                 'Bestanden' => '[]',
  1462.               ];
  1463.               $result $this->soap->callSoap($method$operationBody$werkm);
  1464.               $res = [];
  1465.               if ($result->Bestanden && property_exists($result->Bestanden'string')) {
  1466.                   $res = (array) $result->Bestanden->string;
  1467.               }
  1468.               return new Response(json_encode($res));
  1469.               break;
  1470.           case 'GetBestandWerknemer':
  1471.               $operationBody = [
  1472.                 'Werkm' => $werkm,
  1473.                 'Werknemer' => $data['werknemer'],
  1474.                 'Bestandnaam' => $data['bestandnaam'],
  1475.                 'Bestand' => '[]',
  1476.               ];
  1477.               $result $this->soap->callSoap($method$operationBody$werkm);
  1478.               return new Response($result->Bestand);
  1479.               break;
  1480.           case 'GetBestandKlant':
  1481.               $eckIds $address->getEckIds();
  1482.               foreach ($eckIds as $eckId) {
  1483.                   $operationBody = [
  1484.                     'Werkm' => $werkm,
  1485.                     'Project' => $address->getProject()->getProjectId(),
  1486.                     'ID' => $eckId,
  1487.                     'Bestandnaam' => $data['bestandnaam'],
  1488.                     'Bestand' => '[]',
  1489.                   ];
  1490.                   $result $this->soap->callSoap($method$operationBody$werkm);
  1491.                   if (property_exists($result'Bestand')) {
  1492.                       return new Response($result->Bestand);
  1493.                   }
  1494.               }
  1495.               break;
  1496.       }
  1497.   }
  1498. }