<?php
namespace App\Controller;
use App\Entity\Order;
use App\Entity\Person;
use App\Entity\Invoice;
use App\Form\OrderType;
use App\Entity\WaitItem;
use App\Entity\OrderItem;
use App\Service\UiService;
use App\Form\OrderStatusType;
use App\Service\OrderService;
use Doctrine\DBAL\Connection;
use App\Service\MailerService;
use App\Entity\OrderItemPerson;
use App\Service\InvoiceService;
use App\Entity\CourseOccurrence;
use App\Form\OrderItemPersonCopy;
use App\Repository\OrderRepository;
use App\Repository\WaitItemRepository;
use App\Service\EmailHistoryService;
use App\Repository\PersonRepository;
use App\Repository\InvoiceRepository;
use App\Service\ConfigurationService;
use App\Form\OrderItemPersonCancelDate;
use App\Entity\CourseSubscriptionBooking;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\Common\Collections\Collection;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
use App\Repository\OrderItemPersonRepository;
use App\Repository\CourseOccurrenceRepository;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use App\Repository\CourseOccurrenceTimeRepository;
use Symfony\Component\HttpFoundation\RequestStack;
use Menke\UserBundle\Controller\AbstractClientableController;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Menke\UserBundle\Entity\Client;
/**
* @Route("/order")
* @IsGranted("ROLE_MANAGER")
*/
class OrderController extends AbstractClientableController
{
const LISTING_LIMIT = 25;
/**
* @Route("/", name="order_index", methods="GET")
*/
public function index(
UiService $uiService,
OrderRepository $orderRepo,
OrderItemPersonRepository $orderItemPersonRepository,
Request $request,
RequestStack $requestStack
): Response {
$order = $uiService->getSortOrder('order-index-listing');
$em = $this->getDoctrine()->getManager();
$filterOrders = $request->get('orderAction');
if ($filterOrders) {
$requestStack->getSession()->set('orderFilter', $filterOrders);
} else {
$requestStack->getSession()->set('orderFilter', 'pending');
}
$dateareas = $request->get('datearea');
if ($dateareas) {
$requestStack->getSession()->set('datearea', $dateareas);
}
/* Alle Member in den Orders und order item persons abgleichen und aktualisieren
$orderstest = $orderRepo->findAll();
foreach ($orderstest as $ordertest) {
if($ordertest->getCustomer() && $ordertest->getCustomer()->getMember()){
$ordertest->setCustomerMember($ordertest->getCustomer()->getMember());
$em->persist($ordertest);}
}
$entries = $orderItemPersonRepository->findAll();
foreach ($entries as $entry) {
// Hier wird der aktualisierte Member-Wert gesetzt
if($entry->getPerson() && $entry->getPerson()->getMember()){
$entry->setMember($entry->getPerson()->getMember());
$em->persist($entry);}
}
*/
$orders = $orderRepo->getByClientPaged(
$this->getCurrentClient(),
self::LISTING_LIMIT,
$order['orderDirection'] ?? 'desc',
$order['orderBy'] ?? 'id',
1,
($filterOrders) ? $filterOrders : 'pending',
($dateareas) ? $dateareas : null,
);
return $this->render('order/index.html.twig', [
'uiService' => $uiService,
'orders' => $orders->getIterator(),
'total' => $orders->count(),
'pages' => ceil($orders->count() / self::LISTING_LIMIT),
'page' => 1,
'orderAction' => $request->get('orderAction'),
'datearea' => $request->get('datearea'),
]);
}
/**
* @Route("/fast", name="order_index_fast", methods="GET")
*/
public function indexfast(
UiService $uiService,
OrderRepository $orderRepo,
Request $request,
RequestStack $requestStack
): Response {
$order = $uiService->getSortOrder('order-index-listing');
$filterOrders = $request->get('orderAction');
if ($filterOrders) {
$requestStack->getSession()->set('orderFilter', $filterOrders);
} else {
$requestStack->getSession()->set('orderFilter', 'pending');
}
$orders = $orderRepo->getByClientPaged(
$this->getCurrentClient(),
self::LISTING_LIMIT,
$order['orderDirection'] ?? 'desc',
$order['orderBy'] ?? 'date',
1,
($filterOrders) ? $filterOrders : ''
);
return $this->render('order/fastindex.html.twig', [
'uiService' => $uiService,
'orders' => $orders->getIterator(),
'total' => $orders->count(),
'pages' => ceil($orders->count() / self::LISTING_LIMIT),
'page' => 1,
'orderAction' => $request->get('orderAction'),
]);
}
/**
* @Route("/{page}/{orderby}/{order}", name="order_index_listing", methods="GET", requirements={"page"="\d+","order"="asc|desc"})
*/
public function indexListing(
OrderRepository $orderRepo,
UiService $uiService,
$page,
$orderby,
$order,
Request $request,
RequestStack $requestStack,
): Response {
$uiService->storeSortOrder('order-index-listing', $orderby, $order);
$orders = $orderRepo->getByClientPaged(
$this->getCurrentClient(),
self::LISTING_LIMIT,
$order,
$orderby,
$page,
$requestStack->getSession()->get('orderFilter')
);
return $this->render('order/_index_listing.html.twig', [
'uiService' => $uiService,
'orders' => $orders->getIterator(),
'total' => $orders->count(),
'pages' => ceil($orders->count() / self::LISTING_LIMIT),
'page' => $page,
]);
}
/**
* @Route("/new/{return}", name="order_new", methods="GET|POST")
*/
public function new(
Request $request,
$return = '',
PersonRepository $personRepo,
ConfigurationService $configService,
OrderService $orderService,
): Response {
$customer = null;
$invoiceRecipient = null;
$isEmptyParticipants = false;
if ($return) {
$customer = $personRepo->find($return);
$invoiceRecipient = $personRepo->getInvoiceReciepientMembers($return);
$invoiceRecipient = $this->createInvoiceRecipientValues($invoiceRecipient, $customer);
$customerChildrens = $personRepo->getMembersByClient($customer);
$isEmptyParticipants = (empty($customerChildrens)) ? true : false;
}
$em = $this->getDoctrine()->getManager();
$order = new Order();
$order->setDate(new \DateTime());
$order->setStatus(Order::STATUS_PENDING);
$order->setNumber($configService->getNewOrderNumberByClient($this->getCurrentClient()));
$order->setClient($this->getCurrentClient());
$order->setCustomer($customer);
$order->setCustomerData($customer);
$order->setCreated(new \DateTime());
$order->setPerson($customer);
$form = $this->createForm(OrderType::class, $order, [
'client' => $this->getCurrentClient(),
'taxes' => $configService->getTaxConfigbyClient($this->getCurrentClient()),
'customer' => $customer,
'invoiceRecipient' => $invoiceRecipient,
'form_type' => OrderType::TYPE_CREATE_FOR_CUSTOMER
]);
$form->handleRequest($request);
// $em->persist($order);
// Check if creation is possible
if ($form->isSubmitted() && $form->isValid()) {
if (!$order->checkCustomerData($customer)) {
$this->addFlash('error', 'Die Kundendaten sind unvollständig. Es kann keine neue Bestellung angelegt werden.');
if ($return) {
return $this->redirectToRoute('customer_orders', ['id' => $return]);
} else {
return $this->redirectToRoute('order_index');
}
}
foreach ($order->getOrderItems() as $orderItem) {
if ($orderItem->getCourseOccurrence()) {
$orderItem->setCourseOccurrence($orderItem->getCourseOccurrence());
if ($orderItem->getCourseOccurrence()->getCourse()->getMaterialCost() > 0) {
$item = new OrderItem();
$item->setCourseOccurrence($orderItem->getCourseOccurrence());
$item->setPrice($orderItem->getCourseOccurrence()->getCourse()->getMaterialCost());
$item->setTaxRate($orderItem->getCourseOccurrence()->getCourse()->getTaxRate());
$item->setQuantity($orderItem->getQuantity());
// $item->setCourseItem($orderItem->getCourseOccurrence()->getCourse());
// $item->setCourseItem($orderItem);
$item->setIsFree(false);
$item->setOrder($order);
$item->setCreated(new \Datetime());
// $item->setCourseItem($orderItem);
$em->persist($item);
}
$em->persist($orderItem);
}
// Skip participants check for free items
if ($orderItem->getCourseOccurrence() === null) {
continue;
}
// Check if order item has at least one participant
if (count($orderItem->getParticipants()) == 0) {
$this->addFlash('error', 'Der Kurs enthält keine Teilnehmer.');
return $this->redirectToRoute('order_new', ['return' => $return]);
}
}
$allItemsBookable = true;
// $em->flush();
foreach ($order->getOrderItems() as $orderItem) {
$orderItem->setCourseOccurrence($orderItem->getCourseOccurrence());
$orderItem->setCreated(new \DateTime());
if ($orderItem->getCourse()) {
$orderItem->setName($orderItem->getCourse()->getTitle());
$orderItem->setDescription($orderItem->getCourse()->getSubtitle());
} else {
$orderItem->setName($orderItem->getName());
$orderItem->setDescription($orderItem->getDescription());
}
// $em->persist($orderItem);
// $em->flush($orderItem);
if ($orderItem->getCourseOccurrence()) {
$occurrence = $orderItem->getCourseOccurrence();
///// testen und abgleichen was in der Datenbank steht und wie viele Buchungen es wirklich gibt ////
// $occurrence->setBookedSlots($occurrence->getBookedSlots());
// $em->persist($occurrence);
// $em->flush($occurrence);
if (($occurrence->getSlots() < ($orderItem->getQuantity() + $occurrence->getBookedSlots())) && $occurrence->getReservationAllowed()) {
$waitItem = WaitItem::fromOrderItem($orderItem);
$waitItem->setCreated(new \DateTime());
$em->persist($waitItem);
foreach ($orderItem->getParticipants() as $participant) {
$participant->setOrderItem(null);
$participant->setTitle($participant->getPerson()->getTitle());
$participant->setSalutation($participant->getPerson()->getSalutation());
$participant->setMember($participant->getPerson()->getMember());
$participant->setFirstname($participant->getPerson()->getFirstname());
$participant->setLastname($participant->getPerson()->getLastname());
$participant->setDateOfBirth($participant->getPerson()->getDateOfBirth());
$participant->setComment($participant->getPerson()->getComment());
$participant->setOrderItem($orderItem);
$participant->setCreated(new \DateTime());
// $orderItem->removeParticipant($participant);
//$orderItem->setQuantity($orderItem->getQuantity() - 1);
$em->persist($participant);
}
$order->addWaitItem($waitItem);
$this->addFlash('error', 'Im Kurs "' . $occurrence->getTitle() . '" sind nicht mehr genug Plätze verfügbar. Es fehlen "' . ($orderItem->getQuantity() + $occurrence->getBookedSlots()) - $occurrence->getSlots() . '" Plätze. Die komplette Buchung wurde stattdessen zur Warteliste hinzugefügt.');
$em->flush();
// $order->removeOrderItem($orderItem);
$orderItem->setOrder(null);
$orderItem->setStatus('wait_item');
//$orderItem->setCancelledQuantity($orderItem->getQuantity());
// $orderItem->setQuantity($orderItem->getQuantity());
$em->persist($orderItem);
$em->persist($order);
//$em->remove($orderItem);
$em->flush();
// var_dump($orderItem->getOrder());
return $this->redirectToRoute('customer_orders', ['id' => $return]);
} elseif (($occurrence->getSlots() < ($orderItem->getQuantity() + $occurrence->getBookedSlots())) && !$occurrence->getReservationAllowed()) {
// $occurrence->setBookedSlots($occurrence->getBookedSlots());
$em->persist($occurrence);
$em->remove($order);
$em->flush();
$allItemsBookable = false;
$this->addFlash('error', 'Im Kurs "' . $occurrence->getTitle() . '" sind nicht mehr genug Plätze verfügbar. Es fehlen "' . ($orderItem->getQuantity() + $occurrence->getBookedSlots()) - $occurrence->getSlots() . '" Plätze.');
return $this->redirectToRoute('customer_orders', ['id' => $return]);
} else {
if ($orderItem->getCourseOccurrence()->getCourse()->getCourseNature() == 'CourseSubscription') {
// $courseSubscriptionBooking = new CourseSubscriptionBooking($orderItem, $orderItem->getCourse());
// $courseSubscriptionBooking->setOrderItem($orderItem);
// $courseSubscriptionBooking->setCourse($orderItem->getCourseOccurrence()->getCourse());
// $courseSubscriptionBooking->setCourseSubscription($orderItem->getCourseOccurrence()->getCourse()->getSubscription());
// $orderItem->setCourseSubscriptionBooking($courseSubscriptionBooking);
// $em->persist($courseSubscriptionBooking);
}
/*
foreach ($orderItem->getParticipants() as $participant)
{
$occurrence->setBookedSlots($occurrence->getBookedSlots() + 1);
}
$em->persist($occurrence);
*/
// $em->persist($occurrence);
// $occurrence = $orderItem->getCourseOccurrence();
// $occurrence->setBookedSlots($occurrence->getBookedSlotsDirectly() + $orderItem->getQuantity());
// $occurrence->setBookedSlots($occurrence->getBookedSlots() + $orderItem->getQuantity());
// $em->persist($occurrence);
// $em->flush();
// $occurrences[] = $occurrence;
}
}
// $em->flush();
}
$this->updateParticipantsOfOrder($order);
if ($orderItem->getCourse()) {
$occurrence->setBookedSlots($occurrence->getBookedSlots() + $orderItem->getQuantity());
}
// $em->flush();
if ($allItemsBookable) {
if (count($order->getOrderItems()) > 0 || count($order->getWaitItems()) > 0) {
$order->setClient($this->getCurrentClient());
$order->setCustomer($customer);
$order->setCustomerData($customer);
if ($customer->getIban()) {
$order->setPaymentType(Order::PAYMENT_DEBIT);
$order->setIban($customer->getIban());
$order->setBic($customer->getBic());
$order->setBank($customer->getBank());
}
$orderItem->setOrder($order);
$orderItem->getCourseOccurrence();
// Ggf. nachfolgende Bestellungen fuer Abokurse generieren und speichern
$flashs = [];
$followingOrders = $orderService->generateOrdersForSubscriptionCoursesAllFollowingOccurrences($this->getCurrentClient(), $order, $flashs);
foreach ($followingOrders as $orderToSave) {
$em->persist($orderToSave);
}
foreach ($flashs as $flashToShow) {
foreach ($flashToShow as $key => $value) {
$this->addFlash($key, $value);
}
}
}
/*
foreach ($order->getOrderItems() as $orderItem) {
if ($orderItem->getMaterialCosts()) {
$item = new OrderItem();
$item->setCourseOccurrence($orderItem->getCourseOccurrence());
$item->setPrice($orderItem->getCourseOccurrence()->getCourse()->getMaterialCost());
$item->setTaxRate($orderItem->getCourseOccurrence()->getCourse()->getTaxRate());
$item->setQuantity(1);
$item->setIsFree(false);
$item->setOrder($order);
$item->setCourseItem($orderItem);
$item->setCreated(new \Datetime());
}
$em->persist($item);
}
*/
$em->persist($order);
$em->flush();
if ($return) {
if ($orderItem->getCourse()) {
$this->addFlash('warning', 'Der Kurs "' . $occurrence->getTitle() . '" wurde mit ' . $orderItem->getQuantity() . ' Plätzen bebucht');
}
return $this->redirectToRoute('customer_orders', ['id' => $return]);
} else {
return $this->redirectToRoute('order_index');
}
}
$em->remove($orderItem);
$em->remove($order);
$em->flush();
$this->addFlash('warning', 'LETZTE MÖGLICHKEIT "' . $occurrence->getTitle() . '" ' . $occurrence->getSlots() . ' | ' . $occurrence->getBookedSlots() . '|' . ($occurrence->getSlots() - $occurrence->getBookedSlots()) . ' | ' . $orderItem->getQuantity());
}
return $this->render('order/new.html.twig', [
'order' => $order,
'form' => $form->createView(),
'customer' => $customer,
'invoiceRecipient' => $invoiceRecipient,
'invalidCustomerData' => !$order->checkCustomerData($customer),
'isEmptyParticipants' => $isEmptyParticipants,
'isInvoiceClosed' => false
]);
}
/**
* @Route("/{id}", name="order_show", methods="GET|POST", requirements={"id"="\d+"})
*/
public function show(
Request $request,
Order $order,
InvoiceRepository $invoiceRepo
): Response {
$this->denyAccessUnlessGranted('ROLE_MANAGER', $order);
$form = $this->createForm(OrderStatusType::class, $order);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('order_show', ['id' => $order->getId()]);
}
$orderedInvoices = $invoiceRepo->getOrderedInvoices($order->getId());
$isInvoiceWithCancillation = $this->isInvoiceWithCancillation($order->getInvoices());
return $this->render('order/show.html.twig', [
'order' => $order,
'form' => $form->createView(),
'isInvoiceWithCancillation' => $isInvoiceWithCancillation,
'orderedInvoices' => $orderedInvoices
]);
}
/**
* @Route("/search/{occurrenceId}/{timeId}", name="order_search", methods="GET|POST", requirements={"id"="\d+"})
*/
public function search(
Request $request,
Connection $connection,
CourseOccurrenceTimeRepository $timeRepository
): Response {
$time = $timeRepository->find($request->get('timeId'));
$sql = 'SELECT
oi.*
FROM
customer_order_item oi,
course_occurrence o
WHERE
o.id = oi.course_occurrence_id AND
o.start = "' . $time->getStart()->format('Y-m-d H:i:s') . '"
GROUP BY
oi._order_id';
$result = $connection->fetchAssoc($sql);
if (empty($result)) {
$sql = 'SELECT
oi.*
FROM
wait_item oi,
course_occurrence o
WHERE
o.id = oi.course_occurrence_id AND
o.start = "' . $time->getStart()->format('Y-m-d H:i:s') . '"
GROUP BY
oi._order_id';
$result = $connection->fetchAssoc($sql);
}
return $this->redirectToRoute('order_show', ['id' => $result['_order_id']]);
}
/**
* @Route("/{id}/edit/{return}", name="order_edit", methods="GET|POST", requirements={"id"="\d+","return"="\d+"})
*/
public function edit(
Request $request,
Order $order,
$return = '',
ConfigurationService $configService,
PersonRepository $personRepo
): Response {
$isEmptyParticipants = false;
$invoiceRecipient = null;
$isInvoiceClosed = false;
$this->denyAccessUnlessGranted('ROLE_MANAGER', $order);
$order->setModified(new \DateTime());
$customer = null;
if ($order->getCustomer()) {
$customer = $order->getCustomer();
}
if (
$order->getInvoices()->first() &&
$order->getInvoices()->first()->getStatus() == Invoice::STATUS_CLOSED
) {
$isInvoiceClosed = true;
}
if ($return) {
$customer = $personRepo->find($return);
$invoiceRecipient = $personRepo->getInvoiceReciepientMembers($return);
$invoiceRecipient = $this->createInvoiceRecipientValues($invoiceRecipient, $customer);
$customerChildrens = $personRepo->getMembersByClient($customer);
$isEmptyParticipants = (empty($customerChildrens)) ? true : false;
}
if ($order->getStatus() != Order::STATUS_PENDING) {
$this->addFlash('notice', 'Die Bestellung kann nur bearbeitet werden wenn Sie in Wartestellung ist.');
if ($return) {
return $this->redirectToRoute('customer_orders', ['id' => $return]);
} else {
return $this->redirectToRoute('order_index');
}
}
$form = $this->createForm(OrderType::class, $order, [
'client' => $this->getCurrentClient(),
'taxes' => $configService->getTaxConfigbyClient($this->getCurrentClient()),
'invoiceRecipient' => $invoiceRecipient,
'customer' => $customer,
'form_type' => OrderType::TYPE_CREATE_FOR_CUSTOMER
]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->updateParticipantsOfOrder($order);
$em = $this->getDoctrine()->getManager();
foreach ($order->getOrderItems() as $item) {
$item->setModified(new \DateTime());
if (!$item->isFree() && $item->getCourseOccurrence()) {
$item->setName($item->getCourseOccurrence()->getTitle());
$em->persist($item);
} else {
$item->setCourseOccurrence(null);
$em->persist($item);
}
}
$em->flush();
$this->addFlash('notice', 'Die Bestellung wurde bearbeitet.');
return $this->redirectToRoute('order_index');
// }
}
return $this->render('order/edit.html.twig', [
'order' => $order,
'form' => $form->createView(),
'customer' => $customer,
'isEmptyParticipants' => $isEmptyParticipants,
'invoiceRecipient' => $invoiceRecipient,
'isInvoiceClosed' => $isInvoiceClosed
]);
}
/**
* @Route("/{id}/cancel", name="order_cancel", methods="POST")
*/
public function cancel(
Request $request,
Order $order,
ConfigurationService $configService,
OrderService $orderService
): Response {
$this->denyAccessUnlessGranted('ROLE_MANAGER', $order);
if ($this->isCsrfTokenValid('cancel' . $order->getId(), $request->request->get('_token'))) {
$em = $this->getDoctrine()->getManager();
foreach ($order->getOrderItems() as $orderItem) {
// If order item is connected to time slot mark it bookable again
if ($time = $orderItem->getCourseOccurrenceTime()) {
$time->setAvailability('Bookable');
$time->setOrderItem(null);
}
if ($orderItem) {
$orderItem->setStatus('cancelled');
foreach ($orderItem->getParticipants() as $person) {
$person->setStatus('cancelled');
$person->setCancelled(new \DateTime());
$person->setModified(new \DateTime());
$em->persist($person);
}
$orderItem->setCancelledQuantity($orderItem->getCancelledQuantity() + 1);
$orderItem->setQuantity($orderItem->getQuantity() - 1);
$orderItem->setModified(new \DateTime());
//$orderItem->setQuantity('0');
}
}
foreach ($order->getWaitItems() as $waitItem) {
if ($time = $waitItem->getCourseOccurrenceTime()) {
$time->setAvailability('Requestable');
$time->setWaitItem(null);
}
}
foreach ($order->getInvoices() as $invoice) {
if (!$invoice->isCancelled() && !$invoice->isCancellation()) {
$cancellation = $orderService->createCancellation($invoice);
$cancellation->setSignedBy($this->getCurrentUser());
$invoice->setCancelled(true);
$em->persist($cancellation);
}
}
$order->setStatus(Order::STATUS_CANCELLED);
$order->setModified(new \DateTime());
$orderService->calculateCancelOrderItems($order);
$em->flush();
$this->addFlash('notice', 'Bestellung storniert');
}
return $this->redirectToRoute('order_show', ['id' => $order->getId()]);
}
/**
* @Route("/set-cancel-date/{id}", name="participant_set-cancel-date")
*/
public function setCancelDateForParticicpant(
Request $request,
OrderItemPerson $participant,
OrderService $orderService,
RequestStack $requestStack,
ManagerRegistry $managerRegistry,
// LoggerInterface $logger
): Response {
$this->denyAccessUnlessGranted('ROLE_MANAGER', $participant->getOrderItem()->getOrder());
$form = $this->createForm(OrderItemPersonCancelDate::class, null, [
'action' => $this->generateUrl('participant_set-cancel-date', ['id' => $participant->getId()])
]);
$form->handleRequest($request);
$participant->setCancelled($orderService->getCancelDateForParticipantInCourse($this->getCurrentClient(), $participant));
if ($form->isSubmitted() && $form->isValid()) {
/**
* @var \DateTimeInterface $cancelDate
*/
$cancelDate = $form->getData()['cancelDate'];
// Kuendigungsdatum in entsprechenden Teilnehmereintrag im Kurs schreiben
$participant->setCancelled($cancelDate);
$em = $managerRegistry->getManager();
$booking = $participant->getOrderItem()->getCourseSubscriptionBooking();
if (!empty($booking)) {
$terminationPeriod = $booking->getCourseSubscription()->getTerminationPeriodMonths();
$cancellationTimestamp = strtotime('+' . $terminationPeriod . ' months', $cancelDate->getTimeStamp());
$cancelDate->setTimestamp($cancellationTimestamp);
}
$result = $orderService->setCancelDateForParticipantInCourse(
$this->getCurrentClient(),
$participant,
$cancelDate
);
$em->flush();
// Aktive Eintraege/Bestellpositionen/Bestellungen fuer Kurstermine nach dem Kuendigungsdatum erhalten
$oipsToCancel = $orderService->getAllActiveParticipationsAfterCancelDateByParticipant(
$this->getCurrentClient(),
$participant
);
// Diese Eintraege einzeln durchlaufen und stornieren
foreach ($oipsToCancel as $oipToCancel) {
// Bei schon vorhandenen Rechnungen ggf. Storno-Rechnungen erstellen
foreach ($oipToCancel->getOrderItem()->getOrder()->getInvoices() as $invoice) {
if (!$invoice->isCancelled() && !$invoice->isCancellation() && $invoice->containsOrderItem($oipToCancel->getOrderItem())) {
$cancellation = $orderService->createCancellation($invoice, $oipToCancel->getOrderItem(), $oipToCancel->getId());
$cancellation->setSignedBy($this->getCurrentUser());
$em->persist($cancellation);
}
}
// Eintrag stornieren
$orderService->cancelOrderItemParticipant($oipToCancel->getOrderItem(), $oipToCancel->getId());
// Ggf. Bestellposition stornieren
if (!$oipToCancel->getOrderItem()->hasUncancelledParticipants()) {
$oipToCancel->getOrderItem()->setStatus(OrderItem::STATUS_CANCELLED);
foreach ($oipToCancel->getOrderItem()->getMaterialCosts() as $materialCost) {
$materialCost->setStatus(OrderItem::STATUS_CANCELLED);
}
}
// Ggf. Bestellung stornieren
if (!$oipToCancel->getOrderItem()->getOrder()->hasUncancelledItems()) {
$oipToCancel->getOrderItem()->getOrder()->setStatus(Order::STATUS_CANCELLED);
}
$orderService->calculateCancelOrderItem($oipToCancel->getOrderItem());
}
// Aenderungen in Datenbank speichern
$em->flush();
$flashExists = false;
foreach ($requestStack->getSession()->all() as $flashType => $flashTitle) {
if ($flashType == 'notice' && $flashTitle == 'Kündigungsdatum eingetragen') $flashExists = true;
}
if (!$flashExists) $this->addFlash('notice', 'Kündigungsdatum eingetragen');
$route = $request->headers->get('referer');
return $this->redirect($route);
}
return $this->render('course/_set-cancel-date.html.twig', [
'person' => $participant->getPerson(),
'form' => $form->createView(),
'cancelDate' => $participant->getCancelled(),
'today' => new \DateTime()
]);
}
/**
* @Route("/{id}/cancel-item/{participantId}/{return}", name="order-item_cancel", methods="GET")
*/
public function cancelItem(
Request $request,
OrderItem $orderItem,
int $participantId = 0,
string $return = '',
ConfigurationService $configService,
OrderService $orderService
): Response {
$order = $orderItem->getOrder();
$this->denyAccessUnlessGranted('ROLE_MANAGER', $order);
$em = $this->getDoctrine()->getManager();
foreach ($order->getInvoices() as $invoice) {
if (!$invoice->isCancelled() && !$invoice->isCancellation() && $invoice->containsOrderItem($orderItem)) {
$cancellation = $orderService->createCancellation($invoice, $orderItem, $participantId);
$cancellation->setSignedBy($this->getCurrentUser());
$em->persist($cancellation);
}
}
if ($participantId > 0) {
$orderService->cancelOrderItemParticipant($orderItem, $participantId);
} else {
$orderItem->cancelAllParticipants();
}
if (!$orderItem->hasUncancelledParticipants()) {
$orderItem->setStatus(OrderItem::STATUS_CANCELLED);
foreach ($orderItem->getMaterialCosts() as $materialCost) {
$materialCost->setStatus(OrderItem::STATUS_CANCELLED);
}
}
if (!$order->hasUncancelledItems()) {
$order->setStatus(Order::STATUS_CANCELLED);
}
$orderService->calculateCancelOrderItem($orderItem);
$orderItem->setModified(new \DateTime());
$order->setModified(new \DateTime());
$em->flush();
$this->addFlash('notice', 'Kurs storniert');
// return $this->redirect(urldecode($return));
return $this->redirectToRoute('course_invoices', ['id' => $request->get('course_id')]);
}
/**
* @Route("/copy-participant/{id}", name="participant_copy-to-other-occurrence")
*/
public function copyParticipantToOtherOccurrence(
Request $request,
OrderItemPerson $participant,
OrderService $orderService,
CourseOccurrenceRepository $coRepo,
RequestStack $requestStack
): Response {
$this->denyAccessUnlessGranted('ROLE_MANAGER', $participant->getOrderItem()->getOrder());
$selectableOccurrences = $orderService->getAllOccurrencesOfCourseAParticipantIsNotInBeforeCancelDate($this->getCurrentClient(), $participant);
$selectableOccurrencesArray = [];
foreach ($selectableOccurrences as $selectableOccurrence) {
$selectableOccurrencesArray[$selectableOccurrence->getStart()->format('d.m.Y') . ' - ' . $selectableOccurrence->getEnd()->format('d.m.Y')] = $selectableOccurrence->getId();
}
$form = $this->createForm(OrderItemPersonCopy::class, null, [
'occurrences' => $selectableOccurrencesArray,
'action' => $this->generateUrl('participant_copy-to-other-occurrence', ['id' => $participant->getId()])
]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$flashs = [];
$orders = [];
foreach ($form->getData()['occurrences'] as $occurrenceId) {
$flash = [];
$occurrence = $coRepo->find($occurrenceId);
$newOrder = $orderService->generateOrderForCourseOccurrenceFromOrderItemPerson(
$this->getCurrentClient(),
$participant,
$occurrence,
$flash,
false
);
if ($newOrder !== null) {
$orders[] = $newOrder;
}
if (count($flash) > 0) {
$flashs[] = $flash;
}
}
foreach ($orders as $orderToSave) {
$em->persist($orderToSave);
}
foreach ($flashs as $flashToShow) {
foreach ($flashToShow as $key => $value) {
$this->addFlash($key, $value);
}
}
// Aenderungen in Datenbank speichern
$em->flush();
$flashExists = false;
foreach ($requestStack->getSession()->all() as $flashType => $flashTitle) {
if ($flashType == 'notice' && $flashTitle == 'Teilnehmer in ' . count($orders) . ' weitere Termine übernommen') $flashExists = true;
}
if (!$flashExists) $this->addFlash('notice', 'Teilnehmer in ' . count($orders) . ' weitere Termine übernommen');
return $this->redirectToRoute('course_participants', ['id' => $participant->getOrderItem()->getCourseOccurrence()->getCourse()->getId()]);
}
return $this->render('course/_copy-to-occurrence.html.twig', [
'person' => $participant->getPerson(),
'form' => $form->createView(),
]);
}
/**
* @Route("/{id}/create-invoice", name="order_invoice_create", methods="GET")
*/
public function createInvoice(
Request $request,
Order $order,
InvoiceService $invoiceService
): Response {
$results = $invoiceService->createInvoiceFromOrder($order);
$em = $this->getDoctrine()->getManager();
//Update the order status
$newOrderState = $order->setStatus(Order::STATUS_PROCESSING);
$em->persist($newOrderState);
foreach ($results['attendees'] as $attendee) {
$em->persist($attendee);
}
$em->persist($results['invoice']);
$em->flush();
$this->addFlash('notice', ' Rechnung erstellt');
return $this->redirectToRoute('order_show', ['id' => $order->getId()]);
}
/**
* @Route("/{id}", name="order_delete", methods="DELETE")
*/
public function delete(Request $request, Order $order): Response
{
if ($this->isCsrfTokenValid('delete' . $order->getId(), $request->request->get('_token'))) {
$em = $this->getDoctrine()->getManager();
$em->remove($order);
$em->flush();
}
return $this->redirectToRoute('order_index');
}
protected function updateParticipantsOfOrder(Order $order)
{
if (count($order->getOrderItems()) > 0) {
foreach ($order->getOrderItems() as $orderItem) {
if (count($orderItem->getParticipants()) > 0) {
foreach ($orderItem->getParticipants() as $participant) {
$participant->updateFieldsFromPerson();
}
}
}
}
}
private function createInvoiceRecipientValues($persons, $customer)
{
$res[] = $customer;
foreach ($persons as $person) {
$res[] = $person;
}
return $res;
}
/**
* isInvoiceWithCancillation
*
* Checks whether one of the invoices is a cancellation invoice
*
* @param Collection $invoices
* @return boolean
*/
private function isInvoiceWithCancillation(Collection $invoices)
{
$cancelation = false;
if (empty($invoices)) return $cancelation;
$counter = count($invoices);
if ($counter < 2 || !($invoices[$counter - 1]->isCancellation())) return $cancelation;
foreach ($invoices as $invoice) {
if ($invoice->isCancellation()) {
$cancelation = true;
break;
}
}
return $cancelation;
}
/**
* @Route("/changestatus/{id}/{status}", name="change_status")
*/
public function changeStatus(Order $order, $status): Response
{
$em = $this->getDoctrine()->getManager();
$newstatus = $order->setStatus($status);
$em->persist($newstatus);
$em->flush();
return $this->json([
'success' => 'Der Status wurde geändert.'
]);
}
/**
* @Route("/sendordermail/{id}", name="send_order_mail")
*/
public function sendordermail(Order $order, PersonRepository $personRepo, EmailHistoryService $emailHistoryService, MailerService $mailerService, Connection $connection): Response
{
foreach ($order->getOrderItems() as $item) {
/////////////////////////////////// FIELDS Start //////////////////////////////////////
// Fetch course fields
$sql = 'SELECT
f.*,
d.value_text,
d.value_integer
FROM
course_field f
LEFT JOIN
course_data d
ON
d.field_id = f.id AND
d.course_id = :courseId
WHERE f.certificate = 0';
$stmt = $connection->prepare($sql);
$stmt->bindValue(
'courseId',
$item->getCourseOccurrence()->getCourse()->getId()
);
$stmt->executeQuery();
$result = $stmt->fetchAll();
$fields = [];
foreach ($result as $index => $field) {
if (!empty($field['category'])) {
if (!$item->getCourseOccurrence()->getCourse()->getCategory()) {
continue;
}
if (!in_array($item->getCourseOccurrence()->getCourse()->getCategory()->getId(), json_decode($field['category'], true))) {
continue;
}
}
if (!empty($field['course_type'])) {
if (!$item->getCourseOccurrence()->getCourse()->getType()) {
continue;
}
if (!in_array($item->getCourseOccurrence()->getCourse()->getType()->getId(), json_decode($field['course_type'], true))) {
continue;
}
}
$fields[] = [
'id' => $field['id'],
'name' => $field['name'],
'value' => !empty($field['value_integer']) ? $field['value_integer'] : $field['value_text'],
];
}
$order->setFields($fields);
$sentMessage = $mailerService->sendCheckoutConfirmMessage($order);
$customer = $order->getCustomer();
$emailHistoryService->saveProtocolEntryFromOrder(
$order,
$this->getCurrentClient(),
$customer,
'versandt',
$sentMessage['subject'],
$sentMessage['message'],
'Bestellbestätigung gesendet',
$sentMessage['email']
);
$message = "Bestellbestätigung ist versendet" ;
$this->addFlash('notice', $message);
return $this->redirectToRoute('order_index');
}
}
}