src/Controller/InvoiceController.php line 230

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