app/Customize/Controller/Admin/Order/OrderController.php line 219

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