src/Eccube/Controller/Admin/Order/OrderController.php line 196

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of EC-CUBE
  4.  *
  5.  * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
  6.  *
  7.  * http://www.ec-cube.co.jp/
  8.  *
  9.  * For the full copyright and license information, please view the LICENSE
  10.  * file that was distributed with this source code.
  11.  */
  12. namespace Eccube\Controller\Admin\Order;
  13. use Eccube\Common\Constant;
  14. use Eccube\Controller\AbstractController;
  15. use Eccube\Entity\ExportCsvRow;
  16. use Eccube\Entity\Master\CsvType;
  17. use Eccube\Entity\Master\OrderStatus;
  18. use Eccube\Entity\OrderPdf;
  19. use Eccube\Entity\Shipping;
  20. use Eccube\Event\EccubeEvents;
  21. use Eccube\Event\EventArgs;
  22. use Eccube\Form\Type\Admin\OrderPdfType;
  23. use Eccube\Form\Type\Admin\SearchOrderType;
  24. use Eccube\Repository\CustomerRepository;
  25. use Eccube\Repository\Master\OrderStatusRepository;
  26. use Eccube\Repository\Master\PageMaxRepository;
  27. use Eccube\Repository\Master\ProductStatusRepository;
  28. use Eccube\Repository\Master\SexRepository;
  29. use Eccube\Repository\OrderPdfRepository;
  30. use Eccube\Repository\OrderRepository;
  31. use Eccube\Repository\PaymentRepository;
  32. use Eccube\Repository\ProductStockRepository;
  33. use Eccube\Service\CsvExportService;
  34. use Eccube\Service\MailService;
  35. use Eccube\Service\OrderPdfService;
  36. use Eccube\Service\OrderStateMachine;
  37. use Eccube\Service\PurchaseFlow\PurchaseFlow;
  38. use Eccube\Util\FormUtil;
  39. use Knp\Component\Pager\PaginatorInterface;
  40. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  41. use Symfony\Component\Form\FormBuilder;
  42. use Symfony\Component\HttpFoundation\RedirectResponse;
  43. use Symfony\Component\HttpFoundation\Request;
  44. use Symfony\Component\HttpFoundation\Response;
  45. use Symfony\Component\HttpFoundation\StreamedResponse;
  46. use Symfony\Component\Routing\Annotation\Route;
  47. use Symfony\Component\Validator\Constraints as Assert;
  48. use Symfony\Component\Validator\Validator\ValidatorInterface;
  49. class OrderController extends AbstractController
  50. {
  51.     /**
  52.      * @var PurchaseFlow
  53.      */
  54.     protected $purchaseFlow;
  55.     /**
  56.      * @var CsvExportService
  57.      */
  58.     protected $csvExportService;
  59.     /**
  60.      * @var CustomerRepository
  61.      */
  62.     protected $customerRepository;
  63.     /**
  64.      * @var PaymentRepository
  65.      */
  66.     protected $paymentRepository;
  67.     /**
  68.      * @var SexRepository
  69.      */
  70.     protected $sexRepository;
  71.     /**
  72.      * @var OrderStatusRepository
  73.      */
  74.     protected $orderStatusRepository;
  75.     /**
  76.      * @var PageMaxRepository
  77.      */
  78.     protected $pageMaxRepository;
  79.     /**
  80.      * @var ProductStatusRepository
  81.      */
  82.     protected $productStatusRepository;
  83.     /**
  84.      * @var OrderRepository
  85.      */
  86.     protected $orderRepository;
  87.     /** @var OrderPdfRepository */
  88.     protected $orderPdfRepository;
  89.     /**
  90.      * @var ProductStockRepository
  91.      */
  92.     protected $productStockRepository;
  93.     /** @var OrderPdfService */
  94.     protected $orderPdfService;
  95.     /**
  96.      * @var ValidatorInterface
  97.      */
  98.     protected $validator;
  99.     /**
  100.      * @var OrderStateMachine
  101.      */
  102.     protected $orderStateMachine;
  103.     /**
  104.      * @var MailService
  105.      */
  106.     protected $mailService;
  107.     /**
  108.      * OrderController constructor.
  109.      *
  110.      * @param PurchaseFlow $orderPurchaseFlow
  111.      * @param CsvExportService $csvExportService
  112.      * @param CustomerRepository $customerRepository
  113.      * @param PaymentRepository $paymentRepository
  114.      * @param SexRepository $sexRepository
  115.      * @param OrderStatusRepository $orderStatusRepository
  116.      * @param PageMaxRepository $pageMaxRepository
  117.      * @param ProductStatusRepository $productStatusRepository
  118.      * @param ProductStockRepository $productStockRepository
  119.      * @param OrderRepository $orderRepository
  120.      * @param OrderPdfRepository $orderPdfRepository
  121.      * @param ValidatorInterface $validator
  122.      * @param OrderStateMachine $orderStateMachine ;
  123.      */
  124.     public function __construct(
  125.         PurchaseFlow $orderPurchaseFlow,
  126.         CsvExportService $csvExportService,
  127.         CustomerRepository $customerRepository,
  128.         PaymentRepository $paymentRepository,
  129.         SexRepository $sexRepository,
  130.         OrderStatusRepository $orderStatusRepository,
  131.         PageMaxRepository $pageMaxRepository,
  132.         ProductStatusRepository $productStatusRepository,
  133.         ProductStockRepository $productStockRepository,
  134.         OrderRepository $orderRepository,
  135.         OrderPdfRepository $orderPdfRepository,
  136.         ValidatorInterface $validator,
  137.         OrderStateMachine $orderStateMachine,
  138.         MailService $mailService
  139.     ) {
  140.         $this->purchaseFlow $orderPurchaseFlow;
  141.         $this->csvExportService $csvExportService;
  142.         $this->customerRepository $customerRepository;
  143.         $this->paymentRepository $paymentRepository;
  144.         $this->sexRepository $sexRepository;
  145.         $this->orderStatusRepository $orderStatusRepository;
  146.         $this->pageMaxRepository $pageMaxRepository;
  147.         $this->productStatusRepository $productStatusRepository;
  148.         $this->productStockRepository $productStockRepository;
  149.         $this->orderRepository $orderRepository;
  150.         $this->orderPdfRepository $orderPdfRepository;
  151.         $this->validator $validator;
  152.         $this->orderStateMachine $orderStateMachine;
  153.         $this->mailService $mailService;
  154.     }
  155.     /**
  156.      * 受注一覧画面.
  157.      *
  158.      * - 検索条件, ページ番号, 表示件数はセッションに保持されます.
  159.      * - クエリパラメータでresume=1が指定された場合、検索条件, ページ番号, 表示件数をセッションから復旧します.
  160.      * - 各データの, セッションに保持するアクションは以下の通りです.
  161.      *   - 検索ボタン押下時
  162.      *      - 検索条件をセッションに保存します
  163.      *      - ページ番号は1で初期化し、セッションに保存します。
  164.      *   - 表示件数変更時
  165.      *      - クエリパラメータpage_countをセッションに保存します。
  166.      *      - ただし, mtb_page_maxと一致しない場合, eccube_default_page_countが保存されます.
  167.      *   - ページング時
  168.      *      - URLパラメータpage_noをセッションに保存します.
  169.      *   - 初期表示
  170.      *      - 検索条件は空配列, ページ番号は1で初期化し, セッションに保存します.
  171.      *
  172.      * @Route("/%eccube_admin_route%/order", name="admin_order", methods={"GET", "POST"})
  173.      * @Route("/%eccube_admin_route%/order/page/{page_no}", requirements={"page_no" = "\d+"}, name="admin_order_page", methods={"GET", "POST"})
  174.      * @Template("@admin/Order/index.twig")
  175.      */
  176.     public function index(Request $requestPaginatorInterface $paginator$page_no null)
  177.     {
  178.         $builder $this->formFactory
  179.             ->createBuilder(SearchOrderType::class);
  180.         $event = new EventArgs(
  181.             [
  182.                 'builder' => $builder,
  183.             ],
  184.             $request
  185.         );
  186.         $this->eventDispatcher->dispatch($eventEccubeEvents::ADMIN_ORDER_INDEX_INITIALIZE);
  187.         $searchForm $builder->getForm();
  188.         /**
  189.          * ページの表示件数は, 以下の順に優先される.
  190.          * - リクエストパラメータ
  191.          * - セッション
  192.          * - デフォルト値
  193.          * また, セッションに保存する際は mtb_page_maxと照合し, 一致した場合のみ保存する.
  194.          **/
  195.         $page_count $this->session->get('eccube.admin.order.search.page_count',
  196.             $this->eccubeConfig->get('eccube_default_page_count'));
  197.         $page_count_param = (int) $request->get('page_count');
  198.         $pageMaxis $this->pageMaxRepository->findAll();
  199.         if ($page_count_param) {
  200.             foreach ($pageMaxis as $pageMax) {
  201.                 if ($page_count_param == $pageMax->getName()) {
  202.                     $page_count $pageMax->getName();
  203.                     $this->session->set('eccube.admin.order.search.page_count'$page_count);
  204.                     break;
  205.                 }
  206.             }
  207.         }
  208.         if ('POST' === $request->getMethod()) {
  209.             $searchForm->handleRequest($request);
  210.             if ($searchForm->isValid()) {
  211.                 /**
  212.                  * 検索が実行された場合は, セッションに検索条件を保存する.
  213.                  * ページ番号は最初のページ番号に初期化する.
  214.                  */
  215.                 $page_no 1;
  216.                 $searchData $searchForm->getData();
  217.                 // 検索条件, ページ番号をセッションに保持.
  218.                 $this->session->set('eccube.admin.order.search'FormUtil::getViewData($searchForm));
  219.                 $this->session->set('eccube.admin.order.search.page_no'$page_no);
  220.             } else {
  221.                 // 検索エラーの際は, 詳細検索枠を開いてエラー表示する.
  222.                 return [
  223.                     'searchForm' => $searchForm->createView(),
  224.                     'pagination' => [],
  225.                     'pageMaxis' => $pageMaxis,
  226.                     'page_no' => $page_no,
  227.                     'page_count' => $page_count,
  228.                     'has_errors' => true,
  229.                 ];
  230.             }
  231.         } else {
  232.             if (null !== $page_no || $request->get('resume')) {
  233.                 /*
  234.                  * ページ送りの場合または、他画面から戻ってきた場合は, セッションから検索条件を復旧する.
  235.                  */
  236.                 if ($page_no) {
  237.                     // ページ送りで遷移した場合.
  238.                     $this->session->set('eccube.admin.order.search.page_no', (int) $page_no);
  239.                 } else {
  240.                     // 他画面から遷移した場合.
  241.                     $page_no $this->session->get('eccube.admin.order.search.page_no'1);
  242.                 }
  243.                 $viewData $this->session->get('eccube.admin.order.search', []);
  244.                 $searchData FormUtil::submitAndGetData($searchForm$viewData);
  245.             } else {
  246.                 /**
  247.                  * 初期表示の場合.
  248.                  */
  249.                 $page_no 1;
  250.                 $viewData = [];
  251.                 if ($statusId = (int) $request->get('order_status_id')) {
  252.                     $viewData = ['status' => [$statusId]];
  253.                 }
  254.                 $searchData FormUtil::submitAndGetData($searchForm$viewData);
  255.                 // セッション中の検索条件, ページ番号を初期化.
  256.                 $this->session->set('eccube.admin.order.search'$viewData);
  257.                 $this->session->set('eccube.admin.order.search.page_no'$page_no);
  258.             }
  259.         }
  260.         $qb $this->orderRepository->getQueryBuilderBySearchDataForAdmin($searchData);
  261.         $event = new EventArgs(
  262.             [
  263.                 'qb' => $qb,
  264.                 'searchData' => $searchData,
  265.             ],
  266.             $request
  267.         );
  268.         $this->eventDispatcher->dispatch($eventEccubeEvents::ADMIN_ORDER_INDEX_SEARCH);
  269.         $sortKey $searchData['sortkey'];
  270.         if (empty($this->orderRepository::COLUMNS[$sortKey]) || $sortKey == 'order_status') {
  271.             $pagination $paginator->paginate(
  272.                 $qb,
  273.                 $page_no,
  274.                 $page_count
  275.             );
  276.         } else {
  277.             $pagination $paginator->paginate(
  278.                 $qb,
  279.                 $page_no,
  280.                 $page_count,
  281.                 ['wrap-queries' => true]
  282.             );
  283.         }
  284.         return [
  285.             'searchForm' => $searchForm->createView(),
  286.             'pagination' => $pagination,
  287.             'pageMaxis' => $pageMaxis,
  288.             'page_no' => $page_no,
  289.             'page_count' => $page_count,
  290.             'has_errors' => false,
  291.             'OrderStatuses' => $this->orderStatusRepository->findBy([], ['sort_no' => 'ASC']),
  292.         ];
  293.     }
  294.     /**
  295.      * @Route("/%eccube_admin_route%/order/bulk_delete", name="admin_order_bulk_delete", methods={"POST"})
  296.      */
  297.     public function bulkDelete(Request $request)
  298.     {
  299.         $this->isTokenValid();
  300.         $ids $request->get('ids');
  301.         foreach ($ids as $order_id) {
  302.             $Order $this->orderRepository
  303.                 ->find($order_id);
  304.             if ($Order) {
  305.                 $this->entityManager->remove($Order);
  306.                 log_info('受注削除', [$Order->getId()]);
  307.             }
  308.         }
  309.         $this->entityManager->flush();
  310.         $this->addSuccess('admin.common.delete_complete''admin');
  311.         return $this->redirect($this->generateUrl('admin_order', ['resume' => Constant::ENABLED]));
  312.     }
  313.     /**
  314.      * 受注CSVの出力.
  315.      *
  316.      * @Route("/%eccube_admin_route%/order/export/order", name="admin_order_export_order", methods={"GET"})
  317.      *
  318.      * @param Request $request
  319.      *
  320.      * @return StreamedResponse
  321.      */
  322.     public function exportOrder(Request $request)
  323.     {
  324.         $filename 'order_'.(new \DateTime())->format('YmdHis').'.csv';
  325.         $response $this->exportCsv($requestCsvType::CSV_TYPE_ORDER$filename);
  326.         log_info('受注CSV出力ファイル名', [$filename]);
  327.         return $response;
  328.     }
  329.     /**
  330.      * 配送CSVの出力.
  331.      *
  332.      * @Route("/%eccube_admin_route%/order/export/shipping", name="admin_order_export_shipping", methods={"GET"})
  333.      *
  334.      * @param Request $request
  335.      *
  336.      * @return StreamedResponse
  337.      */
  338.     public function exportShipping(Request $request)
  339.     {
  340.         $filename 'shipping_'.(new \DateTime())->format('YmdHis').'.csv';
  341.         $response $this->exportCsv($requestCsvType::CSV_TYPE_SHIPPING$filename);
  342.         log_info('配送CSV出力ファイル名', [$filename]);
  343.         return $response;
  344.     }
  345.     /**
  346.      * @param Request $request
  347.      * @param $csvTypeId
  348.      * @param string $fileName
  349.      *
  350.      * @return StreamedResponse
  351.      */
  352.     protected function exportCsv(Request $request$csvTypeId$fileName)
  353.     {
  354.         // タイムアウトを無効にする.
  355.         set_time_limit(0);
  356.         // sql loggerを無効にする.
  357.         $em $this->entityManager;
  358.         $em->getConfiguration()->setSQLLogger(null);
  359.         $response = new StreamedResponse();
  360.         $response->setCallback(function () use ($request$csvTypeId) {
  361.             // CSV種別を元に初期化.
  362.             $this->csvExportService->initCsvType($csvTypeId);
  363.             // ヘッダ行の出力.
  364.             $this->csvExportService->exportHeader();
  365.             // 受注データ検索用のクエリビルダを取得.
  366.             $qb $this->csvExportService
  367.                 ->getOrderQueryBuilder($request);
  368.             // データ行の出力.
  369.             $this->csvExportService->setExportQueryBuilder($qb);
  370.             $this->csvExportService->exportData(function ($entity$csvService) use ($request) {
  371.                 $Csvs $csvService->getCsvs();
  372.                 $Order $entity;
  373.                 $OrderItems $Order->getOrderItems();
  374.                 foreach ($OrderItems as $OrderItem) {
  375.                     $ExportCsvRow = new ExportCsvRow();
  376.                     // CSV出力項目と合致するデータを取得.
  377.                     foreach ($Csvs as $Csv) {
  378.                         // 受注データを検索.
  379.                         $ExportCsvRow->setData($csvService->getData($Csv$Order));
  380.                         if ($ExportCsvRow->isDataNull()) {
  381.                             // 受注データにない場合は, 受注明細を検索.
  382.                             $ExportCsvRow->setData($csvService->getData($Csv$OrderItem));
  383.                         }
  384.                         if ($ExportCsvRow->isDataNull() && $Shipping $OrderItem->getShipping()) {
  385.                             // 受注明細データにない場合は, 出荷を検索.
  386.                             $ExportCsvRow->setData($csvService->getData($Csv$Shipping));
  387.                         }
  388.                         $event = new EventArgs(
  389.                             [
  390.                                 'csvService' => $csvService,
  391.                                 'Csv' => $Csv,
  392.                                 'OrderItem' => $OrderItem,
  393.                                 'ExportCsvRow' => $ExportCsvRow,
  394.                             ],
  395.                             $request
  396.                         );
  397.                         $this->eventDispatcher->dispatch($eventEccubeEvents::ADMIN_ORDER_CSV_EXPORT_ORDER);
  398.                         $ExportCsvRow->pushData();
  399.                     }
  400.                     // $row[] = number_format(memory_get_usage(true));
  401.                     // 出力.
  402.                     $csvService->fputcsv($ExportCsvRow->getRow());
  403.                 }
  404.             });
  405.         });
  406.         $response->headers->set('Content-Type''application/octet-stream');
  407.         $response->headers->set('Content-Disposition''attachment; filename='.$fileName);
  408.         return $response;
  409.     }
  410.     /**
  411.      * Update to order status
  412.      *
  413.      * @Route("/%eccube_admin_route%/shipping/{id}/order_status", requirements={"id" = "\d+"}, name="admin_shipping_update_order_status", methods={"PUT"})
  414.      *
  415.      * @param Request $request
  416.      * @param Shipping $Shipping
  417.      *
  418.      * @return \Symfony\Component\HttpFoundation\JsonResponse
  419.      */
  420.     public function updateOrderStatus(Request $requestShipping $Shipping)
  421.     {
  422.         if (!($request->isXmlHttpRequest() && $this->isTokenValid())) {
  423.             return $this->json(['status' => 'NG'], 400);
  424.         }
  425.         $Order $Shipping->getOrder();
  426.         $OrderStatus $this->entityManager->find(OrderStatus::class, $request->get('order_status'));
  427.         if (!$OrderStatus) {
  428.             return $this->json(['status' => 'NG'], 400);
  429.         }
  430.         $result = [];
  431.         try {
  432.             if ($Order->getOrderStatus()->getId() == $OrderStatus->getId()) {
  433.                 log_info('対応状況一括変更スキップ');
  434.                 $result = ['message' => trans('admin.order.skip_change_status', ['%name%' => $Shipping->getId()])];
  435.             } else {
  436.                 if ($this->orderStateMachine->can($Order$OrderStatus)) {
  437.                     if ($OrderStatus->getId() == OrderStatus::DELIVERED) {
  438.                         if (!$Shipping->isShipped()) {
  439.                             $Shipping->setShippingDate(new \DateTime());
  440.                         }
  441.                         $allShipped true;
  442.                         foreach ($Order->getShippings() as $Ship) {
  443.                             if (!$Ship->isShipped()) {
  444.                                 $allShipped false;
  445.                                 break;
  446.                             }
  447.                         }
  448.                         if ($allShipped) {
  449.                             $this->orderStateMachine->apply($Order$OrderStatus);
  450.                         }
  451.                     } else {
  452.                         $this->orderStateMachine->apply($Order$OrderStatus);
  453.                     }
  454.                     if ($request->get('notificationMail')) { // for SimpleStatusUpdate
  455.                         $this->mailService->sendShippingNotifyMail($Shipping);
  456.                         $Shipping->setMailSendDate(new \DateTime());
  457.                         $result['mail'] = true;
  458.                     } else {
  459.                         $result['mail'] = false;
  460.                     }
  461.                     // 対応中・キャンセルの更新時は商品在庫を増減させているので商品情報を更新
  462.                     if ($OrderStatus->getId() == OrderStatus::IN_PROGRESS || $OrderStatus->getId() == OrderStatus::CANCEL) {
  463.                         foreach ($Order->getOrderItems() as $OrderItem) {
  464.                             $ProductClass $OrderItem->getProductClass();
  465.                             if ($OrderItem->isProduct() && !$ProductClass->isStockUnlimited()) {
  466.                                 $this->entityManager->persist($ProductClass);
  467.                                 $this->entityManager->flush();
  468.                                 $ProductStock $this->productStockRepository->findOneBy(['ProductClass' => $ProductClass]);
  469.                                 $this->entityManager->persist($ProductStock);
  470.                                 $this->entityManager->flush();
  471.                             }
  472.                         }
  473.                     }
  474.                     $this->entityManager->persist($Order);
  475.                     $this->entityManager->persist($Shipping);
  476.                     $this->entityManager->flush();
  477.                     // 会員の場合、購入回数、購入金額などを更新
  478.                     if ($Customer $Order->getCustomer()) {
  479.                         $this->orderRepository->updateOrderSummary($Customer);
  480.                         $this->entityManager->persist($Customer);
  481.                         $this->entityManager->flush();
  482.                     }
  483.                 } else {
  484.                     $from $Order->getOrderStatus()->getName();
  485.                     $to $OrderStatus->getName();
  486.                     $result = ['message' => trans('admin.order.failed_to_change_status', [
  487.                         '%name%' => $Shipping->getId(),
  488.                         '%from%' => $from,
  489.                         '%to%' => $to,
  490.                     ])];
  491.                 }
  492.                 log_info('対応状況一括変更処理完了', [$Order->getId()]);
  493.             }
  494.         } catch (\Exception $e) {
  495.             log_error('予期しないエラーです', [$e->getMessage()]);
  496.             return $this->json(['status' => 'NG'], 500);
  497.         }
  498.         return $this->json(array_merge(['status' => 'OK'], $result));
  499.     }
  500.     /**
  501.      * Update to Tracking number.
  502.      *
  503.      * @Route("/%eccube_admin_route%/shipping/{id}/tracking_number", requirements={"id" = "\d+"}, name="admin_shipping_update_tracking_number", methods={"PUT"})
  504.      *
  505.      * @param Request $request
  506.      * @param Shipping $shipping
  507.      *
  508.      * @return Response
  509.      */
  510.     public function updateTrackingNumber(Request $requestShipping $shipping)
  511.     {
  512.         if (!($request->isXmlHttpRequest() && $this->isTokenValid())) {
  513.             return $this->json(['status' => 'NG'], 400);
  514.         }
  515.         $trackingNumber mb_convert_kana($request->get('tracking_number'), 'a''utf-8');
  516.         /** @var \Symfony\Component\Validator\ConstraintViolationListInterface $errors */
  517.         $errors $this->validator->validate(
  518.             $trackingNumber,
  519.             [
  520.                 new Assert\Length(['max' => $this->eccubeConfig['eccube_stext_len']]),
  521.                 new Assert\Regex(
  522.                     ['pattern' => '/^[0-9a-zA-Z-]+$/u''message' => trans('admin.order.tracking_number_error')]
  523.                 ),
  524.             ]
  525.         );
  526.         if ($errors->count() != 0) {
  527.             log_info('送り状番号入力チェックエラー');
  528.             $messages = [];
  529.             /** @var \Symfony\Component\Validator\ConstraintViolationInterface $error */
  530.             foreach ($errors as $error) {
  531.                 $messages[] = $error->getMessage();
  532.             }
  533.             return $this->json(['status' => 'NG''messages' => $messages], 400);
  534.         }
  535.         try {
  536.             $shipping->setTrackingNumber($trackingNumber);
  537.             $this->entityManager->persist($shipping);
  538.             $this->entityManager->flush();
  539.             log_info('送り状番号変更処理完了', [$shipping->getId()]);
  540.             $message = ['status' => 'OK''shipping_id' => $shipping->getId(), 'tracking_number' => $trackingNumber];
  541.             return $this->json($message);
  542.         } catch (\Exception $e) {
  543.             log_error('予期しないエラー', [$e->getMessage()]);
  544.             return $this->json(['status' => 'NG'], 500);
  545.         }
  546.     }
  547.     /**
  548.      * @Route("/%eccube_admin_route%/order/export/pdf", name="admin_order_export_pdf", methods={"GET", "POST"})
  549.      * @Template("@admin/Order/order_pdf.twig")
  550.      *
  551.      * @param Request $request
  552.      *
  553.      * @return array|RedirectResponse
  554.      */
  555.     public function exportPdf(Request $request)
  556.     {
  557.         // requestから出荷番号IDの一覧を取得する.
  558.         $ids $request->get('ids', []);
  559.         if (count($ids) == 0) {
  560.             $this->addError('admin.order.delivery_note_parameter_error''admin');
  561.             log_info('The Order cannot found!');
  562.             return $this->redirectToRoute('admin_order');
  563.         }
  564.         /** @var OrderPdf $OrderPdf */
  565.         $OrderPdf $this->orderPdfRepository->find($this->getUser());
  566.         if (!$OrderPdf) {
  567.             $OrderPdf = new OrderPdf();
  568.             $OrderPdf
  569.                 ->setTitle(trans('admin.order.delivery_note_title__default'))
  570.                 ->setMessage1(trans('admin.order.delivery_note_message__default1'))
  571.                 ->setMessage2(trans('admin.order.delivery_note_message__default2'))
  572.                 ->setMessage3(trans('admin.order.delivery_note_message__default3'));
  573.         }
  574.         /**
  575.          * @var FormBuilder
  576.          */
  577.         $builder $this->formFactory->createBuilder(OrderPdfType::class, $OrderPdf);
  578.         /* @var \Symfony\Component\Form\Form $form */
  579.         $form $builder->getForm();
  580.         // Formへの設定
  581.         $form->get('ids')->setData(implode(','$ids));
  582.         return [
  583.             'form' => $form->createView(),
  584.         ];
  585.     }
  586.     /**
  587.      * @Route("/%eccube_admin_route%/order/export/pdf/download", name="admin_order_pdf_download", methods={"POST"})
  588.      * @Template("@admin/Order/order_pdf.twig")
  589.      *
  590.      * @param Request $request
  591.      *
  592.      * @return Response
  593.      */
  594.     public function exportPdfDownload(Request $requestOrderPdfService $orderPdfService)
  595.     {
  596.         /**
  597.          * @var FormBuilder
  598.          */
  599.         $builder $this->formFactory->createBuilder(OrderPdfType::class);
  600.         /* @var \Symfony\Component\Form\Form $form */
  601.         $form $builder->getForm();
  602.         $form->handleRequest($request);
  603.         // Validation
  604.         if (!$form->isValid()) {
  605.             log_info('The parameter is invalid!');
  606.             return $this->render('@admin/Order/order_pdf.twig', [
  607.                 'form' => $form->createView(),
  608.             ]);
  609.         }
  610.         $arrData $form->getData();
  611.         // 購入情報からPDFを作成する
  612.         $status $orderPdfService->makePdf($arrData);
  613.         // 異常終了した場合の処理
  614.         if (!$status) {
  615.             $this->addError('admin.order.export.pdf.download.failure''admin');
  616.             log_info('Unable to create pdf files! Process have problems!');
  617.             return $this->render('@admin/Order/order_pdf.twig', [
  618.                 'form' => $form->createView(),
  619.             ]);
  620.         }
  621.         // TCPDF::Outputを実行するとプロパティが初期化されるため、ファイル名を事前に取得しておく
  622.         $pdfFileName $orderPdfService->getPdfFileName();
  623.         // ダウンロードする
  624.         $response = new Response(
  625.             $orderPdfService->outputPdf(),
  626.             200,
  627.             ['content-type' => 'application/pdf']
  628.         );
  629.         $downloadKind $form->get('download_kind')->getData();
  630.         // レスポンスヘッダーにContent-Dispositionをセットし、ファイル名を指定
  631.         if ($downloadKind == 1) {
  632.             $response->headers->set('Content-Disposition''attachment; filename="'.$pdfFileName.'"');
  633.         } else {
  634.             $response->headers->set('Content-Disposition''inline; filename="'.$pdfFileName.'"');
  635.         }
  636.         log_info('OrderPdf download success!', ['Order ID' => implode(','$request->get('ids', []))]);
  637.         $isDefault = isset($arrData['default']) ? $arrData['default'] : false;
  638.         if ($isDefault) {
  639.             // Save input to DB
  640.             $arrData['admin'] = $this->getUser();
  641.             $this->orderPdfRepository->save($arrData);
  642.         }
  643.         return $response;
  644.     }
  645. }