src/Controller/InvoiceController.php line 770

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