src/Controller/InvoiceController.php line 229

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