src/Eccube/Service/OrderPdfService.php line 206

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\Service;
  13. use Eccube\Common\EccubeConfig;
  14. use Eccube\Entity\BaseInfo;
  15. use Eccube\Entity\OrderItem;
  16. use Eccube\Entity\Shipping;
  17. use Eccube\Repository\BaseInfoRepository;
  18. use Eccube\Repository\OrderPdfRepository;
  19. use Eccube\Repository\OrderRepository;
  20. use Eccube\Repository\ShippingRepository;
  21. use Eccube\Twig\Extension\EccubeExtension;
  22. use Eccube\Twig\Extension\TaxExtension;
  23. use setasign\Fpdi\Tcpdf\Fpdi;
  24. /**
  25.  * Class OrderPdfService.
  26.  * Do export pdf function.
  27.  */
  28. class OrderPdfService extends Fpdi
  29. {
  30.     /** @var OrderRepository */
  31.     protected $orderRepository;
  32.     /** @var ShippingRepository */
  33.     protected $shippingRepository;
  34.     /** @var OrderPdfRepository */
  35.     protected $orderPdfRepository;
  36.     /** @var TaxRuleService */
  37.     protected $taxRuleService;
  38.     /**
  39.      * @var EccubeConfig
  40.      */
  41.     protected $eccubeConfig;
  42.     /**
  43.      * @var EccubeExtension
  44.      */
  45.     protected $eccubeExtension;
  46.     /**
  47.      * @var TaxExtension
  48.      */
  49.     protected $taxExtension;
  50.     // ====================================
  51.     // 定数宣言
  52.     // ====================================
  53.     /** ダウンロードするPDFファイルのデフォルト名 */
  54.     public const DEFAULT_PDF_FILE_NAME 'nouhinsyo.pdf';
  55.     /** FONT ゴシック */
  56.     public const FONT_GOTHIC 'kozgopromedium';
  57.     /** FONT 明朝 */
  58.     public const FONT_SJIS 'kozminproregular';
  59.     // ====================================
  60.     // 変数宣言
  61.     // ====================================
  62.     /** @var BaseInfo */
  63.     public $baseInfoRepository;
  64.     /** 購入詳細情報 ラベル配列
  65.      * @var array
  66.      */
  67.     protected $labelCell = [];
  68.     /*** 購入詳細情報 幅サイズ配列
  69.      * @var array
  70.      */
  71.     protected $widthCell = [];
  72.     /** 最後に処理した注文番号 @var string */
  73.     protected $lastOrderId null;
  74.     // --------------------------------------
  75.     // Font情報のバックアップデータ
  76.     /** @var string フォント名 */
  77.     protected $bakFontFamily;
  78.     /** @var string フォントスタイル */
  79.     protected $bakFontStyle;
  80.     /** @var string フォントサイズ */
  81.     protected $bakFontSize;
  82.     // --------------------------------------
  83.     // lfTextのoffset
  84.     protected $baseOffsetX 0;
  85.     protected $baseOffsetY = -4;
  86.     /** ダウンロードファイル名 @var string */
  87.     protected $downloadFileName null;
  88.     /** 発行日 @var string */
  89.     protected $issueDate '';
  90.     /**
  91.      * OrderPdfService constructor.
  92.      *
  93.      * @param EccubeConfig $eccubeConfig
  94.      * @param OrderRepository $orderRepository
  95.      * @param ShippingRepository $shippingRepository
  96.      * @param TaxRuleService $taxRuleService
  97.      * @param BaseInfoRepository $baseInfoRepository
  98.      * @param EccubeExtension $eccubeExtension
  99.      * @param TaxExtension $taxExtension
  100.      *
  101.      * @throws \Exception
  102.      */
  103.     public function __construct(EccubeConfig $eccubeConfigOrderRepository $orderRepositoryShippingRepository $shippingRepositoryTaxRuleService $taxRuleServiceBaseInfoRepository $baseInfoRepositoryEccubeExtension $eccubeExtensionTaxExtension $taxExtension)
  104.     {
  105.         $this->eccubeConfig $eccubeConfig;
  106.         $this->baseInfoRepository $baseInfoRepository->get();
  107.         $this->orderRepository $orderRepository;
  108.         $this->shippingRepository $shippingRepository;
  109.         $this->taxRuleService $taxRuleService;
  110.         $this->eccubeExtension $eccubeExtension;
  111.         $this->taxExtension $taxExtension;
  112.         parent::__construct();
  113.         // 購入詳細情報の設定を行う
  114.         // 動的に入れ替えることはない
  115.         $this->labelCell[] = '商品名 / 商品コード';
  116.         $this->labelCell[] = '数量';
  117.         $this->labelCell[] = '単価(税込)';
  118.         $this->labelCell[] = '金額(税込)';
  119.         $this->widthCell = [110.31221.724.5];
  120.         // Fontの設定しておかないと文字化けを起こす
  121.         $this->SetFont(self::FONT_SJIS);
  122.         // PDFの余白(上左右)を設定
  123.         $this->SetMargins(1520);
  124.         // ヘッダーの出力を無効化
  125.         $this->setPrintHeader(false);
  126.         // フッターの出力を無効化
  127.         $this->setPrintFooter(true);
  128.         $this->setFooterMargin();
  129.         $this->setFooterFont([self::FONT_SJIS''8]);
  130.     }
  131.     /**
  132.      * 注文情報からPDFファイルを作成する.
  133.      *
  134.      * @param array $formData
  135.      *                        [KEY]
  136.      *                        ids: 注文番号
  137.      *                        issue_date: 発行日
  138.      *                        title: タイトル
  139.      *                        message1: メッセージ1行目
  140.      *                        message2: メッセージ2行目
  141.      *                        message3: メッセージ3行目
  142.      *                        note1: 備考1行目
  143.      *                        note2: 備考2行目
  144.      *                        note3: 備考3行目
  145.      *
  146.      * @return bool
  147.      */
  148.     public function makePdf(array $formData)
  149.     {
  150.         // 発行日の設定
  151.         $this->issueDate '作成日: '.$formData['issue_date']->format('Y年m月d日');
  152.         // ダウンロードファイル名の初期化
  153.         $this->downloadFileName null;
  154.         // データが空であれば終了
  155.         if (!$formData['ids']) {
  156.             return false;
  157.         }
  158.         // 出荷番号をStringからarrayに変換
  159.         $ids explode(','$formData['ids']);
  160.         foreach ($ids as $id) {
  161.             $this->lastOrderId $id;
  162.             // 出荷番号から出荷情報を取得する
  163.             /** @var Shipping $Shipping */
  164.             $Shipping $this->shippingRepository->find($id);
  165.             if (!$Shipping) {
  166.                 // 出荷情報の取得ができなかった場合
  167.                 continue;
  168.             }
  169.             // テンプレートファイルを読み込む
  170.             $Order $Shipping->getOrder();
  171.             if ($Order->isMultiple()) {
  172.                 // 複数配送の時は読み込むテンプレートファイルを変更する
  173.                 $userPath $this->eccubeConfig->get('eccube_html_admin_dir').'/assets/pdf/nouhinsyo_multiple.pdf';
  174.             } else {
  175.                 $userPath $this->eccubeConfig->get('eccube_html_admin_dir').'/assets/pdf/nouhinsyo.pdf';
  176.             }
  177.             $this->setSourceFile($userPath);
  178.             // PDFにページを追加する
  179.             $this->addPdfPage();
  180.             // タイトルを描画する
  181.             $this->renderTitle($formData['title']);
  182.             // 店舗情報を描画する
  183.             $this->renderShopData();
  184.             // 注文情報を描画する
  185.             $this->renderOrderData($Shipping);
  186.             // メッセージを描画する
  187.             $this->renderMessageData($formData);
  188.             // 出荷詳細情報を描画する
  189.             $this->renderOrderDetailData($Shipping);
  190.             // 備考を描画する
  191.             $this->renderEtcData($formData);
  192.         }
  193.         return true;
  194.     }
  195.     /**
  196.      * PDFファイルを出力する.
  197.      *
  198.      * @return string|mixed
  199.      */
  200.     public function outputPdf()
  201.     {
  202.         return $this->Output($this->getPdfFileName(), 'S');
  203.     }
  204.     /**
  205.      * PDFファイル名を取得する
  206.      * PDFが1枚の時は注文番号をファイル名につける.
  207.      *
  208.      * @return string ファイル名
  209.      */
  210.     public function getPdfFileName()
  211.     {
  212.         if (!is_null($this->downloadFileName)) {
  213.             return $this->downloadFileName;
  214.         }
  215.         $this->downloadFileName self::DEFAULT_PDF_FILE_NAME;
  216.         if ($this->PageNo() == 1) {
  217.             $this->downloadFileName 'nouhinsyo-No'.$this->lastOrderId.'.pdf';
  218.         }
  219.         return $this->downloadFileName;
  220.     }
  221.     /**
  222.      * フッターに発行日を出力する.
  223.      */
  224.     public function Footer()
  225.     {
  226.         $this->Cell(00$this->issueDate00'R');
  227.     }
  228.     /**
  229.      * 作成するPDFのテンプレートファイルを指定する.
  230.      */
  231.     protected function addPdfPage()
  232.     {
  233.         // ページを追加
  234.         $this->AddPage();
  235.         // テンプレートに使うテンプレートファイルのページ番号を取得
  236.         $tplIdx $this->importPage(1);
  237.         // テンプレートに使うテンプレートファイルのページ番号を指定
  238.         $this->useTemplate($tplIdxnullnullnullnulltrue);
  239.         $this->setPageMark();
  240.     }
  241.     /**
  242.      * PDFに店舗情報を設定する
  243.      * ショップ名、ロゴ画像以外はdtb_helpに登録されたデータを使用する.
  244.      */
  245.     protected function renderShopData()
  246.     {
  247.         // 基準座標を設定する
  248.         $this->setBasePosition();
  249.         // ショップ名
  250.         // 会社名で固定 upd 20240404
  251.         // $this->lfText(125, 58, $this->baseInfoRepository->getShopName(), 8, 'B');
  252.         $this->lfText(12563,'株式会社 杏樹',10'B');
  253.         //郵便番号 ※非表示
  254.         // $this->lfText(121, 63, "\u{3012}". ' ' . mb_substr($this->baseInfoRepository->getPostalCode(), 0, 3) . ' - ' . mb_substr($this->baseInfoRepository->getPostalCode(), 3, 4), 8);
  255.         // 都道府県+所在地
  256.         $text $this->baseInfoRepository->getPref().$this->baseInfoRepository->getAddr01();
  257.         $this->lfText(12569$text8);
  258.         // $this->lfText(125, 69, $this->baseInfoRepository->getAddr02(), 8);  ※2行目非表示
  259.         // 電話番号
  260.         $text 'TEL: '.$this->baseInfoRepository->getPhoneNumber();
  261.         $this->lfText(12573$text8); // TEL・FAX
  262.         // メールアドレス
  263.         if (strlen($this->baseInfoRepository->getEmail01()) > 0) {
  264.             $text 'Email: '.$this->baseInfoRepository->getEmail01();
  265.             $this->lfText(12577$text8); // Email
  266.         }
  267.         // インボイス登録番号
  268.         if (!empty($this->baseInfoRepository->getInvoiceRegistrationNumber())) {
  269.             $text '登録番号: '.$this->baseInfoRepository->getInvoiceRegistrationNumber();
  270.             $this->lfText(12581$text8);
  271.         }
  272.         // user_dataにlogo.pngが配置されている場合は優先的に読み込む
  273.         $logoFile $this->eccubeConfig->get('eccube_html_dir').'/user_data/assets/pdf/logo.png';
  274.         if (!file_exists($logoFile)) {
  275.             $logoFile $this->eccubeConfig->get('eccube_html_admin_dir').'/assets/pdf/logo.png';
  276.         }
  277.         /** original $this->Image($logoFile, 124, 46, 40); */
  278.         $this->Image($logoFile1223950);
  279.     }
  280.     /**
  281.      * メッセージを設定する.
  282.      *
  283.      * @param array $formData
  284.      */
  285.     protected function renderMessageData(array $formData)
  286.     {
  287.         $this->lfText(2770$formData['message1'], 8); // メッセージ1
  288.         $this->lfText(2774$formData['message2'], 8); // メッセージ2
  289.         $this->lfText(2778$formData['message3'], 8); // メッセージ3
  290.     }
  291.     /**
  292.      * PDFに備考を設定数.
  293.      *
  294.      * @param array $formData
  295.      */
  296.     protected function renderEtcData(array $formData)
  297.     {
  298.         // フォント情報のバックアップ
  299.         $this->backupFont();
  300.         $this->Cell(010''01'C'0'');
  301.         // 行頭近くの場合、表示崩れがあるためもう一個字下げする
  302.         if (270 <= $this->GetY()) {
  303.             $this->Cell(010''01'C'0'');
  304.         }
  305.         $this->SetFont(self::FONT_GOTHIC'B'9);
  306.         $this->MultiCell(06'< 備考 >''T'2'L'0'');
  307.         $this->SetFont(self::FONT_SJIS''8);
  308.         $this->Ln();
  309.         // rtrimを行う
  310.         $text preg_replace('/\s+$/us'''$formData['note1']."\n".$formData['note2']."\n".$formData['note3']);
  311.         $this->MultiCell(04$text''2'L'0'');
  312.         // フォント情報の復元
  313.         $this->restoreFont();
  314.     }
  315.     /**
  316.      * タイトルをPDFに描画する.
  317.      *
  318.      * @param string $title
  319.      */
  320.     protected function renderTitle($title)
  321.     {
  322.         // 基準座標を設定する
  323.         $this->setBasePosition();
  324.         // フォント情報のバックアップ
  325.         $this->backupFont();
  326.         // 文書タイトル(納品書・請求書)
  327.         $this->SetFont(self::FONT_GOTHIC''15);
  328.         $this->Cell(010$title02'C'0'');
  329.         $this->Cell(066''02'R'0'');
  330.         $this->Cell(50''00'R'0'');
  331.         // フォント情報の復元
  332.         $this->restoreFont();
  333.     }
  334.     /**
  335.      * 購入者情報を設定する.
  336.      *
  337.      * @param Shipping $Shipping
  338.      */
  339.     protected function renderOrderData(Shipping $Shipping)
  340.     {
  341.         // 基準座標を設定する
  342.         $this->setBasePosition();
  343.         // フォント情報のバックアップ
  344.         $this->backupFont();
  345.         // =========================================
  346.         // 購入者情報部
  347.         // =========================================
  348.         $Order $Shipping->getOrder();
  349.         // 購入者郵便番号(3012は郵便マークのUTFコード)
  350.         $text "\u{3012}" ' ' mb_substr($Shipping->getPostalCode(), 03) . ' - ' mb_substr($Shipping->getPostalCode(), 34);
  351.         $this->lfText(2243$text10);
  352.         // 購入者都道府県+住所1
  353.         // $text = $Order->getPref().$Order->getAddr01();
  354.         $text $Shipping->getPref().$Shipping->getAddr01();
  355.         $this->lfText(2747$text10);
  356.         $this->lfText(2751$Shipping->getAddr02(), 10); // 購入者住所2
  357.         // upd 20240409 購入者名の宛名制御を追加
  358.         // 購入者氏名
  359.         // upd 2024/04/03 
  360.         // if (null !== $Shipping->getCompanyName()) {
  361.         //     // 会社名
  362.         //     $text = $Shipping->getCompanyName();
  363.         //     $this->lfText(27, 57, $text, 11);
  364.         //     // 氏名
  365.         //     $text = $Shipping->getName01().' '.$Shipping->getName02().' 様';
  366.         //     $this->lfText(27, 63, $text, 11);
  367.         // } else {
  368.         //     $text = $Shipping->getName01().' '.$Shipping->getName02().' 様';
  369.         //     $this->lfText(27, 59, $text, 11);
  370.         // }
  371.         // $text = $Order->getPref().$Order->getAddr01();
  372.         $selSex $Shipping->getOrder()->getCustomer()->getSex();
  373.         if ($selSex == '店舗') {
  374.             if (null !== $Shipping->getCompanyName()) {
  375.                 // 会社名
  376.                 $text $Shipping->getCompanyName() . ' 御中';
  377.                 $this->lfText(2757$text11);
  378.             } else {
  379.                 // 氏名
  380.                 $text $Shipping->getName01().' '.$Shipping->getName02().' 御中';
  381.                 $this->lfText(2759$text11);
  382.             }
  383.         } else {
  384.             if (null !== $Shipping->getCompanyName()) {
  385.                 // 会社名
  386.                 $text $Shipping->getCompanyName();
  387.                 $this->lfText(2757$text11);
  388.                 // 氏名
  389.                 $text $Shipping->getName01().' '.$Shipping->getName02().' 様';
  390.                 $this->lfText(2763$text11);
  391.             } else {
  392.                 $text $Shipping->getName01().' '.$Shipping->getName02().' 様';
  393.                 $this->lfText(2759$text11);
  394.             }
  395.         }
  396.         // →ここまで
  397.         // =========================================
  398.         // お買い上げ明細部
  399.         // =========================================
  400.         $this->SetFont(self::FONT_SJIS''10);
  401.         // ご注文日
  402.         $orderDate $Order->getCreateDate()->format('Y/m/d H:i');
  403.         if ($Order->getOrderDate()) {
  404.             $orderDate $Order->getOrderDate()->format('Y/m/d H:i');
  405.         }
  406.         $this->lfText(25125$orderDate10);
  407.         // 注文番号
  408.         $this->lfText(25135$Order->getOrderNo(), 10);
  409.         // 総合計金額
  410.         if (!$Order->isMultiple()) {
  411.             $this->SetFont(self::FONT_SJIS'B'15);
  412.             $paymentTotalText $this->eccubeExtension->getPriceFilter($Order->getPaymentTotal());
  413.             $this->setBasePosition(12095.5);
  414.             $this->Cell(57''00''0'');
  415.             $this->Cell(678$paymentTotalText02'R'0'');
  416.             $this->Cell(045''02''0'');
  417.         }
  418.         // フォント情報の復元
  419.         $this->restoreFont();
  420.     }
  421.     /**
  422.      * 購入商品詳細情報を設定する.
  423.      *
  424.      * @param Shipping $Shipping
  425.      */
  426.     protected function renderOrderDetailData(Shipping $Shipping)
  427.     {
  428.         $arrOrder = [];
  429.         // テーブルの微調整を行うための購入商品詳細情報をarrayに変換する
  430.         // =========================================
  431.         // 受注詳細情報
  432.         // =========================================
  433.         $i 0;
  434.         $meisai_gokei=0;
  435.         $isShowReducedTaxMess false;
  436.         $Order $Shipping->getOrder();
  437.         /* @var OrderItem $OrderItem */
  438.         foreach ($Shipping->getOrderItems() as $OrderItem) {
  439.             if (!$Order->isMultiple() && !$OrderItem->isProduct()) {
  440.                 continue;
  441.             }
  442.             // class categoryの生成
  443.             $classCategory '';
  444.             /** @var OrderItem $OrderItem */
  445.             if ($OrderItem->getClassCategoryName1()) {
  446.                 $classCategory .= ' [ '.$OrderItem->getClassCategoryName1();
  447.                 if ($OrderItem->getClassCategoryName2() == '') {
  448.                     $classCategory .= ' ]';
  449.                 } else {
  450.                     $classCategory .= ' * '.$OrderItem->getClassCategoryName2().' ]';
  451.                 }
  452.             }
  453.             // product
  454.             $productName $OrderItem->getProductName();
  455.             if (null !== $OrderItem->getProductCode()) {
  456.                 $productName .= ' / '.$OrderItem->getProductCode();
  457.             }
  458.             if ($classCategory) {
  459.                 $productName .= ' / '.$classCategory;
  460.             }
  461.             if ($this->taxExtension->isReducedTaxRate($OrderItem)) {
  462.                 $productName .= ' ※';
  463.                 $isShowReducedTaxMess true;
  464.             }
  465.             $arrOrder[$i][0] = $productName;
  466.             // 購入数量
  467.             $arrOrder[$i][1] = number_format($OrderItem->getQuantity());
  468.             // upd 20240409 協議の結果、すべて内税に変更
  469.             // 税込金額(単価)
  470.             // $arrOrder[$i][2] = $this->eccubeExtension->getPriceFilter($OrderItem->getPrice());
  471.             $arrOrder[$i][2] = $this->eccubeExtension->getPriceFilter($OrderItem->getPriceIncTax());
  472.             // 小計(商品毎) UPD -20240403-
  473.             // 購入数量 × 単価 ※明細金額を税抜き表示に変更
  474.             $arrOrder[$i][3] = $this->eccubeExtension->getPriceFilter($OrderItem->getTotalPrice());
  475.             // $arrOrder[$i][3] = $this->eccubeExtension->getPriceFilter($OrderItem->getQuantity() * $OrderItem->getPrice());
  476.             $meisai_gokei += $OrderItem->getQuantity() * $OrderItem->getPrice();
  477.             // ここまで UPD -20240403-
  478.             ++$i;
  479.         }
  480.         if (!$Order->isMultiple()) {
  481.             // =========================================
  482.             // 小計
  483.             // =========================================
  484.             $arrOrder[$i][0] = '';
  485.             $arrOrder[$i][1] = '';
  486.             $arrOrder[$i][2] = '';
  487.             $arrOrder[$i][3] = '';
  488.             ++$i;
  489.             $arrOrder[$i][0] = '';
  490.             $arrOrder[$i][1] = '';
  491.             $arrOrder[$i][2] = '';
  492.             $arrOrder[$i][3] = '';
  493.             ++$i;
  494.             $arrOrder[$i][0] = '';
  495.             $arrOrder[$i][1] = '';
  496.             $arrOrder[$i][2] = '商品合計  ';
  497.             // ==obl_21/01/13 upd 2024/04/03 商品合計の積み上げに変更 =============================
  498.             $arrOrder[$i][3] = $this->eccubeExtension->getPriceFilter($Order->getSubtotal());
  499.             // DEL      $arrOrder[$i][3] = $this->eccubeExtension->getPriceFilter($meisai_gokei);
  500.             // ==obl_21/01/13 upd end ================================
  501.  
  502.             // ==obl_21/01/13 送料は出力しない ================================
  503.             // DEL      ++$i;
  504.             // DEL      $arrOrder[$i][0] = '';
  505.             // DEL      $arrOrder[$i][1] = '';
  506.             // DEL      $arrOrder[$i][2] = '送料';
  507.             // DEL      $arrOrder[$i][3] = $this->eccubeExtension->getPriceFilter($Order->getDeliveryFeeTotal());
  508.             // ==obl_21/01/13 end ================================
  509.             // ==obl_21/01/13 手数料は出力しない ================================
  510.             // ++$i;
  511.             // $arrOrder[$i][0] = '';
  512.             // $arrOrder[$i][1] = '';
  513.             // $arrOrder[$i][2] = '手数料';
  514.             // $arrOrder[$i][3] = $this->eccubeExtension->getPriceFilter($Order->getCharge());
  515.             // ==obl_21/01/13 end ================================
  516.             // ==obl_24/04/03 値引きは出力しない ================================
  517.             // DEL      ++$i;
  518.             // DEL      $arrOrder[$i][0] = '';
  519.             // DEL      $arrOrder[$i][1] = '';
  520.             // DEL      $arrOrder[$i][2] = '値引き';
  521.             // DEL      $arrOrder[$i][3] = $this->eccubeExtension->getPriceFilter($Order->getTaxableDiscount());
  522.             // ==obl_24/04/03 end ================================
  523.             // ==obl_24/04/03 空白行を削除=============================
  524.             // DEL      ++$i;
  525.             // DEL      $arrOrder[$i][0] = '';
  526.             // DEL      $arrOrder[$i][1] = '';
  527.             // DEL      $arrOrder[$i][2] = '';
  528.             // DEL      $arrOrder[$i][3] = '';
  529.             // ==obl_24/04/03 end =============================
  530.             // ==obl_24/04/03 upd 端数調整の為、お買上額合計-明細合計を消費税とする ====================
  531.             ++$i;
  532.             $arrOrder[$i][0] = '';
  533.             $arrOrder[$i][1] = '';
  534.             $arrOrder[$i][2] = '内消費税(10%)';
  535.             // $arrOrder[$i][3] = $this->eccubeExtension->getPriceFilter($Order->getTaxableTotal());
  536.             //  $arrOrder[$i][3] = $this->eccubeExtension->getPriceFilter($Order->getPaymentTotal() - $meisai_gokei);
  537.             // $taxVal = 10;
  538.             // $roundingType = $Order->getRoundingTypeByTaxRate();
  539.             // $prnTax = TaxRuleService::roundByRoundingType($meisai_gokei * $taxVal / 100, $roundingType[$taxVal]->getId());
  540.             //  $arrOrder[$i][3] = $this->eccubeExtension->getPriceFilter($prnTax);
  541.             // 算出した消費税額が販売時の消費税額と異なる場合、端数調整額を表示  ※必要なくなったがとりあえず残す
  542.             $culkTax=0;
  543.             foreach ($Order->getTotalByTaxRate() as $rate => $total) {
  544.                 $this->eccubeExtension->getPriceFilter($total);
  545.                 $culkTax += $Order->getTaxByTaxRate()[$rate];
  546.             }
  547.             $arrOrder[$i][3] = $this->eccubeExtension->getPriceFilter($culkTax);
  548.    
  549.             // if($prnTax != $culkTax){
  550.             //     ++$i;
  551.             //     $arrOrder[$i][0] = '';
  552.             //     $arrOrder[$i][1] = '';
  553.             //     $arrOrder[$i][2] = '端数調整';
  554.             // DEL  $arrOrder[$i][3] = $this->eccubeExtension->getPriceFilter($culkTax - $prnTax);
  555.             // 端数調整  お買上額-(商品合計+商品合計消費税額)に修正
  556.             //     $arrOrder[$i][3] = $this->eccubeExtension->getPriceFilter($Order->getPaymentTotal() - ($meisai_gokei + $prnTax)) ;
  557.             // }   
  558.             // ==obl_24/04/03 upd end =============================
  559.             // DEL      ++$i;
  560.             // DEL      $arrOrder[$i][0] = '';
  561.             // DEL      $arrOrder[$i][1] = '';
  562.             // DEL      $arrOrder[$i][2] = '';
  563.             // DEL      $arrOrder[$i][3] = '';
  564.             foreach ($Order->getTaxFreeDiscountItems() as $Item) {
  565.                 ++$i;
  566.                 $arrOrder[$i][0] = '';
  567.                 $arrOrder[$i][1] = '';
  568.                 $arrOrder[$i][2] = $Item->getProductName();
  569.                 $arrOrder[$i][3] = $this->eccubeExtension->getPriceFilter($Item->getTotalPrice());
  570.             }
  571.             //dell      ++$i;
  572.             //dell      $arrOrder[$i][0] = '';
  573.             //dell      $arrOrder[$i][1] = '';
  574.                         // obl_21/01/13  名称変更
  575.             //dell      $arrOrder[$i][2] = '請求金額';
  576.             //dell      $arrOrder[$i][2] = 'お買上金額';
  577.             // obl_21/01/13  END
  578.             //dell      $arrOrder[$i][3] = $this->eccubeExtension->getPriceFilter($Order->getPaymentTotal());
  579.             if ($isShowReducedTaxMess) {
  580.                 ++$i;
  581.                 $arrOrder[$i][0] = '※は軽減税率対象商品です。';
  582.                 $arrOrder[$i][1] = '';
  583.                 $arrOrder[$i][2] = '';
  584.                 $arrOrder[$i][3] = '';
  585.             }
  586.         }
  587.         // PDFに設定する
  588.         $this->setFancyTable($this->labelCell$arrOrder$this->widthCell);
  589.     
  590.         // // インボイス対応
  591.         // $this->backupFont();
  592.         // $this->SetLineWidth(.3);
  593.         // $this->SetFont(self::FONT_SJIS, '', 6);
  594.         // $this->Cell(0, 0, '', 0, 1, 'C', 0, '');
  595.         // // 行頭近くの場合、表示崩れがあるためもう一個字下げする
  596.         // if (270 <= $this->GetY()) {
  597.         //     $this->Cell(0, 0, '', 0, 1, 'C', 0, '');
  598.         // }
  599.         // $width = array_reduce($this->widthCell, function ($n, $w) {
  600.         //     return $n + $w;
  601.         // });
  602.         // $this->SetX(20);
  603.         // $message = '';
  604.         // foreach ($Order->getTotalByTaxRate() as $rate => $total) {
  605.         //     $message .= '('.$rate.'%対象: ';
  606.         //     $message .= $this->eccubeExtension->getPriceFilter($total);
  607.         //     $message .= ' 内消費税: '.$this->eccubeExtension->getPriceFilter($Order->getTaxByTaxRate()[$rate]).')'.PHP_EOL;
  608.         //    }
  609.         // $this->MultiCell($width, 4, $message, 0, 'R', 0, '');
  610.         // $this->restoreFont();
  611.     }
  612.     /**
  613.      * PDFへのテキスト書き込み
  614.      *
  615.      * @param int    $x     X座標
  616.      * @param int    $y     Y座標
  617.      * @param string $text  テキスト
  618.      * @param int    $size  フォントサイズ
  619.      * @param string $style フォントスタイル
  620.      */
  621.     protected function lfText($x$y$text$size 0$style '')
  622.     {
  623.         // 退避
  624.         $bakFontStyle $this->FontStyle;
  625.         $bakFontSize $this->FontSizePt;
  626.         $this->SetFont(''$style$size);
  627.         $this->Text($x $this->baseOffsetX$y $this->baseOffsetY$text);
  628.         // 復元
  629.         $this->SetFont(''$bakFontStyle$bakFontSize);
  630.     }
  631.     /**
  632.      * Colored table.
  633.      *
  634.      * @param array $header 出力するラベル名一覧
  635.      * @param array $data   出力するデータ
  636.      * @param array $w      出力するセル幅一覧
  637.      */
  638.     protected function setFancyTable($header$data$w)
  639.     {
  640.         // フォント情報のバックアップ
  641.         $this->backupFont();
  642.         // 開始座標の設定
  643.         $this->setBasePosition(0149);
  644.         // Colors, line width and bold font
  645.         $this->SetFillColor(216216216);
  646.         $this->SetTextColor(0);
  647.         $this->SetDrawColor(000);
  648.         $this->SetLineWidth(.3);
  649.         $this->SetFont(self::FONT_SJIS'B'8);
  650.         $this->SetFont('''B');
  651.         // Header
  652.         $this->Cell(57''00''0'');
  653.         $count count($header);
  654.         for ($i 0$i $count; ++$i) {
  655.             $this->Cell($w[$i], 7$header[$i], 10'C'1);
  656.         }
  657.         $this->Ln();
  658.         // Color and font restoration
  659.         $this->SetFillColor(235235235);
  660.         $this->SetTextColor(0);
  661.         $this->SetFont('');
  662.         // Data
  663.         $fill 0;
  664.         $writeRow = function($row$cellHeight$fill$isBorder) use($w) {
  665.             $i 0;
  666.             $h 0;
  667.             foreach ($row as $col) {
  668.                 // 列の処理
  669.                 // TODO: 汎用的ではない処理。この指定は呼び出し元で行うようにしたい。
  670.                 // テキストの整列を指定する
  671.                 $align = ($i == 0) ? 'L' 'R';
  672.                 // セル高さが最大値を保持する
  673.                 if ($h >= $cellHeight) {
  674.                     $cellHeight $h;
  675.                 }
  676.                 // 最終列の場合は次の行へ移動
  677.                 // (0: 右へ移動(既定)/1: 次の行へ移動/2: 下へ移動)
  678.                 $ln = ($i == (count($row) - 1)) ? 0;
  679.                 $this->MultiCell(
  680.                     $w[$i], // セル幅
  681.                     $cellHeight// セルの最小の高さ
  682.                     !$isBorder $col ''// 文字列
  683.                     $isBorder 0// 境界線の描画方法を指定
  684.                     $align// テキストの整列
  685.                     $fill// 背景の塗つぶし指定
  686.                     $ln // 出力後のカーソルの移動方法
  687.                 );
  688.                 $h $this->getLastH();
  689.                 $i++;
  690.             }
  691.             return $cellHeight;
  692.         };
  693.         foreach ($data as $row) {
  694.             // 行の処理
  695.             $h 4;
  696.             $this->Cell(5$h''00''0'');
  697.             if ((277 $this->getY()) < ($h 4)) {
  698.                 $this->checkPageBreak($this->PageBreakTrigger 1);
  699.             }
  700.             $x $this->getX();
  701.             $y $this->getY();
  702.             // 1度目は文字だけ出力し、行の高さ最大を取得
  703.             $h $writeRow($row$h$fillfalse);
  704.             $this->setXY($x$y);
  705.             // 2度目に最大の高さに合わせて、境界線を描画
  706.             $writeRow($row$h$filltrue);
  707.             $fill = !$fill;
  708.         }
  709.         $h 4;
  710.         $this->Cell(5$h''00''0'');
  711.         $this->Cell(array_sum($w), 0'''T');
  712.         $this->SetFillColor(255);
  713.         // フォント情報の復元
  714.         $this->restoreFont();
  715.     }
  716.     /**
  717.      * 基準座標を設定する.
  718.      *
  719.      * @param int $x
  720.      * @param int $y
  721.      */
  722.     protected function setBasePosition($x null$y null)
  723.     {
  724.         // 現在のマージンを取得する
  725.         $result $this->getMargins();
  726.         // 基準座標を指定する
  727.         $actualX is_null($x) ? $result['left'] : $x;
  728.         $this->SetX($actualX);
  729.         $actualY is_null($y) ? $result['top'] : $y;
  730.         $this->SetY($actualY);
  731.     }
  732.     /**
  733.      * Font情報のバックアップ.
  734.      */
  735.     protected function backupFont()
  736.     {
  737.         // フォント情報のバックアップ
  738.         $this->bakFontFamily $this->FontFamily;
  739.         $this->bakFontStyle $this->FontStyle;
  740.         $this->bakFontSize $this->FontSizePt;
  741.     }
  742.     /**
  743.      * Font情報の復元.
  744.      */
  745.     protected function restoreFont()
  746.     {
  747.         $this->SetFont($this->bakFontFamily$this->bakFontStyle$this->bakFontSize);
  748.     }
  749. }