Merged in izzati-feat-serahan-new (pull request #84)

update serahan baru
This commit is contained in:
izzati zulkifli
2025-03-19 03:14:20 +00:00
4 changed files with 307 additions and 178 deletions
+143
View File
@@ -0,0 +1,143 @@
<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithTitle;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithStyles;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use Maatwebsite\Excel\Concerns\WithCustomStartCell;
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
class PendSerExport implements FromCollection, WithHeadings, WithTitle, WithMapping, WithStyles, WithCustomStartCell, WithColumnFormatting
{
protected $pendser;
protected $jenisLaporan;
protected $counter = 1; // ✅ Fix counter issue
public function __construct($pendser, $jenisLaporan)
{
$this->pendser = $pendser;
$this->jenisLaporan = strtolower($jenisLaporan); // ✅ Convert to lowercase for array key matching
}
public function collection()
{
$data = collect($this->pendser);
// Calculate total amaun
$totalAmaun = $data->sum(function ($item) {
return $item['pendahuluan'] > 0 ? $item['pendahuluan'] : $item['serahan'];
});
// Append total row
$data->push([
'tarikh' => '',
'descpt' => '',
'teller' => 'JUMLAH KESELURUHAN',
'pendahuluan' => 0,
'serahan' => $totalAmaun,
]);
return $data;
}
// ✅ Set Title Row Above The Table
public function headings(): array
{
$reportTitles = [
'serahan' => 'LAPORAN SERAHAN KEPADA HQ',
'serahanv3' => 'LAPORAN SERAHAN KEPADA V3',
'pendahuluan' => 'LAPORAN PENDAHULUAN DARIPADA HQ',
'pendahuluanv3' => 'LAPORAN PENDAHULUAN DARIPADA V2',
'online' => 'LAPORAN SERAHAN KEPADA HQ (arrahnPay)',
'serahanlelong' => 'LAPORAN SERAHAN KEPADA HQ (arrahnBid)',
'serahanonline' => 'LAPORAN SERAHAN KESELURUHAN',
'all' => 'LAPORAN KESELURUHAN HQ'
];
// ✅ Use lowercase key for better matching
$title = $reportTitles[$this->jenisLaporan] ?? 'LAPORAN TIDAK DIKETAHUI';
return [
[$title], // Report title in the first row
['Bil', 'Tarikh', 'Keterangan', 'Nama', 'Amaun (RM)'], // Column headers
];
}
// ✅ Move Table Start Position (Avoid Overlapping with Title)
public function startCell(): string
{
return 'A2'; // Start table from row 2 to leave space for the title
}
// ✅ Map Data to Match the Columns
public function map($item): array
{
static $counter = 1;
static $totalAmaun = 0;
// Get amount (either "pendahuluan" or "serahan")
$amount = $item['pendahuluan'] > 0 ? $item['pendahuluan'] : $item['serahan'];
// Accumulate total amount
$totalAmaun += $amount;
// If this is the total row (JUMLAH KESELURUHAN), remove numbering
if ($item['teller'] === 'JUMLAH KESELURUHAN') {
return [
'', // Empty Bil column
'', // Empty Tarikh column
'', // Empty Keterangan column
strtoupper($item['teller']), // "JUMLAH KESELURUHAN" (Uppercase)
number_format($amount, 2), // Total Amount
];
}
return [
$counter++, // Bil
$item['tarikh'], // Date
$item['descpt'], // Description
$item['teller'], // Name
number_format($amount, 2), // Amount RM (Formatted)
];
}
// ✅ Set Title for Excel Tab Name
public function title(): string
{
return strtoupper($this->jenisLaporan ?? 'LAPORAN'); // Capitalize for better readability
}
public function styles(Worksheet $sheet)
{
// Set title and headers bold
$sheet->getStyle('A1')->getFont()->setBold(true)->setSize(16);
$sheet->getStyle('A2:E2')->getFont()->setBold(true)->setSize(12);
// Auto-size columns A to E
foreach (range('A', 'E') as $column) {
$sheet->getColumnDimension($column)->setAutoSize(true);
}
// Get last row index (total row)
$lastRow = $sheet->getHighestRow();
// Bold total row
$sheet->getStyle("A{$lastRow}:E{$lastRow}")->getFont()->setBold(true);
return [];
}
// ✅ Format Column E (Amaun) as a Number with 2 Decimal Places
public function columnFormats(): array
{
return [
'E' => NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED1, // ✅ Properly format numbers
];
}
}
+33 -41
View File
@@ -19,6 +19,7 @@ use App\Services\RingkasanHarianServices;
use App\Exports\Laporan\StokAuditBackdateExport;
use Maatwebsite\Excel\Facades\Excel;
use App\Exports\PendSerExport;
class AkaunController extends Controller
{
@@ -495,59 +496,50 @@ class AkaunController extends Controller
$api_url = $request->hostname;
$auth_user = Auth::user();
$current = Carbon::now();
$current = new Carbon();
$current = now();
$tarikh_cetak = $current->toDateString();
if($request->datemula == null){
$mula_date = '2017-01-01';
}else{
$split_date = explode('-', $request->datemula);
// $mula_date = $split_date[2] . '-' . $split_date[1] . '-' . $split_date[0];
$mula_date = $request->datemula;
}
$mula_date = $request->datemula ?? '2017-01-01';
$hingga_date = $request->datehingga ?? $current->toDateString();
if($request->datehingga == null){
$hingga_date = $current->toDateString();
}else{
$split_date = explode('-', $request->datehingga);
// $hingga_date = $split_date[2] . '-' . $split_date[1] . '-' . $split_date[0];
$hingga_date = $request->datehingga;
}
$pendser = Http::get($request->hostname . '/api/SenaraiPendSer/range/' . $request->kodcaw, [
'mula' => $mula_date,
'hingga' => $hingga_date,
'jenis' => $request->radpendser
])->json();
$pendser = Http::get($request->hostname. '/api/SenaraiPendSer/range/' . $request->kodcaw,['mula' => $mula_date,'hingga' => $hingga_date,'jenis' => $request->radpendser])->json();
$cawangan = Http::get($request->hostname . '/api/cawangan/detail/' . $request->kodcaw)->json();
$cawangan_detail = $cawangan[0];
$cawangan = Http::get($request->hostname.'/api/cawangan/detail/'.$request->kodcaw)->json();
$cawangan_detail=$cawangan[0];
// Define report title mappings
$reportTitles = [
'serahan' => 'Laporan_Serahan_HQ',
'pendahuluan' => 'Laporan_Pendahuluan_HQ',
'online' => 'Laporan_Serahan_Online_HQ',
'serahanlelong' => 'Laporan_Serahan_Lelong_HQ',
'serahanonline' => 'Laporan_Serahan_Dan_Serahan_Online_HQ',
'all' => 'Laporan_Keseluruhan_HQ'
];
if(isset($request->jenis))
{
$jenisLaporan = $request->radpendser; // Get report type
// Get the correct report title
$jenisLaporan = $request->radpendser;
$fileTitle = $reportTitles[$jenisLaporan] ?? 'Laporan_Tidak_Diketahui';
if($request->jenis == 'pdf')
{
if (isset($request->jenis)) {
if ($request->jenis == 'pdf') {
$pdf = PDF::loadView('akaun.laporan_pendahuluanserahan', compact(
'pendser',
'cawangan_detail',
'tarikh_cetak',
'mula_date',
'hingga_date',
'api_url',
'jenisLaporan' // Pass the report type
'pendser', 'cawangan_detail', 'tarikh_cetak', 'mula_date', 'hingga_date', 'api_url', 'jenisLaporan'
))->setPaper('a4', 'portrait');
return $pdf->download('laporan_HQ_' . $request->kodcaw . '_' . $mula_date . '_' . $jenisLaporan . '.pdf');
return $pdf->download($fileTitle . '_' . $request->kodcaw . '_' . $mula_date . '.pdf');
}
else
{
else if ($request->jenis == 'excel') {
return Excel::download(new PendSerExport($pendser, $jenisLaporan), $fileTitle . '_' . $request->kodcaw . '_' . $mula_date . '.xlsx');
}
else {
return view('akaun.laporan_pendahuluanserahan', compact(
'pendser',
'cawangan_detail',
'tarikh_cetak',
'mula_date',
'hingga_date',
'api_url',
'jenisLaporan' // Pass the report type to the view
'pendser', 'cawangan_detail', 'tarikh_cetak', 'mula_date', 'hingga_date', 'api_url', 'jenisLaporan'
));
}
}
+123 -131
View File
@@ -1,132 +1,124 @@
<template>
<div class="container">
<div class="flex w-100%">
<div class="xl:w-10/9 2xl:w-8/9 p-12 mx-auto">
<div class="bg-yellow-600 text-gray-200 text-lg px-6 py-4 rounded-t-lg">
<router-link to="/akaunhome">
<i class="fas fa-backspace text-white"></i>
</router-link>
<span class="text-center mx-auto text-white font-bold">Laporan Pendahuluan & Serahan</span>
</div>
<form method="get" id="formpendser" :action="Urlredirect()" target="_blank">
<input :value="$kodcaw" name="kodcaw" hidden/>
<div class="rounded bg-white shadow p-6">
<div class="pb-6">
<!-- <label for="username" class="font-semibold text-gray-700 block pb-1">Tarikh</label> -->
<div class="flex place-content-center mb-2">
<input :value="jenisgenerate" type="hidden" name="jenis" />
<input :value="$hostname" name="hostname" hidden/>
<input :value="$kodcaw" name="kodcaw" hidden/>
<span style="background-color: #F9FAFB" class="text-gray-600 border border-2 rounded-l px-4 py-2 whitespace-no-wrap">Mula</span>
<input id="tarikhmula" name="datemula" class="border border-2 border-l-0 rounded-r px-4 py-2 w-80r mr-2" type="date" />
<span style="background-color: #F9FAFB" class="text-gray-600 border border-2 rounded-l px-4 py-2 whitespace-no-wrap">Hingga</span>
<input id="tarikhmula" name="datehingga" class="border border-2 border-l-0 rounded-r px-4 py-2 w-80r mr-2" type="date" />
</div>
</div>
<div class="flex flex-wrap justify-end mt-10">
<div class="mx-2 radio">
<input type="radio" id="pendahuluan" name="radpendser" value="pendahuluan" class="hidden focus:bg-gray-500" v-model="selected">
<label for="pendahuluan" class="cursor-pointer text-gray-500 focus:bg-gray-500 hover:bg-gray-200 focus:bg-purple-500 focus:bg-purple-500 focus:outline-none border px-10 py-4 border-solid border-gray-500 rounded">Pendahuluan</label>
</div>
<div class="mx-2 radio cursor-pointer">
<input type="radio" id="serahan" name="radpendser" value="serahan" class="hidden focus:bg-gray-500" v-model="selected">
<label for="serahan" class="cursor-pointer text-gray-500 focus:bg-gray-500 hover:bg-gray-200 focus:bg-purple-500 focus:outline-none border px-10 py-4 border-solid border-gray-500 rounded">Serahan</label>
</div>
<div class="mx-2 radio cursor-pointer">
<input type="radio" id="online" name="radpendser" value="online" class="hidden focus:bg-gray-500" v-model="selected">
<label for="online" class="cursor-pointer text-gray-500 focus:bg-gray-500 hover:bg-gray-200 focus:bg-purple-500 focus:outline-none border px-10 py-4 border-solid border-gray-500 rounded">Serahan Online</label>
</div>
<div class="mx-2 radio cursor-pointer">
<input type="radio" id="serahanlelong" name="radpendser" value="serahanlelong" class="hidden focus:bg-gray-500" v-model="selected">
<label for="serahanlelong" class="cursor-pointer text-gray-500 focus:bg-gray-500 hover:bg-gray-200 focus:bg-purple-500 focus:outline-none border px-10 py-4 border-solid border-gray-500 rounded">Serahan Lelong</label>
</div>
<div class="mx-2 radio cursor-pointer">
<input type="radio" id="serahanonline" name="radpendser" value="serahanonline" class="hidden focus:bg-gray-500" v-model="selected">
<label for="serahanonline" class="cursor-pointer text-gray-500 focus:bg-gray-500 hover:bg-gray-200 focus:bg-purple-500 focus:outline-none border px-10 py-4 border-solid border-gray-500 rounded">Serahan All</label>
</div>
<div class="mx-2 radio cursor-pointer">
<input type="radio" id="all" name="radpendser" value="all" class="hidden focus:bg-gray-500" v-model="selected">
<label for="all" class="cursor-pointer text-gray-500 focus:bg-gray-500 hover:bg-gray-200 focus:bg-purple-500 focus:outline-none border px-10 py-4 border-solid border-gray-500 rounded">All</label>
</div>
</div>
<div class="flex justify-end mt-10">
<button @click.prevent="generatepdf" class="mr-2 border border-yellow-600 text-yellow-600 font-montserrat py-2 px-8 font-medium rounded-xl hover:bg-yellow-600 hover:text-white transition-all duration-300 w-full sm:w-auto">
<i class="fas fa-file-pdf mr-2"></i>PDF
</button>
<button @click.prevent="generateview" class="border border-yellow-600 text-yellow-600 font-montserrat py-2 px-8 font-medium rounded-xl hover:bg-yellow-600 hover:text-white transition-all duration-300 w-full sm:w-auto">
<i class="fas fa-eye mr-2"></i>View
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</template>
<style>
.radio input:checked + label{
border-color:#F6D860;
background-color:#FFF1BD;
outline:none;
}
</style>
<script>
export default {
data(){
return{
jenisgenerate:'none',
selected:'',
kodcaw:''
}
},
methods: {
async generatepdf(){
await this.setJenis('pdf');
Vue.swal({
title: 'Memuatkan...',
allowEscapeKey : false,
allowOutsideClick: false,
showCancelButton: false,
showConfirmButton: false,
timer: 8000,
});
document.getElementById("formpendser").submit();
},
async generateview(){
await this.setJenis('view');
Vue.swal({
title: 'Memuatkan...',
allowEscapeKey : false,
allowOutsideClick: false,
showCancelButton: false,
showConfirmButton: false,
timer: 8000,
});
document.getElementById("formpendser").submit();
},
Urlredirect: function() {
return window.route('cetak.pendser')
},
setJenis: function(value){
return this.jenisgenerate = value;
}
}
}
</script>
<div class="container">
<div class="flex w-100%">
<div class="xl:w-10/9 2xl:w-8/9 p-12 mx-auto">
<div class="bg-yellow-600 text-gray-200 text-lg px-6 py-4 rounded-t-lg">
<router-link to="/akaunhome">
<i class="fas fa-backspace text-white"></i>
</router-link>
<span class="text-center mx-auto text-white font-bold">Laporan Pendahuluan & Serahan</span>
</div>
<form method="get" id="formpendser" :action="Urlredirect()" target="_blank">
<input :value="$kodcaw" name="kodcaw" hidden/>
<div class="rounded bg-white shadow p-6">
<div class="pb-6">
<div class="flex place-content-center mb-2">
<input :value="jenisgenerate" type="hidden" name="jenis" />
<input :value="$hostname" name="hostname" hidden/>
<input :value="$kodcaw" name="kodcaw" hidden/>
<span style="background-color: #F9FAFB" class="text-gray-600 border border-2 rounded-l px-4 py-2 whitespace-no-wrap">Mula</span>
<input id="tarikhmula" name="datemula" class="border border-2 border-l-0 rounded-r px-4 py-2 w-80r mr-2" type="date" />
<span style="background-color: #F9FAFB" class="text-gray-600 border border-2 rounded-l px-4 py-2 whitespace-no-wrap">Hingga</span>
<input id="tarikhhingga" name="datehingga" class="border border-2 border-l-0 rounded-r px-4 py-2 w-80r mr-2" type="date" />
</div>
</div>
<!-- Dropdown Selection -->
<div class="mt-6 text-center">
<label for="laporanType" class="text-gray-700 font-semibold block mb-2">Pilih Jenis Laporan:</label>
<select id="laporanType" v-model="selected" name="radpendser" class="border border-gray-500 rounded px-4 py-2 w-full sm:w-auto">
<option value="pendahuluan">Pendahuluan</option>
<option value="pendahuluanv3">Pendahuluan Dari V2</option>
<option value="serahan">Serahan</option>
<option value="serahanv3">Serahan Kepada V3</option>
<option value="online">Serahan Online</option>
<option value="serahanlelong">Serahan Lelong</option>
<option value="serahanonline">Serahan All</option>
<option value="all">All</option>
</select>
</div>
<div class="flex justify-end mt-10">
<!-- PDF Button -->
<button @click.prevent="generatepdf" class="mr-2 border border-yellow-600 text-yellow-600 font-montserrat py-2 px-6 font-medium rounded-xl hover:bg-yellow-600 hover:text-white transition-all duration-300 w-full sm:w-auto">
<i class="fas fa-file-pdf mr-2"></i>PDF
</button>
<!-- View Button -->
<button @click.prevent="generateview" class="mr-2 border border-yellow-600 text-yellow-600 font-montserrat py-2 px-6 font-medium rounded-xl hover:bg-yellow-600 hover:text-white transition-all duration-300 w-full sm:w-auto">
<i class="fas fa-eye mr-2"></i>View
</button>
<!-- Excel Button -->
<button @click.prevent="generateExcel" class="border border-green-600 text-green-600 font-montserrat py-2 px-6 font-medium rounded-xl hover:bg-green-600 hover:text-white transition-all duration-300 w-full sm:w-auto">
<i class="fas fa-file-excel mr-2"></i>Excel
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
jenisgenerate: 'none',
selected: '', // This now binds to the dropdown
kodcaw: ''
}
},
methods: {
async generatepdf() {
await this.setJenis('pdf');
Vue.swal({
title: 'Memuatkan...',
allowEscapeKey: false,
allowOutsideClick: false,
showCancelButton: false,
showConfirmButton: false,
timer: 8000,
});
document.getElementById("formpendser").submit();
},
async generateview() {
await this.setJenis('view');
Vue.swal({
title: 'Memuatkan...',
allowEscapeKey: false,
allowOutsideClick: false,
showCancelButton: false,
showConfirmButton: false,
timer: 8000,
});
document.getElementById("formpendser").submit();
},
async generateExcel() {
await this.setJenis('excel');
Vue.swal({
title: 'Memuatkan...',
allowEscapeKey: false,
allowOutsideClick: false,
showCancelButton: false,
showConfirmButton: false,
timer: 8000,
});
document.getElementById("formpendser").submit();
},
Urlredirect() {
return window.route('cetak.pendser') // Ensure your backend supports Excel export
},
setJenis(value) {
this.jenisgenerate = value;
}
}
}
</script>
@@ -173,12 +173,14 @@
<br>
@php
$reportNames = [
'serahan' => 'LAPORAN SERAHAN HQ',
'pendahuluan' => 'LAPORAN PENDAHULUAN HQ',
'online' => 'LAPORAN SERAHAN ONLINE HQ',
'serahanlelong' => 'LAPORAN SERAHAN LELONG HQ',
'serahanonline' => 'LAPORAN SERAHAN DAN SERAHAN ONLINE HQ',
'all' => 'LAPORAN KESELURUHAN HQ'
'serahan' => 'LAPORAN SERAHAN KEPADA HQ',
'serahanv3' => 'LAPORAN SERAHAN KEPADA V3',
'pendahuluan' => 'LAPORAN PENDAHULUAN DARIPADA HQ',
'pendahuluanv3' => 'LAPORAN PENDAHULUAN DARIPADA V2',
'online' => 'LAPORAN SERAHAN KEPADA HQ (arrahnPay)',
'serahanlelong' => 'LAPORAN SERAHAN KEPADA HQ (arrahnBid)',
'serahanonline' => 'LAPORAN SERAHAN KESELURUHAN',
'all' => 'LAPORAN KESELURUHAN HQ'
];
$displayJenisLaporan = $reportNames[$jenisLaporan] ?? 'Laporan Tidak Diketahui';