バージョン選択

フォーラム

メニュー

オンライン状況

60 人のユーザが現在オンラインです。 (43 人のユーザが フォーラム を参照しています。)
登録ユーザ: 0
ゲスト: 60
もっと...

サイト内検索

質問 > 管理機能 > 受注一覧の納品書出力で注文ごとにPDFを出力したい

管理機能

新規スレッドを追加する

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
yuyu2000
投稿日時: 2020/6/3 10:14
対応状況: −−−
半人前
登録日: 2020/3/6
居住地:
投稿: 22
受注一覧の納品書出力で注文ごとにPDFを出力したい
受注一覧の納品書出力を複数の注文を選択して実行した場合に
複数の注文が1つのPDFにまとめられて出力されますが、
それを注文ごとに出力するようにしたいと思い
src/Eccube/Controller/Admin/Order/OrderController.phpの
exportPdfDownloadメソッドの一部を下記のように修正しました。

// PDFを注文ごとに出力
$ids = explode(',', $arrData['ids']);

foreach ($ids as $id) {
    
    $arrData['ids'] = $id;

    // 購入情報からPDFを作成する
    $status = $orderPdfService->makePdf($arrData);

    // 異常終了した場合の処理
    if (!$status) {
        $this->addError('admin.order.export.pdf.download.failure', 'admin');
        log_info('Unable to create pdf files! Process have problems!');

        return $this->render('@admin/Order/order_pdf.twig', [
            'form' => $form->createView(),
        ]);
    }

    // ダウンロードする
    $response = new Response(
        $orderPdfService->outputPdf(),
        200,
        ['content-type' => 'application/pdf']
    );

    $downloadKind = $form->get('download_kind')->getData();

    // レスポンスヘッダーにContent-Dispositionをセットし、ファイル名を指定
    if ($downloadKind == 1) {
        $response->headers->set('Content-Disposition', 'attachment; filename="'.$orderPdfService->getPdfFileName().'"');
    } else {
        $response->headers->set('Content-Disposition', 'inline; filename="'.$orderPdfService->getPdfFileName().'"');
    }
}


しかし、なぜか2つ目のPDF出力で失敗してしまいます。
OrderPdfServiceのmakePdfメソッドで$this->shippingRepositoryがnullになっているために
$this->shippingRepository->find($id)が失敗しているようです。

自分で調べた感じだと、
1回目の$orderPdfService->outputPdf()実行後に
OrderPdfServiceのコンストラクタで設定したサービスが
$this->shippingRepositoryと同様全てnullになっているように見えるのですが、

どなたか何故このような現象が起きるのか、
またどういった解決策があるのかご教示いただけないでしょうか?
468
投稿日時: 2020/6/3 10:51
対応状況: −−−
登録日: 2008/10/26
居住地:
投稿: 3217
Re: 受注一覧の納品書出力で注文ごとにPDFを出力したい
最終的にやりたい事というのは
1.pdf
2.pdf
3.pdf
のように注文ごとにPDFのファイルを分けたいと言う事でしょうか?

もしそうであれば、一回の通信で複数のファイルをダウンロードするという事はWEBの仕組み上出来ないのではないかと思いますので
forでループさせても無理だと思いますが如何でしょうか?

少なくとも私はブラウザで一回のダウンロードで複数のファイルをダウンロード出来るようなサービスは見た事がありませんので
知らないだけかもしれませんが...
(複数のファイルをダウンロードさせる場合は、ZIPファイル等の1つのファイルに圧縮したからダウンロードさせると思います)


----------------
株式会社シロハチ
■ECCUBE2系、3系構築カスタマイズご相談ください。
EC-CUBE3マニュアル
blog

yuyu2000
投稿日時: 2020/6/3 11:32
対応状況: −−−
半人前
登録日: 2020/3/6
居住地:
投稿: 22
Re: 受注一覧の納品書出力で注文ごとにPDFを出力したい
468 様
早速ご回答いただきありがとうございます。

大変失礼致しました。。
より説明しやすいようにと考えた構成が
ご指摘の通りそもそも実現不可能なものでした。。すみません。

先に説明した内容は実際にやりたいこととは微妙に違っていて
実際は管理画面ではなくCommandでOrderPdfServiceを利用して
注文ごとにPDFをローカルに作成し、顧客に送信するみたいなことをやりたいのですが、
やはり先に説明したように2回目の実行で失敗してしまうという状況です。

具体的にはCommandに以下のような処理を、

// PDFを注文ごとに出力
$ids = explode(',', $arrData['ids']);

foreach ($ids as $id) {
    
    $arrData['ids'] = $id;

    // 購入情報からPDFを作成する
    $status = $orderPdfService->makePdf($arrData);
    $filepath = '/pdfpath/' . $id . '.pdf';
    $orderPdfService->outputPdfLocal($filepath);
}


OrderPdfServiceにはローカルに出力するメソッドoutputPdfLocalを追加
/**
 * PDFをローカルに出力する
 */
public function outputPdfLocal($filepath)
{
    $this->Output($filepath, 'F');
}


のように実装しているのですが、やはりうまくいきません。

原因をご存知だったりしないでしょうか?
(色々調べたりはしたんですが、原因も解決策もわからない状況でして。。)
468
投稿日時: 2020/6/4 7:19
対応状況: −−−
登録日: 2008/10/26
居住地:
投稿: 3217
Re: 受注一覧の納品書出力で注文ごとにPDFを出力したい
Outputを実行する際、編集の終了と言う事で内部的にCloseメソッドが呼ばれますが
その辺りが原因でエラーになっているのではないでしょうか?
ECCUBEで2つ以上のPDFファイルを生成した事はありませんが
他のシステムでFPDFを利用して複数のPDFを生成するような時は
1ファイルごとにFPDFオブジェクトをインスタンス化していました。
(ECCUBEはTCPDFのようなので違うといえば違いますが...)

今回のパターンだと$orderPdfServiceをループ内でnewする必要があるのではないでしょうか?
($orderPdfServiceごとに1回したOutputできないのかも?)


----------------
株式会社シロハチ
■ECCUBE2系、3系構築カスタマイズご相談ください。
EC-CUBE3マニュアル
blog

yuyu2000
投稿日時: 2020/6/4 11:41
対応状況: −−−
半人前
登録日: 2020/3/6
居住地:
投稿: 22
Re: 受注一覧の納品書出力で注文ごとにPDFを出力したい
468 様
お忙しいところお付き合いいただきありがとうございます。

引用:
今回のパターンだと$orderPdfServiceをループ内でnewする必要があるのではないでしょうか?

はい。私も同じように思い、
以下の2つの方法でサービスの再生成?を試してはみたのですが、


$orderPdfService = new OrderPdfService();

→「Type error: Too few arguments to function Eccube\Service\OrderPdfService::__construct()」で
コンストラクタに引数を渡してないためエラーになる。
(まあ、当然といえば当然ですが。)


$orderPdfService = $this->container->get('Eccube\Service\OrderPdfService');

→実行はできるものの
同じサービスにアクセスしているだけのようで
(サービスが再生成されているわけではない?)
$this->shippingRepositoryがnullの同じエラーになる。

という感じでその方法がわからない状況でして、
何か解決方法があれば、、と思ったのですが。。


どうしようもないようであれば
外部から$this->shippingRepositoryを渡すなどして解決しようと思いますが、
何かわかることがあればアドバイスなどいただけると助かります。
468
投稿日時: 2020/6/10 10:43
対応状況: −−−
登録日: 2008/10/26
居住地:
投稿: 3217
Re: 受注一覧の納品書出力で注文ごとにPDFを出力したい
私もServiceクラスについて完全に理解している訳ではありませんが
多分、今回の要件に合っていないのだと思います。
(Serviceクラスは同じインスタンスが必ず利用できる事がウリなのだと思っているのですが...)

少しややこしくなりそうですが
OrderPdfServiceを元に新しいServiceを作って(継承元のTcpdfFpdiクラスを外部から受け取って加工するようなクラス)利用する形が良いのではないでしょうか?
私ではその方法くらいしか思い付かないです。
それで実現できるかどうかもやってみないと分からないというのが正直なところです。


----------------
株式会社シロハチ
■ECCUBE2系、3系構築カスタマイズご相談ください。
EC-CUBE3マニュアル
blog

yuyu2000
投稿日時: 2020/6/11 10:40
対応状況: −−−
半人前
登録日: 2020/3/6
居住地:
投稿: 22
Re: 受注一覧の納品書出力で注文ごとにPDFを出力したい
468 様
ご回答いただきありがとうございます。

多分、今回の要件に合っていないのだと思います。
(Serviceクラスは同じインスタンスが必ず利用できる事がウリなのだと思っているのですが...)

色々試してみて私も同じように感じました。

OrderPdfServiceを元に新しいServiceを作って(継承元のTcpdfFpdiクラスを外部から受け取って加工するようなクラス)利用する形が良いのではないでしょうか?


結局先に投稿した通り、外部からshippingRepositoryを渡す方法など試してはみたのですが、それ以外のサービスやインスタンス変数も軒並み使えない状態でOrderPdfServiceが機能せず正常に動作しないという結果でした。。

なので468様のおっしゃる通り、
他のサービスに依存しないOrderPdfServiceを別に作って対応するしかないのではないかと考えています。(時間がなくてまだ私もそれで動くか確認できてはいないですが。)
EC-CUBE2系では同様のことができたので(2系はFPDFですが)
恐らくTCPDF自体の問題ではなく、Symfonyとの関連で起きている問題ではないかと。

お忙しいところご回答いただきありがとうございました。
アドバイス大変参考になりました。
スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ


 



ログイン


EC-CUBE公式 Amazon Payプラグイン

統計情報

総メンバー数は88,291名です
総投稿数は109,691件です

投稿数ランキング

1
seasoft
7365
2
468
3217
3
AMUAMU
2712
4
nanasess
2303
5
umebius
2085
6
yuh
1818
7
h_tanaka
1610
8
red
1568
9
mcontact
1240
10
tsuji
958
11
fukap
907
12
shutta
835
13
tao_s
796
14 ramrun 789
15 karin 689
16 sumida 641
17
homan
633
18 DELIGHT 572
19
patapata
502
20
flealog
485


ネットショップの壺

EC-CUBEインテグレートパートナー

Copyright© EC-CUBE CO.,LTD. All Rights Reserved.