Yii2 : Generator Invoice Sederhana (part 2)

Post berikut ini adalah post lanjutan tentang tutorial membuat generator invoice sederhana menggunakan yiiframework. Bagian pertama bisa dibaca di sini. Pada bagian pertama kita sudah bisa mengenerate invoice dan mengupdate nya. Pada bagian kedua ini kita akan tambahkan feature generate invoice dalam format PDF dan proses payment.

Generate PDF

Pertama-tama kita install plugin mpdf dari kartik

composer require kartik-v/yii2-mpdf "dev-master"

notehttp://demos.krajee.com/mpdf#installation

Kita akan ubah actionView() pada InvoiceController.php menjadi generator pdf untuk invoice yang telah dibuat. Silahkan update fungsinya menjadi seperti di bawah ini.

/**
 * generate pdf .
 * @param integer $id
 * @return mixed
 * @throws NotFoundHttpException if the model cannot be found
 */
public function actionView($id)
{
    // get your HTML raw content without any layouts or scripts
    $model = $this->findModel($id);
    $items = InvoiceItem::find()->where(['id_invoice'=>$id])->all();
    $content = $this->renderPartial('view',['model'=>$model,'items'=>$items]);

    // setup kartik\mpdf\Pdf component
    $pdf = new Pdf([
        // set to use core fonts only
        'mode' => Pdf::MODE_CORE,
        // A4 paper format
        'format' => Pdf::FORMAT_A4,
        // portrait orientation
        'orientation' => Pdf::ORIENT_PORTRAIT,
        // stream to browser inline
        'destination' => Pdf::DEST_BROWSER,
        // your html content input
        'content' => $content,
        // format content from your own css file if needed or use the
        // enhanced bootstrap css built by Krajee for mPDF formatting
        'cssFile' => '@vendor/kartik-v/yii2-mpdf/src/assets/kv-mpdf-bootstrap.min.css',
        // any css to be embedded if required
        'cssInline' => '.kv-heading-1{font-size:18px}',
        // set mPDF properties on the fly
        'options' => ['title' => 'Invoice number'],
        // call mPDF methods on the fly
        'methods' => [
            'SetHeader'=>false,
            'SetFooter'=>false,
        ]
    ]);

    // return the pdf output as per the destination setting
    return $pdf->render();
}

Kemudian update file invoice/view.php menjadi seperti di bawah ini.

<?php
use yii\helpers\Html;
?>

<table border="0" width="100%">
    <tr>
        <td align="right">
            <?php if($model->status==\app\models\Invoice::STATUS_PAID):?>
                <?= Html::img('@web/img/paid.png');?>
            <?php else:?>
                <?= Html::img('@web/img/unpaid.jpg');?>
            <?php endif;?>
        </td>
    </tr>
</table>
<!-- silahkan update data penerbit invoice di bawah ini -->

<table border="0" width="100%" cellpadding="5" cellspacing="5">
    <tr>
        <td bgcolor="#a9a9a9" width="212px"> &nbsp;L O G O</td>
        <td align="right">
            Tajimalela<br>
            Sumedang -  Indonesia
        </td>
    </tr>
</table>
<br><br>
<table width="100%" cellpadding="5" cellspacing="5">
    <tr>
        <td bgcolor="#eee">
            <b>Invoice #<?= $model->invoice_number;?></b><br>
            Invoice Date #<?= $model->created_at;?><br>
            Due Date #<?= $model->due_date;?><br>
        </td>
    </tr>

    <tr>
        <td>
            <br><br>
            <b>Invoiced To :</b><br>
            <?= $model->name;?><br>
            ATTN : <?= $model->attn;?><br>
            <?= $model->address;?><br>
        </td>
    </tr>

    <tr>
        <td>
            <br><br>
            <table width="100%" cellpadding="5" cellspacing="0" border="1">
                <tr bgcolor="#eee">
                    <th width="80%" align="center">Description</th>
                    <th align="center">Total</th>
                </tr>
                <?php foreach($items as $m):?>
                    <tr>
                        <td><?= $m->item;?></td>
                        <td>Rp.<?= number_format($m->total,0);?></td>
                    </tr>
                <?php endforeach;?>

                <tr bgcolor="#eee">
                    <td align="right">
                        <b>Subtotal</b><br>
                        <b>Credit</b>
                    </td>
                    <td align="center">
                        <b>Rp.<?= number_format($model->amount,0);?></b><br>
                        <b>Rp.0</b>
                    </td>
                </tr>
                <tr bgcolor="#eee">
                    <td align="center">
                        <b>Total</b>
                    </td>
                    <td align="center">
                        <b>Rp.<?= number_format($model->amount,0);?></b>
                    </td>
                </tr>

            </table>
        </td>
    </tr>
</table>

<br>

<h3>Transaction</h3>
<table width="100%" cellpadding="5" cellspacing="0" border="1">
    <tr bgcolor="#eee">
        <th align="center">Transaction Date</th>
        <th align="center">Payment Method</th>
        <th align="center">Transaction ID</th>
        <th align="center">Amount</th>
    </tr>
    <?php if($model->status=='UNPAID'):?>
        <tr>
            <td colspan="4" align="center">No Related Transactions Found</td>
        </tr>
        <tr bgcolor="#eee">
            <td colspan="3" align="right"><b>Balance</b></td>
            <td align="center"><b>Rp.<?= number_format($model->amount,0);?></b></td>
        </tr>
    <?php else:?>
        <tr>
            <td align="center"><?= $model->transaction_date;?></td>
            <td align="center"><?= $model->payment_method;?></td>
            <td align="center"><?= $model->transaction_id;?></td>
            <td align="center">Rp.<?= number_format($model->payment,0);?></td>
        </tr>
        <tr bgcolor="#eee">
            <td colspan="3" align="right"><b>Balance</b></td>
            <td align="center"><b>Rp.0</b></td>
        </tr>

    <?php endif;?>
</table>
<br><br><br><br>
<table width="100%">
    <tr>
        <td align="center">PDF Generated on <?= $model->created_at;?></td>
    </tr>
</table>

Pada view di atas, kita akan menambahkan cap paid atau unpaid sesuai dengan status invoice. Silahkan save kedua gambar berikut lalu simpan di dalam folder web/img/

stempel paid stempel unpaid

Silahkan dicoba, masuk ke list invoice lalu view salah satu invoice dengan mengklik icon mata pada tabel.

pdf invoice

 

Payment

Secara teknis, pada proses payment ini akan merubah status invoice dari created ke paid dan menyimpan data-data pembayaran yaitu jumlah bayar, payment method, payment id dan tanggal bayar.

Kita tambahkan satu link pada gridview untuk proses pembayaran. Update gridview pada invoice/index.php menjadi seperti di bawah ini.

<?= GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,
        'columns' => [
            ['class' => 'yii\grid\SerialColumn'],
            'invoice_number',
            'due_date',
            'attn',
            'amount',
            //'transaction_date',
            //'transaction_id',
            [
                'class' => 'yii\grid\ActionColumn',
                'template'=>'{view} {update} {payment} {delete}',
                'buttons'=>[
                    'payment'=> function($url,$model){
                        if($model->status==\app\models\Invoice::STATUS_CREATED)
                            return Html::a('<span class="glyphicon glyphicon-ok"></span>',\yii\helpers\Url::toRoute(['invoice/payment','id'=>$model->id]),['title'=>'payment']);
                    },
                ]

            ],
        ],
    ]); ?>

Tambahkan actionPayment() pada InvoiceController.php

//untuk proses payment
public function actionPayment($id){
    //cek apakah status invoice masih 'created'
    $model = $this->findModel($id);
    if($model->status !== Invoice::STATUS_CREATED)
        throw new NotFoundHttpException('The requested page does not exist.');

    //tambahkan skenario payment untuk mengaktifkan rule pada model
    $model->scenario = 'payment';
    $model->transaction_date = date('Y-m-d');
    $model->payment = $model->amount;

    //query data item invoice untuk ditampilkan
    $items = new ActiveDataProvider([
        'query' => InvoiceItem::find()->where(['id_invoice'=>$id]),
    ]);

    if($model->load(Yii::$app->request->post())){
        //ganti status menjadi 'paid'
        $model->status = Invoice::STATUS_PAID;
        if($model->save()){
            Yii::$app->session->setFlash('success', 'Data payment telah berhasil disimpan');
            return $this->redirect(['invoice/index']);
        }
    }

    return $this->render('payment', [
        'model' => $model,
        'items' => $items
    ]);
}

Tambahkan rule pada function rule() untuk skenario ‘payment‘ di model Invoice.php.

//rule tambahan yang akan dipakai saat proses payment
[['payment','transaction_date','payment_method','transaction_id'],'required','on'=>'payment'],


Kemudian buat view baru invoice/payment.php lalu copy paste skrip di bawah ini.

<?php
use yii\widgets\ActiveForm;
use yii\helpers\Html;
use kartik\date\DatePicker;
use yii\grid\GridView;

$this->title = 'Payment Invoice: ' . $model->name;
$this->params['breadcrumbs'][] = ['label' => 'Invoices', 'url' => ['index']];
$this->params['breadcrumbs'][] = 'Paid';
?>
<div class="row">
    <!-- form pembayaran-->
    <div class="col-md-5">
        <?php $form = ActiveForm::begin(); ?>
        <?php
        echo $form->field($model, 'transaction_date')->widget(DatePicker::classname(), [
            'options' => ['placeholder' => ''],
            'removeButton' => false,
            'pluginOptions' => [
                'autoclose'=>true,
                'format' => 'yyyy-mm-dd'
            ]
        ]);
        ?>
        <?= $form->field($model, 'payment_method')->textInput(['maxlength' => true]) ?>
        <?= $form->field($model, 'transaction_id')->textInput(['maxlength' => true]) ?>
        <?php echo $form->field($model, 'payment')->textInput(['type'=>'number']);?>

        <div class="form-group">
            <?= Html::submitButton('Paid', ['class' => 'btn btn-success']) ?>
        </div>
        <?php ActiveForm::end(); ?>
    </div>

    <!--detail invoice-->
    <div class="col-md-7">
        <div class="well well-sm">
            <table>
                <tr>
                    <td>
                        <b>Invoiced To :</b><br>
                        <?= $model->name;?><br>
                        ATTN : <?= $model->attn;?><br>
                        <?= $model->address;?><br>
                    </td>
                    <td>&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;</td>
                    <td valign="top">
                        <b>Invoice #<?= $model->invoice_number;?></b><br>
                        Invoice Date #<?= $model->created_at;?><br>
                        Due Date #<?= $model->due_date;?><br>
                    </td>
                </tr>
                <tr>
                    <td colspan="3">
                        <br>
                        <?= GridView::widget([
                            'dataProvider' => $items,
                            'layout'=>'{items}',
                            'columns' => [
                                'item',
                                [
                                    'attribute'=>'price',
                                    'content'=>function($m){
                                        return "Rp.".number_format($m->total,0);
                                    }
                                ]
                            ],
                        ]); ?>
                    </td>
                </tr>
            </table>
        </div>
    </div>
</div>

Silahkan dicoba untuk melakukan payment, lalu cek lagi pdf nya. Jika berhasil maka cap yang tadinya ‘unpaid‘ akan berubah menjadi ‘paid‘.

sample generate PDF

Selesai…

Tutorial aplikasi untuk mengenerate invoice secara sederhana ini saya cukupkan sampai di sini, Jika membutuhkan sourcecode aplikasi ini, silahkan download di https://github.com/dendoy/invoice-generator-yii2

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *