src/Controller/InvoiceController.php line 270

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Order;
  4. use App\Entity\Person;
  5. use App\Entity\Invoice;
  6. use App\Entity\WaitItem;
  7. use App\Form\InvoiceType;
  8. use App\Service\UiService;
  9. use App\Form\CsvImportType;
  10. use App\Service\PdfService;
  11. use App\Form\InvoiceOnlyType;
  12. use App\Entity\InvoicePayment;
  13. use App\Service\MailerService;
  14. use App\Service\InvoiceService;
  15. use App\Service\PaymentService;
  16. use App\Service\SepaXmlService;
  17. use App\Entity\Dto\CsvImportDto;
  18. use App\Service\CsvImportService;
  19. use App\Repository\PersonRepository;
  20. use App\Service\EmailHistoryService;
  21. use App\Repository\InvoiceRepository;
  22. use App\Service\ConfigurationService;
  23. use App\Service\Exception\ServiceException;
  24. use App\Repository\InvoicePaymentRepository;
  25. use App\Repository\InvoiceReminderRepository;
  26. use Symfony\Component\HttpFoundation\Request;
  27. use Symfony\Component\HttpFoundation\Response;
  28. use Symfony\Component\Routing\Annotation\Route;
  29. use Doctrine\Common\Collections\ArrayCollection;
  30. use App\Repository\InvoiceItemAttendeesRepository;
  31. use Symfony\Component\HttpFoundation\RequestStack;
  32. use Symfony\Component\HttpFoundation\RedirectResponse;
  33. use Menke\UserBundle\Controller\AbstractClientableController;
  34. use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
  35. use Symfony\Component\HttpFoundation\File\Exception\FileException;
  36. /**
  37.  * @Route("/invoice")
  38.  * @IsGranted("ROLE_MANAGER")
  39.  */
  40. class InvoiceController extends AbstractClientableController
  41. {
  42.     const LISTING_LIMIT 20;
  43.     private function generateUniqueFileName()
  44.     {
  45.         return md5(uniqid());
  46.     }
  47.     /**
  48.      * @Route("/", name="invoice_index", methods="GET|POST")
  49.      */
  50.     public function index(
  51.         Request $request,
  52.         InvoiceRepository $invoiceRepo,
  53.         CsvImportService $importService,
  54.         UiService $uiService,
  55.         RequestStack $requestStack,
  56.         PaymentService $paymentService
  57.     ): Response {
  58.         $order $uiService->getSortOrder('invoice-index-listing');
  59.         //Check for unset invoice status
  60.         $this->checkForUnsetInvoiceStatus($invoiceRepo$paymentService);
  61.         $filterInvoices $request->get('action');
  62.         if ($filterInvoices) {
  63.             $requestStack->getSession()->set('filter'$filterInvoices);
  64.         } else {
  65.             $requestStack->getSession()->set('filter'null);
  66.         }
  67.         $invoice $invoiceRepo->getByClientPaged(
  68.             $this->getCurrentClient(),
  69.             self::LISTING_LIMIT,
  70.             $order['orderDirection'] ?? 'desc',
  71.             $order['orderBy'] ?? 'id',
  72.             1,
  73.             ($filterInvoices) ? $filterInvoices null
  74.         );
  75.         $csvImportDto = new CsvImportDto();
  76.         $form $this->createForm(CsvImportType::class, $csvImportDto);
  77.         $form->handleRequest($request);
  78.         if ($form->isSubmitted() && $form->isValid()) {
  79.             $fileName =
  80.                 md5(uniqid()) . '.' $csvImportDto->file->guessExtension();
  81.             try {
  82.                 $csvImportDto->file->move(
  83.                     $this->getParameter('import_directory'),
  84.                     $fileName
  85.                 );
  86.                 $fullFileName $this->getParameter('import_directory') . '/' $fileName;
  87.             } catch (FileException $e) {
  88.                 $this->addFlash(
  89.                     'error',
  90.                     'Beim Datei-Upload ist ein Fehler aufgetreten. Bitte versuchen Sie es später noch einmal.'
  91.                 );
  92.                 return $this->redirectToRoute('invoice_index');
  93.             }
  94.             $result $importService->updateInvoiceStatus(
  95.                 $fullFileName,
  96.                 $this->getCurrentClient()
  97.             );
  98.             if (is_array($result)) {
  99.                 $message 'Beim Rechnungsimport ';
  100.                 if (count($result) > 1) {
  101.                     $message .=
  102.                         'sind ' count($result) . ' Fehler aufgetreten.';
  103.                 } else {
  104.                     $message .= 'ist ein Fehler aufgetreten.';
  105.                 }
  106.                 $this->addFlash('error'$message);
  107.                 foreach ($result as $key => $error) {
  108.                     $this->addFlash('error'$key '. ' $error);
  109.                 }
  110.             } elseif ($result !== false) {
  111.                 $this->addFlash('notice'$result ' Rechnungen importiert.');
  112.                 return $this->redirectToRoute('invoice_index');
  113.             }
  114.         }
  115.         return $this->render('invoice/index.html.twig', [
  116.             'uiService' => $uiService,
  117.             'invoices' => $invoice->getIterator(),
  118.             'total' => $invoice->count(),
  119.             'pages' => ceil($invoice->count() / self::LISTING_LIMIT),
  120.             'page' => 1,
  121.             'form' => $form->createView(),
  122.             'filterAction' => $requestStack->getSession()->get('filter'),
  123.             'env' => $_ENV,
  124.             'now' => new \DateTime()
  125.         ]);
  126.     }
  127.     /**
  128.      * @Route("/{page}/{orderby}/{order}", name="invoice_index_listing", methods="GET", requirements={"page"="\d+","order"="asc|desc"})
  129.      */
  130.     public function indexListing(
  131.         InvoiceRepository $invoiceRepo,
  132.         UiService $uiService,
  133.         $page,
  134.         $orderby,
  135.         $order,
  136.         RequestStack $requestStack
  137.     ): Response {
  138.         $uiService->storeSortOrder('invoice-index-listing'$orderby$order);
  139.         $invoice $invoiceRepo->getByClientPaged(
  140.             $this->getCurrentClient(),
  141.             self::LISTING_LIMIT,
  142.             $order,
  143.             $orderby,
  144.             $page,
  145.             $requestStack->getSession()->get('filter')
  146.         );
  147.         return $this->render('invoice/_index_listing.html.twig', [
  148.             'invoices' => $invoice->getIterator(),
  149.             'total' => $invoice->count(),
  150.             'pages' => ceil($invoice->count() / self::LISTING_LIMIT),
  151.             'page' => $page,
  152.             'filterAction' => $requestStack->getSession()->get('filter'),
  153.             'env' => $_ENV,
  154.             'now' => new \DateTime()
  155.         ]);
  156.     }
  157.     /**
  158.      * @Route("/{id}/close", name="invoice_close", methods="GET", requirements={"id"="\d+"})
  159.      */
  160.     public function close(
  161.         Request $request,
  162.         Invoice $invoice,
  163.         PdfService $pdfService,
  164.         MailerService $mailer,
  165.         EmailHistoryService $emailHistoryService
  166.     ): Response {
  167.         $this->denyAccessUnlessGranted('ROLE_MANAGER'$invoice);
  168.         $pdf $pdfService->getInvoicePdf($this->getCurrentClient(), $invoice);
  169.      
  170.         $sentMessage $mailer->sendInvoiceEmail(
  171.             $invoice,
  172.             'Rechnung-' $invoice->getNumber() . '.pdf',
  173.             $pdf->Output('S''Rechnung-' $invoice->getNumber() . '.pdf')
  174.         );
  175.         $outputfile $this->generateUniqueFileName() . '.pdf';
  176.         $outputpath $this->getParameter('attachment_directory') . '/' $outputfile;
  177.         $pdf->Output('F'$outputpath);
  178.         $emailHistoryService->saveProtocolEntryFromInvoiceMessage(
  179.             $invoice,
  180.             $sentMessage['sender'],
  181.             $sentMessage['subject'],
  182.             $sentMessage['message'],
  183.             $outputfile,
  184.             'Rechnung-' $invoice->getNumber() . '.pdf'
  185.         );
  186.         if ($invoice->getStatus() != Invoice::STATUS_CLOSED) {
  187.             if ($invoice->isPaymentDebit()) {
  188.                 $invoice->setStatus(Invoice::STATUS_DEBIT_PENDING);
  189.             } else {
  190.                 $invoice->setStatus(Invoice::STATUS_CLOSED);
  191.             }
  192.         }
  193.         $em $this->getDoctrine()->getManager();
  194.         //Update the order status
  195.         $newOrderState $invoice->getOrder()->setStatus(Order::STATUS_DONE);
  196.         $em->persist($newOrderState);
  197.         $em->flush();
  198.         $this->addFlash('notice''Rechnung versendet');
  199.         return $this->redirect($request->get('return'));
  200.     }
  201.     /**
  202.      * @Route("/{id}/lock", name="invoice_lock", methods="GET", requirements={"id"="\d+"})
  203.      */
  204.     public function lock(
  205.         Request $request,
  206.         Invoice $invoice,
  207.         PdfService $pdfService,
  208.       
  209.         
  210.     ): Response {
  211.         $this->denyAccessUnlessGranted('ROLE_MANAGER'$invoice);
  212.         $pdf $pdfService->getInvoicePdf($this->getCurrentClient(), $invoice);
  213.      
  214.         $outputfile $this->generateUniqueFileName() . '.pdf';
  215.         $outputpath $this->getParameter('attachment_directory') . '/' $outputfile;
  216.         $pdf->Output('F'$outputpath);
  217.        
  218.         if ($invoice->getStatus() != Invoice::STATUS_CLOSED) {
  219.             if ($invoice->isPaymentDebit()) {
  220.                 $invoice->setStatus(Invoice::STATUS_DEBIT_PENDING);
  221.             } else {
  222.                 $invoice->setStatus(Invoice::STATUS_CLOSED);
  223.             }
  224.         }
  225.         $em $this->getDoctrine()->getManager();
  226.         //Update the order status
  227.         $newOrderState $invoice->getOrder()->setStatus(Order::STATUS_DONE);
  228.         $em->persist($newOrderState);
  229.         $em->flush();
  230.         $this->addFlash('notice''Rechnung abgeschlossen');
  231.         return $this->redirect($request->get('return'));
  232.     }
  233.     /**
  234.      * @Route("/new/{return}", name="invoice_new", methods="GET|POST")
  235.      */
  236.     public function new(
  237.         Request $request,
  238.         $return '',
  239.         PersonRepository $personRepo,
  240.         ConfigurationService $configService
  241.     ): Response {
  242.         $customer null;
  243.         if ($return) {
  244.             $customer $personRepo->find($return);
  245.         }
  246.         $invoice = new Invoice();
  247.         $form $this->createForm(InvoiceType::class, $invoice, [
  248.             'client' => $this->getCurrentClient(),
  249.             'taxes' => $configService->getTaxConfigbyClient(
  250.                 $this->getCurrentClient()
  251.             ),
  252.             'customer' => $customer,
  253.         ]);
  254.         $form->handleRequest($request);
  255.         // check if creation is possible
  256.         if ($form->isSubmitted() && $form->isValid()) {
  257.             $em $this->getDoctrine()->getManager();
  258.             $allItemsBookable true;
  259.             $occurrences = [];
  260.             foreach ($invoice->getOrder()->getOrderItems() as $orderItem) {
  261.                 if ($orderItem->getCourseOccurrence()) {
  262.                     $occurrence $orderItem->getCourseOccurrence();
  263.                     if (
  264.                         !$occurrence->isBookable($orderItem->getQuantity()) &&
  265.                         $occurrence->getReservationAllowed()
  266.                     ) {
  267.                         $waitItem WaitItem::fromOrderItem($orderItem);
  268.                         foreach ($orderItem->getParticipants()
  269.                             as $participant) {
  270.                             $orderItem->removeParticipant($participant);
  271.                         }
  272.                         $invoice->getOrder()->addWaitItem($waitItem);
  273.                         $invoice->getOrder()->removeOrderItem($orderItem);
  274.                         $em->persist($waitItem);
  275.                         $this->addFlash(
  276.                             'error',
  277.                             'Im Kurs "' .
  278.                                 $occurrence->getTitle() .
  279.                                 '" sind nicht mehr genug Plätz verfügbar. Die Buchung wurde stattdessen zur Warteliste hinzugefügt.'
  280.                         );
  281.                     } elseif (
  282.                         !$occurrence->isBookable($orderItem->getQuantity()) &&
  283.                         !$occurrence->getReservationAllowed()
  284.                     ) {
  285.                         $allItemsBookable false;
  286.                         $this->addFlash(
  287.                             'error',
  288.                             'Im Kurs "' .
  289.                                 $occurrence->getTitle() .
  290.                                 '" sind nicht mehr genug Plätz verfügbar.'
  291.                         );
  292.                     } else {
  293.                         $occurrence->bookSlots($orderItem->getQuantity());
  294.                         $occurrences[] = $occurrence;
  295.                     }
  296.                 }
  297.             }
  298.             if ($allItemsBookable) {
  299.                 if (
  300.                     count($invoice->getOrderItems()) > ||
  301.                     count($invoice->getOrder()->getWaitItems()) > 0
  302.                 ) {
  303.                     $invoice->setNumber(
  304.                         $configService->getNewInvoiceNumberByClient(
  305.                             $this->getCurrentClient()
  306.                         )
  307.                     );
  308.                     $invoice->setSignedBy($this->getCurrentUser());
  309.                     $order $invoice->getOrder();
  310.                     $order->setClient($this->getCurrentClient());
  311.                     $order->setCustomer($customer);
  312.                     $order->setCustomerData($customer);
  313.                     $order->setDate(new \DateTime());
  314.                     $order->setNumber(
  315.                         $configService->getNewOrderNumberByClient(
  316.                             $this->getCurrentClient()
  317.                         )
  318.                     );
  319.                     $em->persist($order);
  320.                     $em->persist($invoice);
  321.                     $em->flush();
  322.                     foreach ($occurrences as $occurrence) {
  323.                         $occurrence->flushBooking();
  324.                     }
  325.                 }
  326.                 $em->flush();
  327.                 if ($return) {
  328.                     return $this->redirectToRoute('customer_invoices', [
  329.                         'id' => $return,
  330.                     ]);
  331.                 } else {
  332.                     return $this->redirectToRoute('invoice_index');
  333.                 }
  334.             }
  335.         }
  336.         return $this->render('invoice/new.html.twig', [
  337.             'invoice' => $invoice,
  338.             'form' => $form->createView(),
  339.             'customer' => $customer,
  340.         ]);
  341.     }
  342.     /**
  343.      * @Route("/{id}", name="invoice_show", methods="GET|POST", requirements={"id"="\d+"})
  344.      */
  345.     public function show(
  346.         Request $request,
  347.         Invoice $invoice,
  348.         InvoicePaymentRepository $invoicePaymentRepo,
  349.         InvoiceRepository $repo,
  350.         ConfigurationService $configService,
  351.         InvoiceService $invoiceService,
  352.         PersonRepository $personRepo
  353.     ): Response {
  354.         
  355.         $invoiceRecipient null;
  356.         if ($request->query->has('invoice')) {
  357.             //Entries from the invoice table
  358.             $invoiceRecipient $repo->findOneBy([
  359.                 'invoiceAdressPerson' => $personRepo,
  360.                 'id' => $request->get('invoice')
  361.             ]);
  362.         }
  363.         
  364.         $payments $invoicePaymentRepo->getByInvoicePaged($invoice, static::LISTING_LIMIT);
  365.         $invoiceRecipientMembers null;
  366.         $adressChanged false;
  367.         //Need the original recipient ID before update
  368.         $lastInvoiceRecipient $invoice->getInvoiceAdressPerson();
  369.         //var_dump($invoice);
  370.         if (is_null($invoice->getInvoiceAdressPerson()) ) {
  371.             if (!is_null($invoice->getInvoiceAdressPerson())) {
  372.                 $currentRecipient $invoice->getInvoiceAdressPerson();
  373.                 $invoiceRecipientMembers $personRepo->getInvoiceReciepientMembers$currentRecipient );
  374.                 /**
  375.                  * If there are no Members, so we have to look, if the current Invoice Recipient
  376.                  * is an family member. Then we can get the original client and his recipient members.
  377.                  */
  378.                 if (empty($invoiceRecipientMembers)) {
  379.                     //Get FamilyMembers By Client
  380.                     $invoiceRecipientMembers $personRepo->getInvoiceReciepientsByParent(
  381.                         $currentRecipient->getFamilyMemberOf()
  382.                     );
  383.                     //Client of the Family Member
  384.                     $currentRecipient $currentRecipient->getFamilyMemberOf();
  385.                 }
  386.                 //Create values for the SelectBox (Frontend invoice/edit)
  387.                 $invoiceRecipient $this->createInvoiceRecipientValues(
  388.                     $invoiceRecipientMembers,
  389.                     $currentRecipient,
  390.                     $invoice->getInvoiceAdressPerson()
  391.                 );
  392.             } else {
  393.                 //If there is no InvoiceAdressPerson, we have to take the Person from the Order Table.
  394.             
  395.                 $currentRecipient $invoice->getOrder()->getCustomer();
  396.                 $invoiceRecipientMembers $personRepo->getInvoiceReciepientMembers(
  397.                     $currentRecipient
  398.                 );
  399.                 //Create values for the SelectBox (Frontend invoice/edit)
  400.                 $invoiceRecipient $this->createInvoiceRecipientValues(
  401.                     $invoiceRecipientMembers,
  402.                     $currentRecipient,
  403.                     $invoice->getInvoiceAdressPerson(),
  404.                     true
  405.                 );
  406.             }
  407.         
  408.             
  409.         if (
  410.             $invoice->getInvoiceAdressPerson()
  411.             // && $invoice->getInvoiceAdressPerson()->getIsInvoiceRecipient()
  412.         ) {
  413.             $adressChanged $invoiceService->checkIfAdressHasChanged($invoicetrue);
  414.         }
  415.         // else {
  416.         //     $adressChanged = $invoiceService->checkIfAdressHasChanged($invoice, true);
  417.         // }
  418.         }
  419.         if ($request->get('flashMessage')){ $this->addFlash('notice''Rechnungsadresse wurde erfolgreich aktualisiert.');}
  420.         $cancellations $repo->findCancellationByInvoice($invoice);
  421.         if ($invoice->isDraft()) {
  422.             $currentRecipient $invoice->getInvoiceAdressPerson();
  423.             $invoiceRecipientMembers $personRepo->getInvoiceReciepientMembers$currentRecipient );
  424.             $invoiceRecipient $this->createInvoiceRecipientValues(
  425.                 $invoiceRecipientMembers,
  426.                 $currentRecipient,
  427.                 $invoice->getInvoiceAdressPerson()
  428.             );
  429.         //  var_dump($invoiceRecipient);
  430.             $form $this->createForm(InvoiceOnlyType::class, $invoice, [
  431.                 'client' => $this->getCurrentClient(),
  432.                 'taxes' => $configService->getTaxConfigbyClient(
  433.                     $this->getCurrentClient()
  434.                 ),
  435.                 'invoiceRecipient' => $invoiceRecipient,
  436.                 
  437.             ]);
  438.             $form->handleRequest($request);
  439.             if ($form->isSubmitted() && $form->isValid()) {
  440.                 $em $this->getDoctrine()->getManager();
  441.                
  442.                     $em->flush();
  443.                
  444.                 $this->addFlash('notice''Rechnung gespeichert.');
  445.             }
  446.             return $this->render('invoice/edit.html.twig', [
  447.                 'invoice' => $invoice,
  448.                 'cancellations' => $cancellations,
  449.                 'payments' => $payments->getIterator(),
  450.                 'total' => $payments->count(),
  451.                 'pages' => ceil($payments->count() / self::LISTING_LIMIT),
  452.                 'page' => 1,
  453.                 'form' => $form->createView(),
  454.                 'adressChanged' => $adressChanged,
  455.             ]);
  456.         } else {
  457.             return $this->render('invoice/show.html.twig', [
  458.                 'invoice' => $invoice,
  459.                 'cancellations' => $cancellations,
  460.                 'payments' => $payments->getIterator(),
  461.                 'total' => $payments->count(),
  462.                 'pages' => ceil($payments->count() / self::LISTING_LIMIT),
  463.                 'page' => 1,
  464.             ]);
  465.         }
  466.     }
  467.     /**
  468.      * @Route("/{id}/updateAdress", name="invoice_update_adress", methods="GET|POST", requirements={"id"="\d+"})
  469.      */
  470.     public function updateAdress(
  471.         Request $request,
  472.         Invoice $invoice,
  473.         InvoiceService $invoiceService,
  474.         PersonRepository $personRepo
  475.     ): RedirectResponse {
  476.         $em $this->getDoctrine()->getManager();
  477.         if ($request->get('person')) {
  478.             $person $personRepo->find($request->get('personId'));
  479.             $updatedInvoice $invoiceService->updateInvoiceAdress($invoice$person);
  480.             $em->persist($updatedInvoice);
  481.             $em->flush();
  482.         }
  483.         // else {
  484.         //     $updatedInvoice = $invoiceService->updateInvoiceAdress($invoice, $null);
  485.         // }
  486.         return $this->redirectToRoute('invoice_show', [
  487.             'id' => $invoice->getId(),
  488.             'flashMessage' => true
  489.         ]);
  490.     }
  491.     /**
  492.      * @Route("/{id}", name="invoice_delete", methods="DELETE", requirements={"id"="\d+"})
  493.      */
  494.     public function delete(Request $requestInvoice $invoiceInvoiceItemAttendeesRepository $invoiceItemAttendeesRepo): Response
  495.     {
  496.         $this->denyAccessUnlessGranted('ROLE_MANAGER'$invoice);
  497.         if ($this->isCsrfTokenValid('delete' $invoice->getId(), $request->request->get('_token')) && $invoice->isDraft()) {
  498.             $em $this->getDoctrine()->getManager();
  499.             $attendees = [];
  500.             foreach ($invoice->getItems() as $item) {
  501.                 $attendees $invoiceItemAttendeesRepo->findBy(['invoice_item' => $item]);
  502.             }
  503.             if ($attendees) {
  504.                 foreach ($attendees as $attendee) {
  505.                     $em->remove($attendee);
  506.                 }
  507.             }
  508.             $em->remove($invoice);
  509.             $em->flush();
  510.             $this->addFlash('notice''Rechnung gelöscht');
  511.         }
  512.         return $this->redirectToRoute('invoice_index');
  513.     }
  514.     /**
  515.      * @Route("/{id}/cancel", name="invoice_cancel", methods="POST", requirements={"id"="\d+"})
  516.      */
  517.     public function cancel(
  518.         Request $request,
  519.         Invoice $invoice,
  520.         ConfigurationService $configService
  521.     ): Response {
  522.         $this->denyAccessUnlessGranted('ROLE_MANAGER'$invoice);
  523.         if ($this->isCsrfTokenValid('cancel' $invoice->getId(), $request->request->get('_token')) && !$invoice->isDraft()) {
  524.             $em $this->getDoctrine()->getManager();
  525.             $coppiedInvoice $invoice->cloneForCancellation();
  526.             $cancellation $coppiedInvoice['invoice'];
  527.             $cancellation->setInvoiceDate(new \DateTime());
  528.             $cancellation->setNumber(
  529.                 $configService->getNewInvoiceNumberByClient(
  530.                     $this->getCurrentClient()
  531.                 )
  532.             );
  533.             $cancellation->setCancellation(true);
  534.             $cancellation->setParent($invoice);
  535.             $cancellation->setSignedBy($this->getCurrentUser());
  536.             $cancellation->setStatus(Invoice::STATUS_CLOSED);
  537.             $invoice->setCancelled(true);
  538.             foreach ($coppiedInvoice['attendees'] as $attendee) {
  539.                 $em->persist($attendee);
  540.             }
  541.             $em->persist($cancellation);
  542.             $em->flush();
  543.             $this->addFlash('notice''Rechnung storniert');
  544.         }
  545.         return $this->redirectToRoute('invoice_show', [
  546.             'id' => $invoice->getId(),
  547.         ]);
  548.     }
  549.     /**
  550.      * @Route("/{id}/cancel_fromorder/{order}", name="invoice_cancel_fromorder", methods="POST", requirements={"id"="\d+"})
  551.      */
  552.     public function cancel_fromorder(
  553.         Request $request,
  554.         Invoice $invoice,
  555.         Order $order,
  556.         ConfigurationService $configService
  557.     ): Response {
  558.         $this->denyAccessUnlessGranted('ROLE_MANAGER'$invoice);
  559.         if ($this->isCsrfTokenValid('cancel' $invoice->getId(), $request->request->get('_token')) && !$invoice->isDraft()) {
  560.             $em $this->getDoctrine()->getManager();
  561.             $coppiedInvoice $invoice->cloneForCancellation();
  562.             $cancellation $coppiedInvoice['invoice'];
  563.             $cancellation->setInvoiceDate(new \DateTime());
  564.             $cancellation->setNumber(
  565.                 $configService->getNewInvoiceNumberByClient(
  566.                     $this->getCurrentClient()
  567.                 )
  568.             );
  569.             $cancellation->setCancellation(true);
  570.             $cancellation->setParent($invoice);
  571.             $cancellation->setSignedBy($this->getCurrentUser());
  572.             $cancellation->setStatus(Invoice::STATUS_CLOSED);
  573.             $invoice->setCancelled(true);
  574.             foreach ($coppiedInvoice['attendees'] as $attendee) {
  575.                 $em->persist($attendee);
  576.             }
  577.             $em->persist($cancellation);
  578.             $em->flush();
  579.             $this->addFlash('notice''Rechnung storniert');
  580.         }
  581.         return $this->redirectToRoute('order_show', [
  582.             'id' => $order->getId(),
  583.         ]);
  584.     }
  585.     /**
  586.      * @Route("/{id}/pdf", name="invoice_pdf", methods="GET", requirements={"id"="\d+"})
  587.      */
  588.     public function pdf(
  589.         Request $request,
  590.         Invoice $invoice,
  591.         ConfigurationService $configService,
  592.         PdfService $pdfService,
  593.         InvoiceItemAttendeesRepository $invoiceItemAttendeesRepository
  594.     ) {
  595.         #dd($invoice->getItems()[0]->getId());
  596.         #        dd(count($invoice->getItems()));
  597.         $this->denyAccessUnlessGranted('ROLE_MANAGER'$invoice);
  598.         $pdf $pdfService->getInvoicePdf($this->getCurrentClient(), $invoice);
  599.         $pdf->Output('D''Rechnung-' $invoice->getNumber() . '.pdf');
  600.         exit();
  601.     }
  602.     /**
  603.      * @Route("/{id}/cancellation-pdf", name="invoice_cancellation-pdf", methods="GET", requirements={"id"="\d+"})
  604.      */
  605.     public function cancellationPdf(
  606.         Request $request,
  607.         Invoice $invoice,
  608.         ConfigurationService $configService,
  609.         PdfService $pdfService
  610.     ) {
  611.         $this->denyAccessUnlessGranted('ROLE_MANAGER'$invoice);
  612.         $pdf $pdfService->getCancellationPdf(
  613.             $this->getCurrentClient(),
  614.             $invoice
  615.         );
  616.         $pdf->Output('D''Gutschrift-' $invoice->getNumber() . '.pdf');
  617.         exit();
  618.     }
  619.     /**
  620.      * @Route("/{id}/sepa-xml", name="invoice_sepa-xml", methods="GET", requirements={"id"="\d+"})
  621.      */
  622.     public function sepaXml(
  623.         Request $request,
  624.         Invoice $invoice,
  625.         ConfigurationService $configService,
  626.         SepaXmlService $sepaXmlService
  627.     ) {
  628.         $this->denyAccessUnlessGranted('ROLE_MANAGER'$invoice);
  629.         $em $this->getDoctrine()->getManager();
  630.         $invoice->setStatus(Invoice::STATUS_CLOSED);
  631.         if (
  632.             !$invoice
  633.                 ->getOrder()
  634.                 ->getCustomer()
  635.                 ->getDebitActive()
  636.         ) {
  637.             $invoice
  638.                 ->getOrder()
  639.                 ->getCustomer()
  640.                 ->setDebitActive(true);
  641.             $invoice->setIsNewSepaMandate(true);
  642.         }
  643.         $config $configService->getSepaXmlConfigByClient(
  644.             $this->getCurrentClient()
  645.         );
  646.         try {
  647.             $xml $sepaXmlService->getSepaXmlSingle(
  648.                 $this->getCurrentClient(),
  649.                 $config,
  650.                 $invoice
  651.             );
  652.         } catch (ServiceException $e) {
  653.             $this->addFlash('error'$e->getMessage());
  654.             return $this->redirectToRoute('invoice_index');
  655.         }
  656.         $em->flush();
  657.         $response = new Response($xml);
  658.         $response->headers->set('Content-Type''text/xml');
  659.         $response->headers->set('Content-disposition''attachment; filename="SEPA-' date('Ymd-His') . '.xml"');
  660.         return $response;
  661.     }
  662.     /**
  663.      * @Route("/new-sepa-xml", name="invoice_new-sepa-xml", methods="GET")
  664.      */
  665.     public function newInvoicesSepaXml(
  666.         Request $request,
  667.         ConfigurationService $configService,
  668.         SepaXmlService $sepaXmlService,
  669.         InvoiceRepository $invoiceRepo
  670.     ) {
  671.         $invoices $invoiceRepo->getByClientAndStatuses(
  672.             $this->getCurrentClient(),
  673.             [Invoice::STATUS_DRAFTInvoice::STATUS_DEBIT_PENDING],
  674.             Invoice::PAYMENT_DEBIT
  675.         );
  676.         $invoicesToExport = new ArrayCollection();
  677.         foreach ($invoices as $invoice) {
  678.             if (!$invoicesToExport->contains($invoice)) {
  679.                 $invoice->setStatus(Invoice::STATUS_CLOSED);
  680.                 $invoicesToExport->add($invoice);
  681.                 if (
  682.                     $invoice->getOrder()->getCustomer() &&
  683.                     !$invoice
  684.                         ->getOrder()
  685.                         ->getCustomer()
  686.                         ->getDebitActive()
  687.                 ) {
  688.                     $invoice
  689.                         ->getOrder()
  690.                         ->getCustomer()
  691.                         ->setDebitActive(true);
  692.                     $invoice->setIsNewSepaMandate(true);
  693.                 }
  694.             }
  695.         }
  696.         try {
  697.             if (count($invoicesToExport) > 0) {
  698.                 $config $configService->getSepaXmlConfigByClient($this->getCurrentClient());
  699.                 $xml $sepaXmlService->getSepaXmlMultiple($this->getCurrentClient(), $config$invoicesToExport);
  700.                 $em $this->getDoctrine()->getManager();
  701.                 $em->flush();
  702.                 $response = new Response($xml);
  703.                 $response->headers->set('Content-Type''text/xml');
  704.                 $response->headers->set('Content-disposition''attachment; filename="SEPA-' date('Ymd-His') . '.xml"');
  705.                 return $response;
  706.             }
  707.         } catch (ServiceException $e) {
  708.             $this->addFlash('error'$e->getMessage());
  709.             return $this->redirectToRoute('invoice_index');
  710.         }
  711.         $this->addFlash('error''Es wurden keine exportierbaren Rechnungen gefunden.');
  712.         return $this->redirectToRoute('invoice_index');
  713.     }
  714.     /**
  715.      * @Route("/{id}/payments/{page}/{orderby}/{order}", name="invoice_payments_listing", methods="GET", requirements={"id"="\d+"})
  716.      */
  717.     public function paymentsListing(
  718.         Request $request,
  719.         Invoice $invoice,
  720.         $page 1,
  721.         $orderby 'payedDate',
  722.         $order 'ASC',
  723.         InvoicePaymentRepository $repo
  724.     ) {
  725.         $this->denyAccessUnlessGranted('ROLE_MANAGER'$invoice);
  726.         $payments $repo->getByInvoicePaged(
  727.             $invoice,
  728.             self::LISTING_LIMIT,
  729.             $order,
  730.             $orderby,
  731.             $page
  732.         );
  733.         return $this->render('invoice/tabs/_payments_listing.html.twig', [
  734.             'payments' => $payments->getIterator(),
  735.             'total' => $payments->count(),
  736.             'pages' => ceil($payments->count() / self::LISTING_LIMIT),
  737.             'page' => $page,
  738.         ]);
  739.     }
  740.     /**
  741.      * @Route("/{id}/reminders/{page}/{orderby}/{order}", name="invoice_reminders_listing", methods="GET", requirements={"id"="\d+"})
  742.      */
  743.     public function remindersListing(
  744.         Request $request,
  745.         Invoice $invoice,
  746.         $page 1,
  747.         $orderby 'remindDate',
  748.         $order 'ASC',
  749.         InvoiceReminderRepository $repo
  750.     ) {
  751.         $this->denyAccessUnlessGranted('ROLE_MANAGER'$invoice);
  752.         $reminders $repo->getByInvoicePaged(
  753.             $invoice,
  754.             self::LISTING_LIMIT,
  755.             $order,
  756.             $orderby,
  757.             $page
  758.         );
  759.         return $this->render('invoice/tabs/_reminders_listing.html.twig', [
  760.             'reminders' => $reminders->getIterator(),
  761.             'total' => $reminders->count(),
  762.             'pages' => ceil($reminders->count() / self::LISTING_LIMIT),
  763.             'page' => $page,
  764.         ]);
  765.     }
  766.     private function getInvoiceRecipientId(Person $person)
  767.     {
  768.         if ($person->getIsInvoiceRecipient()) {
  769.             return [
  770.                 'id' => $person->getId(),
  771.                 'type' => 'personRecipient'
  772.             ];
  773.         }
  774.         return [
  775.             'id' => $person->getId(),
  776.             'type' => 'clientRecipient'
  777.         ];
  778.     }
  779.     private function createInvoiceRecipientValues($invoiceRecipientMembers$currentRecipient$invoicePerson null$onlyClient false)
  780.     {
  781.         $invoicePersonId null;
  782.         if ($invoicePerson) {
  783.             $res[] = $invoicePerson;
  784.             $invoicePersonId $invoicePerson->getId();
  785.         }
  786.         if ($onlyClient) {
  787.             $res[] = $currentRecipient;
  788.         } else {
  789.             if (
  790.                 $currentRecipient &&
  791.                 $currentRecipient->getId() != $invoicePersonId
  792.             $res[] = $currentRecipient;
  793.         }
  794.         foreach ($invoiceRecipientMembers as $person) {
  795.             if ($person->getId() != $invoicePersonId) {
  796.                 $res[] = $person;
  797.             }
  798.         }
  799.         return $res;
  800.     }
  801.     /**
  802.      * @Route("/{id}/getPersonAdress", name="get_person_adress", methods="GET|POST")
  803.      */
  804.     public  function getClientAdress(Request $requestPerson $personInvoiceRepository $invoiceRepo)
  805.     {
  806.         /**
  807.          * Ajax Call
  808.          * Returns the person informations back to the invoice/edit by onChange the persons.
  809.          */
  810.         $invoiceRecipient null;
  811.         if ($request->query->has('invoice')) {
  812.             //Entries from the invoice table
  813.             $invoiceRecipient $invoiceRepo->findOneBy([
  814.                 'invoiceAdressPerson' => $person,
  815.                 'id' => $request->get('invoice')
  816.             ]);
  817.         }
  818.         if ($invoiceRecipient) {
  819.             return $this->json([
  820.                 'person' => [
  821.                     'id' => $person->getId(),
  822.                     'company' => $invoiceRecipient->getCompany(),
  823.                     'name' => $invoiceRecipient->getInvoiceFullname(),
  824.                     'street' => $invoiceRecipient->getInvoiceFullStreet(),
  825.                     'place' => $invoiceRecipient->getInvoicePostalcodeCity(),
  826.                     'isInvoiceRecipient' => $person->getIsInvoiceRecipient()
  827.                 ]
  828.             ], Response::HTTP_OK);
  829.         }
  830.         //Entries from the person table
  831.         return $this->json([
  832.             'person' => [
  833.                 'id' => $person->getId(),
  834.                 'company' => $person->getCompany(),
  835.                 'name' => $person->getFullname(),
  836.                 'street' => $person->getFullStreet(),
  837.                 'place' => $person->getPostalcodeCity(),
  838.                 'isInvoiceRecipient' => $person->getIsInvoiceRecipient()
  839.             ]
  840.         ], Response::HTTP_OK);
  841.     }
  842.     private function checkForUnsetInvoiceStatus(
  843.         InvoiceRepository $invoiceRepo,
  844.         PaymentService $paymentService
  845.     ) {
  846.         $allInvoicesWithoutState $invoiceRepo->findBy(['paymentStatus' => null]);
  847.         if (!empty($allInvoicesWithoutState)) {
  848.             foreach ($allInvoicesWithoutState as $invoice) {
  849.                 $sumOfPayments $paymentService->getPayments($invoice);
  850.                 $state $paymentService->interpretPayments($sumOfPayments$invoice);
  851.                 $invoice->setPaymentStatus($state);
  852.                 $em $this->getDoctrine()->getManager();
  853.                 $em->persist($invoice);
  854.             }
  855.             $em->flush();
  856.         }
  857.     }
  858.     /**
  859.      * @Route("/{id}/payInvoice", name="pay_invoice", methods="GET|POST")
  860.      */
  861.     public function payTheBill(Invoice $invoicePaymentService $paymentService)
  862.     {
  863.         $openSum = (float) $paymentService->payAmount($invoice);
  864.         $invoicePayment = new InvoicePayment();
  865.         $invoicePayment->setInvoice($invoice);
  866.         $invoicePayment->setPayedDate(new \DateTime());
  867.         $invoicePayment->setSum($openSum);
  868.         $invoice->setPaymentStatus(Invoice::FULLY_PAID);
  869.         $em $this->getDoctrine()->getManager();
  870.         $em->persist($invoicePayment);
  871.         $em->persist($invoice);
  872.         $em->flush();
  873.         return $this->json([
  874.             'success' => "Die Rechnung wurde als bezahlt markiert.",
  875.             'invoice' => true,
  876.         ]);
  877.     }
  878. }