Add Excel export to Billplz Transaction Summary
This commit is contained in:
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exports;
|
||||||
|
|
||||||
|
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
|
||||||
|
|
||||||
|
class BillplzTransactionSummaryExport implements WithMultipleSheets
|
||||||
|
{
|
||||||
|
protected $bill_plz_transaction_summary_pkb;
|
||||||
|
protected $bill_plz_transaction_summary_koop;
|
||||||
|
protected $date;
|
||||||
|
|
||||||
|
public function __construct($bill_plz_transaction_summary_pkb, $bill_plz_transaction_summary_koop, $date = null)
|
||||||
|
{
|
||||||
|
$this->bill_plz_transaction_summary_pkb = $bill_plz_transaction_summary_pkb;
|
||||||
|
$this->bill_plz_transaction_summary_koop = $bill_plz_transaction_summary_koop;
|
||||||
|
$this->date = $date;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function sheets(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
new BillplzTransactionSummarySheet($this->bill_plz_transaction_summary_pkb, 'PKB (v2)', $this->date),
|
||||||
|
new BillplzTransactionSummarySheet($this->bill_plz_transaction_summary_koop, 'KOPKB (v3)', $this->date),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,180 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exports;
|
||||||
|
|
||||||
|
use Maatwebsite\Excel\Concerns\FromArray;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithColumnWidths;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithEvents;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithStrictNullComparison;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithStyles;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithTitle;
|
||||||
|
use Maatwebsite\Excel\Events\AfterSheet;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Cell\Cell;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||||
|
|
||||||
|
|
||||||
|
class BillplzTransactionSummarySheet extends DefaultValueBinder implements FromArray, WithColumnFormatting, WithColumnWidths, WithCustomValueBinder, WithEvents, WithStrictNullComparison, WithStyles, WithTitle
|
||||||
|
{
|
||||||
|
protected $summary_data;
|
||||||
|
protected $sheet_title;
|
||||||
|
protected $date;
|
||||||
|
|
||||||
|
public function __construct($summary_data, $sheet_title, $date = null)
|
||||||
|
{
|
||||||
|
$this->summary_data = $summary_data;
|
||||||
|
$this->sheet_title = $sheet_title;
|
||||||
|
$this->date = $date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function title(): string
|
||||||
|
{
|
||||||
|
return $this->sheet_title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function bindValue(Cell $cell, $value)
|
||||||
|
{
|
||||||
|
if ($cell->getColumn() === 'J' && $value !== '' && $value !== null) {
|
||||||
|
$cell->setValueExplicit((string) $value, DataType::TYPE_STRING);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::bindValue($cell, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function columnFormats(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'J' => NumberFormat::FORMAT_TEXT,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
public function registerEvents(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
AfterSheet::class => function (AfterSheet $event) {
|
||||||
|
$sheet = $event->sheet->getDelegate();
|
||||||
|
$highest_column = $sheet->getHighestColumn(8);
|
||||||
|
$sheet->mergeCells('A1:' . $highest_column . '1');
|
||||||
|
$sheet->getStyle('A1')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
|
||||||
|
$sheet->getStyle('B6')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_LEFT);
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function columnWidths(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'A' => 25,
|
||||||
|
'B' => 22,
|
||||||
|
'C' => 15,
|
||||||
|
'D' => 22,
|
||||||
|
'E' => 15,
|
||||||
|
'F' => 22,
|
||||||
|
'G' => 20,
|
||||||
|
'H' => 15,
|
||||||
|
'I' => 30,
|
||||||
|
'J' => 16,
|
||||||
|
'K' => 20,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function styles(Worksheet $sheet)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
1 => ['alignment' => ['wrapText' => true, 'horizontal' => Alignment::HORIZONTAL_CENTER]],
|
||||||
|
3 => ['alignment' => ['wrapText' => true]],
|
||||||
|
4 => ['alignment' => ['wrapText' => true]],
|
||||||
|
5 => ['alignment' => ['wrapText' => true]],
|
||||||
|
6 => ['alignment' => ['wrapText' => true]],
|
||||||
|
8 => ['alignment' => ['wrapText' => true]],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public function array(): array
|
||||||
|
{
|
||||||
|
$title = 'Billplz Transaction Summary' . ($this->date ? ' (' . $this->date . ')' : '');
|
||||||
|
$rows = [];
|
||||||
|
$rows[] = [$title];
|
||||||
|
$rows[] = ['', '', '', '', '', '', '', '', '', '', ''];
|
||||||
|
|
||||||
|
$rows[] = ['Sum of Billplz Transactions', $this->summary_data['sumOfBillplzTransactions'] ?? ''];
|
||||||
|
$rows[] = ['Sum of Arrahn Transactions', $this->summary_data['sumOfArrahnTransactions'] ?? ''];
|
||||||
|
$rows[] = ['Payment Gateway Cost', $this->summary_data['paymentGatewayCost'] ?? ''];
|
||||||
|
$rows[] = ['No of Arrahn Transactions', $this->summary_data['numberOfArrahnTransactions'] ?? ''];
|
||||||
|
$rows[] = ['', '', '', '', '', '', '', '', '', '', ''];
|
||||||
|
|
||||||
|
$rows[] = [
|
||||||
|
'Bil',
|
||||||
|
'Billplz ID',
|
||||||
|
'Billplz Status',
|
||||||
|
'Billplz Paid Amount (RM)',
|
||||||
|
'Arrahn Status',
|
||||||
|
'Arrahn Total Payment',
|
||||||
|
'Arrahn Norujukan',
|
||||||
|
'Arrahn Kodcaw',
|
||||||
|
'Arrahn Customer Name',
|
||||||
|
'Arrahn No. KP',
|
||||||
|
'Arrahn Paid At',
|
||||||
|
];
|
||||||
|
|
||||||
|
$bil = 1;
|
||||||
|
$details = $this->summary_data['billPlzTransactionSummary'] ?? [];
|
||||||
|
|
||||||
|
foreach ($details as $data) {
|
||||||
|
$billplz_bill = $data['billplz_bill'] ?? null;
|
||||||
|
$arrahn_transactions = $data['arrahn_transactions'] ?? [];
|
||||||
|
|
||||||
|
$billplz_id = $billplz_bill['id'] ?? '';
|
||||||
|
$billplz_status = $billplz_bill['state'] ?? '';
|
||||||
|
$billplz_paid_amount = '';
|
||||||
|
|
||||||
|
if (isset($billplz_bill['paid_amount']['amount'])) {
|
||||||
|
$billplz_paid_amount = floatval($billplz_bill['paid_amount']['amount']) / 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($arrahn_transactions)) {
|
||||||
|
$rows[] = [
|
||||||
|
$bil++,
|
||||||
|
$billplz_id,
|
||||||
|
$billplz_status,
|
||||||
|
$billplz_paid_amount,
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
];
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($arrahn_transactions as $transaction) {
|
||||||
|
$rows[] = [
|
||||||
|
$bil++,
|
||||||
|
$billplz_id,
|
||||||
|
$billplz_status,
|
||||||
|
$billplz_paid_amount,
|
||||||
|
$transaction['status'] ?? '',
|
||||||
|
$transaction['total_payment'] ?? '',
|
||||||
|
$transaction['norujukan'] ?? '',
|
||||||
|
$transaction['kodcaw'] ?? '',
|
||||||
|
$transaction['customer_name'] ?? '',
|
||||||
|
$transaction['nokp'] ?? '',
|
||||||
|
$transaction['paid_at'] ?? '',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $rows;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,14 +5,58 @@ use Illuminate\Http\Request;
|
|||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
use App\Exports\BillplzTransactionSummaryExport;
|
||||||
|
use App\Exports\BillplzTransactionSummarySheet;
|
||||||
|
|
||||||
|
|
||||||
class BillplzTransactionSummaryController extends Controller
|
class BillplzTransactionSummaryController extends Controller
|
||||||
{
|
{
|
||||||
public function index(Request $request)
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
$date = $request->selectedDate ?? Carbon::now()->toDateString();
|
$date = $request->selectedDate ?? Carbon::now()->toDateString();
|
||||||
|
|
||||||
$transactionDataPKB = collect( Http::arrahn()->get('/api/transaction/online/query', ['date' => $date, 'status' => 'paid'])->json() );
|
[$billPlzTransactionSummaryPKB, $billPlzTransactionSummaryKOOP] = $this->getSummaryData($date);
|
||||||
|
|
||||||
|
return view('online.billplz-transaction-summary.index', compact('billPlzTransactionSummaryPKB', 'billPlzTransactionSummaryKOOP', 'date'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function export(Request $request)
|
||||||
|
{
|
||||||
|
$date = $request->selectedDate ?? Carbon::now()->toDateString();
|
||||||
|
$tab = $request->tab ?? 'all';
|
||||||
|
|
||||||
|
[$billPlzTransactionSummaryPKB, $billPlzTransactionSummaryKOOP] = $this->getSummaryData($date);
|
||||||
|
|
||||||
|
if ($tab === 'kopkb') {
|
||||||
|
$file_name = 'billplz_transaction_summary_kopkb_' . $date . '.xlsx';
|
||||||
|
|
||||||
|
return Excel::download(
|
||||||
|
new BillplzTransactionSummarySheet($billPlzTransactionSummaryKOOP, 'KOPKB (v3)', $date),
|
||||||
|
$file_name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($tab === 'pkb') {
|
||||||
|
$file_name = 'billplz_transaction_summary_pkb_' . $date . '.xlsx';
|
||||||
|
|
||||||
|
return Excel::download(
|
||||||
|
new BillplzTransactionSummarySheet($billPlzTransactionSummaryPKB, 'PKB (v2)', $date),
|
||||||
|
$file_name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$file_name = 'billplz_transaction_summary_' . $date . '.xlsx';
|
||||||
|
|
||||||
|
return Excel::download(
|
||||||
|
new BillplzTransactionSummaryExport($billPlzTransactionSummaryPKB, $billPlzTransactionSummaryKOOP, $date),
|
||||||
|
$file_name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getSummaryData($date)
|
||||||
|
{
|
||||||
|
$transactionDataPKB = collect( Http::arrahn()->get('/api/transaction/online/query', ['date' => $date, 'status' => 'paid'])->json() );
|
||||||
$transactionDataPKB = $transactionDataPKB->map(function($x){
|
$transactionDataPKB = $transactionDataPKB->map(function($x){
|
||||||
$x['account_own_by'] = 'PKB';
|
$x['account_own_by'] = 'PKB';
|
||||||
return $x;
|
return $x;
|
||||||
@@ -60,14 +104,14 @@ class BillplzTransactionSummaryController extends Controller
|
|||||||
abort( response('Portal ArrahnPay kemungkinan tidak beroperasi. Waktu Operasi Portal ArrahnPay adalah dari 7.30 AM hingga 11.30 PM', 503) );
|
abort( response('Portal ArrahnPay kemungkinan tidak beroperasi. Waktu Operasi Portal ArrahnPay adalah dari 7.30 AM hingga 11.30 PM', 503) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return $billplzBillsPromise;
|
return $billplzBillsPromise;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
$mergeBillplzResponse = function($externalArray) {
|
$mergeBillplzResponse = function($externalArray) {
|
||||||
$merged = [];
|
$merged = [];
|
||||||
|
|
||||||
foreach ($externalArray as $key => $subArray) {
|
foreach ($externalArray as $key => $subArray) {
|
||||||
foreach (['KOPKB', 'PKB'] as $type) {
|
foreach (['KOPKB', 'PKB'] as $type) {
|
||||||
if (!isset($merged[$type])) {
|
if (!isset($merged[$type])) {
|
||||||
$merged[$type] = [];
|
$merged[$type] = [];
|
||||||
@@ -75,9 +119,9 @@ class BillplzTransactionSummaryController extends Controller
|
|||||||
|
|
||||||
$merged[$type] = array_merge($merged[$type], $subArray[$type]);
|
$merged[$type] = array_merge($merged[$type], $subArray[$type]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return array_map('array_values', $merged);
|
return array_map('array_values', $merged);
|
||||||
};
|
};
|
||||||
|
|
||||||
$billplzBillsResponse = $queryBillIdsURL->map(fn($x) => $getBillplzPromise($x))
|
$billplzBillsResponse = $queryBillIdsURL->map(fn($x) => $getBillplzPromise($x))
|
||||||
@@ -88,9 +132,11 @@ class BillplzTransactionSummaryController extends Controller
|
|||||||
|
|
||||||
$data = array_map(fn($x, $y) => $this->processBillplzBills($x, $y), $billplzBills, [$transactionDataKOOP, $transactionDataPKB]);
|
$data = array_map(fn($x, $y) => $this->processBillplzBills($x, $y), $billplzBills, [$transactionDataKOOP, $transactionDataPKB]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[$billPlzTransactionSummaryKOOP, $billPlzTransactionSummaryPKB] = $data;
|
[$billPlzTransactionSummaryKOOP, $billPlzTransactionSummaryPKB] = $data;
|
||||||
|
|
||||||
return view('online.billplz-transaction-summary.index', compact('billPlzTransactionSummaryPKB' ,'billPlzTransactionSummaryKOOP', 'date'));
|
return [$billPlzTransactionSummaryPKB, $billPlzTransactionSummaryKOOP];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function processArrahnTransactions($transactionData)
|
public function processArrahnTransactions($transactionData)
|
||||||
|
|||||||
@@ -10,14 +10,23 @@
|
|||||||
</breadcrumb>
|
</breadcrumb>
|
||||||
|
|
||||||
|
|
||||||
<div class="container p-4 mx-auto">
|
<div class="container pt-4 mx-auto">
|
||||||
<div class="flex mb-0 border-b border-gray-200">
|
<div class="flex mb-0 border-b border-gray-200 justify-between items-center">
|
||||||
<button class="flex items-center tab-button active" data-tab="pkb-transactions-summary">
|
<div class="flex">
|
||||||
<span>PKB (v2)</span>
|
<button class="flex items-center tab-button active" data-tab="pkb-transactions-summary">
|
||||||
</button>
|
<span>PKB (v2)</span>
|
||||||
<button class="flex items-center tab-button" data-tab="kopkb-transactions-summary">
|
</button>
|
||||||
<span>KOPKB (v3)</span>
|
<button class="flex items-center tab-button" data-tab="kopkb-transactions-summary">
|
||||||
</button>
|
<span>KOPKB (v3)</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<a id="export-summary-btn"
|
||||||
|
href="{{ route('transaction.online.billplz-transaction-summary.export', ['selectedDate' => $date, 'tab' => 'pkb']) }}"
|
||||||
|
data-date="{{ $date }}"
|
||||||
|
class="bg-gray-500 text-white py-2 px-6 font-medium rounded-xl hover:bg-gray-600 transition-all duration-300 mb-1">
|
||||||
|
<i class="fas fa-file-excel mr-2"></i> <span id="export-summary-text">Export Excel for v2</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div id="pkb-transactions-summary" class="container p-4 mx-auto bg-yellow-50 tab-content active">
|
<div id="pkb-transactions-summary" class="container p-4 mx-auto bg-yellow-50 tab-content active">
|
||||||
@@ -210,6 +219,17 @@
|
|||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
const tabButtons = document.querySelectorAll('.tab-button');
|
const tabButtons = document.querySelectorAll('.tab-button');
|
||||||
const tabContents = document.querySelectorAll('.tab-content');
|
const tabContents = document.querySelectorAll('.tab-content');
|
||||||
|
const exportBtn = document.getElementById('export-summary-btn');
|
||||||
|
const exportText = document.getElementById('export-summary-text');
|
||||||
|
const selectedDate = exportBtn.getAttribute('data-date');
|
||||||
|
const exportBaseUrl = "{{ route('transaction.online.billplz-transaction-summary.export') }}";
|
||||||
|
|
||||||
|
function updateExportButton(tabId) {
|
||||||
|
const tab = tabId === 'kopkb-transactions-summary' ? 'kopkb' : 'pkb';
|
||||||
|
const version = tabId === 'kopkb-transactions-summary' ? 'v3' : 'v2';
|
||||||
|
exportBtn.href = exportBaseUrl + '?selectedDate=' + encodeURIComponent(selectedDate) + '&tab=' + tab;
|
||||||
|
exportText.textContent = 'Export Excel for ' + version;
|
||||||
|
}
|
||||||
|
|
||||||
tabButtons.forEach(button => {
|
tabButtons.forEach(button => {
|
||||||
button.addEventListener('click', () => {
|
button.addEventListener('click', () => {
|
||||||
@@ -221,8 +241,9 @@
|
|||||||
|
|
||||||
// Activate the clicked tab
|
// Activate the clicked tab
|
||||||
button.classList.add('active');
|
button.classList.add('active');
|
||||||
console.log(tabId)
|
|
||||||
document.getElementById(tabId).classList.add('active');
|
document.getElementById(tabId).classList.add('active');
|
||||||
|
|
||||||
|
updateExportButton(tabId);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -183,6 +183,7 @@ Route::get('/transaction/online/trail', OnlineTransactionTrailController::class)
|
|||||||
Route::get('/transaction/online/billplz-transaction-review', [BillplzTransactionReviewController::class, 'index'])->name('transaction.online.billplz-transaction-review.index');
|
Route::get('/transaction/online/billplz-transaction-review', [BillplzTransactionReviewController::class, 'index'])->name('transaction.online.billplz-transaction-review.index');
|
||||||
Route::get('/transaction/online/billplz-transaction-review/{bill_id}', [BillplzTransactionReviewController::class, 'show'])->name('transaction.online.billplz-transaction-review.show');
|
Route::get('/transaction/online/billplz-transaction-review/{bill_id}', [BillplzTransactionReviewController::class, 'show'])->name('transaction.online.billplz-transaction-review.show');
|
||||||
Route::get('/transaction/online/billplz-transaction-summary', [BillplzTransactionSummaryController::class, 'index'])->name('transaction.online.billplz-transaction-summary.index');
|
Route::get('/transaction/online/billplz-transaction-summary', [BillplzTransactionSummaryController::class, 'index'])->name('transaction.online.billplz-transaction-summary.index');
|
||||||
|
Route::get('/transaction/online/billplz-transaction-summary/export', [BillplzTransactionSummaryController::class, 'export'])->name('transaction.online.billplz-transaction-summary.export');
|
||||||
Route::get('/transaction/online/log', [OnlineTransactionLogController::class, 'index'])->name('transaction.online.log.index');
|
Route::get('/transaction/online/log', [OnlineTransactionLogController::class, 'index'])->name('transaction.online.log.index');
|
||||||
Route::get('/transaction/online/log/{bill_id}', [OnlineTransactionLogController::class, 'show'])->name('transaction.online.log.show');
|
Route::get('/transaction/online/log/{bill_id}', [OnlineTransactionLogController::class, 'show'])->name('transaction.online.log.show');
|
||||||
Route::get('/transaction/online/gadaian/{norujukan}', OnlineTransactionGadaianController::class)->name('transaction.online.gadaian');
|
Route::get('/transaction/online/gadaian/{norujukan}', OnlineTransactionGadaianController::class)->name('transaction.online.gadaian');
|
||||||
|
|||||||
Reference in New Issue
Block a user