Export Excel Invoice & Imporve Invoice
This commit is contained in:
23
app/Exports/ReportExport.php
Normal file
23
app/Exports/ReportExport.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exports;
|
||||
|
||||
use App\Exports\Sheets\Invoices\VOPSheet;
|
||||
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
|
||||
use App\Exports\Sheets\UsersSheet;
|
||||
use App\Exports\Sheets\OrdersSheet;
|
||||
|
||||
class ReportExport implements WithMultipleSheets
|
||||
{
|
||||
protected array $filters;
|
||||
public function __construct(array $filters = [])
|
||||
{
|
||||
$this->filters = $filters;
|
||||
}
|
||||
public function sheets(): array
|
||||
{
|
||||
return [
|
||||
new VOPSheet($this->filters),
|
||||
];
|
||||
}
|
||||
}
|
||||
349
app/Exports/Sheets/Invoices/VOPSheet.php
Normal file
349
app/Exports/Sheets/Invoices/VOPSheet.php
Normal file
@@ -0,0 +1,349 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exports\Sheets\Invoices;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\{
|
||||
Cell,
|
||||
DataType,
|
||||
StringValueBinder
|
||||
};
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
use Maatwebsite\Excel\Concerns\{
|
||||
FromCollection,
|
||||
WithHeadings,
|
||||
WithMapping,
|
||||
WithTitle,
|
||||
WithCustomValueBinder,
|
||||
WithEvents
|
||||
};
|
||||
use Maatwebsite\Excel\Events\AfterSheet;
|
||||
|
||||
class VOPSheet extends StringValueBinder implements
|
||||
FromCollection,
|
||||
WithHeadings,
|
||||
WithMapping,
|
||||
WithTitle,
|
||||
WithCustomValueBinder,
|
||||
WithEvents
|
||||
{
|
||||
protected array $filters;
|
||||
protected int $no = 0;
|
||||
protected float $grandTotal = 0;
|
||||
|
||||
protected array $benefits = [];
|
||||
|
||||
protected $benefitAmounts;
|
||||
|
||||
protected bool $benefitInitialized = false;
|
||||
|
||||
|
||||
public function __construct(array $filters = [])
|
||||
{
|
||||
$this->filters = $filters;
|
||||
}
|
||||
|
||||
public function collection()
|
||||
{
|
||||
$query = DB::table('invoice_payments')
|
||||
->leftJoin('invoice_payment_details', 'invoice_payment_details.invoice_payment_id', '=', 'invoice_payments.id')
|
||||
->leftJoin('claim_requests', 'claim_requests.id', '=', 'invoice_payment_details.claim_request_id')
|
||||
->leftJoin('request_logs', 'request_logs.id', '=', 'claim_requests.request_log_id')
|
||||
->leftJoin('organizations', 'organizations.id', '=', 'request_logs.organization_id')
|
||||
->leftJoin('members', 'members.id', '=', 'request_logs.member_id')
|
||||
->leftJoin('specialities', 'specialities.id', '=', 'request_logs.specialities_id')
|
||||
->leftJoin('icd', DB::raw("icd.code"), '=', DB::raw("SUBSTRING_INDEX(request_logs.diagnosis, ',', 1)"))
|
||||
->orderBy('request_logs.service_code', 'desc')
|
||||
->select(
|
||||
'invoice_payments.*',
|
||||
'organizations.name as organization_name',
|
||||
'members.name as member_name',
|
||||
'request_logs.diagnosis as code_diagnosis',
|
||||
'request_logs.service_code',
|
||||
'request_logs.dppj',
|
||||
'specialities.name as specialities_name',
|
||||
'request_logs.submission_date as in',
|
||||
'request_logs.discharge_date as out',
|
||||
'request_logs.code as code_log',
|
||||
'members.payor_id',
|
||||
'request_logs.nominal as amount',
|
||||
'claim_requests.request_log_id',
|
||||
'members.member_id as batch_number',
|
||||
'request_logs.keterangan',
|
||||
'icd.name as diagnosis',
|
||||
'request_logs.type_of_member'
|
||||
);
|
||||
|
||||
|
||||
if (!empty($this->filters['search'])) {
|
||||
$query->where('invoice_number', 'like', '%' . $this->filters['search'] . '%');
|
||||
}
|
||||
|
||||
if (!empty($this->filters['start_date'])) {
|
||||
$query->whereDate('invoice_payments.created_at', '>=', $this->filters['start_date']);
|
||||
}
|
||||
|
||||
if (!empty($this->filters['end_date'])) {
|
||||
$query->whereDate('invoice_payments.created_at', '<=', $this->filters['end_date']);
|
||||
}
|
||||
|
||||
if (!empty($this->filters['orderBy'])) {
|
||||
$query->orderBy(
|
||||
$this->filters['orderBy'],
|
||||
$this->filters['order'] ?? 'asc'
|
||||
);
|
||||
}
|
||||
|
||||
$items = $query->get();
|
||||
|
||||
// ambil request_log_id
|
||||
$requestLogIds = $items
|
||||
->pluck('request_log_id')
|
||||
->filter()
|
||||
->unique()
|
||||
->values();
|
||||
|
||||
// set benefit header (hanya yg dipakai)
|
||||
$this->benefits = DB::table('request_log_benefits')
|
||||
->join('benefits', 'benefits.id', '=', 'request_log_benefits.benefit_id')
|
||||
->whereIn('request_log_benefits.request_log_id', $requestLogIds)
|
||||
->select('benefits.id', 'benefits.description')
|
||||
->distinct()
|
||||
->orderBy('benefits.id')
|
||||
->pluck('benefits.description', 'benefits.id')
|
||||
->toArray();
|
||||
|
||||
// 🔥 preload benefit amount SEKALI (anti N+1)
|
||||
$this->benefitAmounts = DB::table('request_log_benefits')
|
||||
->whereIn('request_log_id', $requestLogIds)
|
||||
->get()
|
||||
->groupBy('request_log_id');
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
public function map($item): array
|
||||
{
|
||||
$this->no++;
|
||||
$this->grandTotal += (float) $item->amount_paid;
|
||||
$benefitData = $this->getBenefitAmountsWithTotal($item->request_log_id);
|
||||
|
||||
return array_merge([
|
||||
// $this->no,
|
||||
(string) $item->invoice_number,
|
||||
// (string) $item->payment_number,
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
(string) $item->no_reference,
|
||||
'',
|
||||
'',
|
||||
(string) ($item->code_log ?? '-'),
|
||||
(string) ($item->payor_id ?? '-'),
|
||||
'',
|
||||
'',
|
||||
(string) ($item->organization_name ?? '-'),
|
||||
(string) ($item->member_name ?? '-'),
|
||||
(string) ($item->batch_number ?? '-'),
|
||||
(string) $benefitData['total'],
|
||||
'',
|
||||
'',
|
||||
],
|
||||
$benefitData['amounts'],
|
||||
[
|
||||
(string) ($item->in ?? '-'),
|
||||
(string) ($item->out ?? '-'),
|
||||
'',
|
||||
(string) ($item->diagnosis ?? '-'),
|
||||
(string) ($item->type_of_member ?? '-'), // omt
|
||||
(string) ($item->service_code == 'OP' ? 'RJ' : 'RI'),
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
(string) ($item->dppj ?? '-'),
|
||||
(string) ($item->in ?? '-'),
|
||||
(string) ($item->out ?? '-'),
|
||||
(string) ($item->specialities_name ?? '-'),
|
||||
'Karyawan',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
(string) ($item->keterangan ?? '-'),
|
||||
// (string) $item->invoice_date,
|
||||
// (string) $item->start_date,
|
||||
// (string) $item->end_date,
|
||||
// (float) $item->amount_paid,
|
||||
// (string) $item->created_at,
|
||||
// (string) $item->updated_at,
|
||||
]);
|
||||
}
|
||||
|
||||
public function headings(): array
|
||||
{
|
||||
$this->initBenefits();
|
||||
return array_merge([
|
||||
// 'No',
|
||||
'No Invoice', //ok
|
||||
// 'Pembayaran Ke',
|
||||
'MONTH', //ok
|
||||
'PERIODE SES', //ok
|
||||
'SUBMIT INV/SES', //ok
|
||||
'REFERENCE', //ok
|
||||
'RECEIVED', //ok
|
||||
'INV. DATE', //ok
|
||||
'CODE', //ok
|
||||
'VENDOR', //ok
|
||||
'PO', //ok
|
||||
'SES', //ok
|
||||
'MAIN DESCRIPTION', //ok
|
||||
'DESCRIPTION', //ok
|
||||
'BN', //ok
|
||||
'AMOUNT', //ok
|
||||
'WBS', // ok
|
||||
'NOTE', // ok
|
||||
],
|
||||
array_values($this->benefits),
|
||||
[ 'DEPARTURE', // ok
|
||||
'ARRIVED', // ok
|
||||
'TEMPORARY DIAGNOSA', // ok
|
||||
'FINAL DIAGNOSA',
|
||||
'NOTE (OMT / NON OMT)',
|
||||
'RI/RJ', // OK
|
||||
'Dept', // OK
|
||||
'Cost Center', // OK
|
||||
'No.TA', // OK
|
||||
'DPJP', // OK
|
||||
'IN', // OK
|
||||
'OUT', // OK
|
||||
'SPECIALIST', // OK
|
||||
'Employee', // OK
|
||||
'Total Invoice sebelum BPJS', // OK
|
||||
'BPJS', // OK
|
||||
'Ditanggung Perusahaan', // OK
|
||||
'KETERANGAN', // OK
|
||||
// 'Tanggal Invoice',
|
||||
// 'Start Date',
|
||||
// 'End Date',
|
||||
// 'Nominal Pembayaran',
|
||||
// 'Created At',
|
||||
// 'Updated At',
|
||||
]);
|
||||
}
|
||||
|
||||
public function title(): string
|
||||
{
|
||||
return 'VOP & VIP';
|
||||
}
|
||||
|
||||
/**
|
||||
* FOOTER: Grand Total
|
||||
*/
|
||||
public function registerEvents(): array
|
||||
{
|
||||
return [
|
||||
AfterSheet::class => function (AfterSheet $event) {
|
||||
// $event->sheet->getStyle('A1:AO1')
|
||||
// ->getFont()
|
||||
// ->setBold(true);
|
||||
|
||||
$highestColumn = $event->sheet->getDelegate()->getHighestColumn();
|
||||
|
||||
$event->sheet->getStyle('A1:' . $highestColumn . '1')
|
||||
->getFont()
|
||||
->setBold(true);
|
||||
|
||||
|
||||
// $row = $event->sheet->getHighestRow() + 1;
|
||||
|
||||
// $event->sheet->setCellValue("A{$row}", 'Grand Total');
|
||||
// $event->sheet->setCellValue("G{$row}", $this->grandTotal);
|
||||
|
||||
// // Bold footer
|
||||
// $event->sheet->getStyle("A{$row}:G{$row}")
|
||||
// ->getFont()
|
||||
// ->setBold(true);
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* FORCE: object → string
|
||||
*/
|
||||
public function bindValue(Cell $cell, $value)
|
||||
{
|
||||
if (is_object($value) || is_array($value)) {
|
||||
$value = json_encode($value);
|
||||
}
|
||||
|
||||
$cell->setValueExplicit($value, DataType::TYPE_STRING);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function getBenefitAmountsWithTotal(?int $requestLogId): array
|
||||
{
|
||||
if (!$requestLogId || !isset($this->benefitAmounts[$requestLogId])) {
|
||||
return [
|
||||
'amounts' => array_fill(0, count($this->benefits), 0),
|
||||
'total' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
$rows = $this->benefitAmounts[$requestLogId]
|
||||
->pluck('amount_approved', 'benefit_id')
|
||||
->toArray();
|
||||
|
||||
$amounts = [];
|
||||
$total = 0;
|
||||
|
||||
foreach ($this->benefits as $benefitId => $desc) {
|
||||
$amount = (float) ($rows[$benefitId] ?? 0);
|
||||
$amounts[] = $amount;
|
||||
$total += $amount;
|
||||
}
|
||||
|
||||
// 🔥 kalau ini memang mau jadi grand total global
|
||||
$this->grandTotal += $total;
|
||||
|
||||
return [
|
||||
'amounts' => $amounts,
|
||||
'total' => $total,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
protected function initBenefits(): void
|
||||
{
|
||||
if ($this->benefitInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ambil request_log_id dulu
|
||||
$requestLogIds = DB::table('invoice_payments')
|
||||
->leftJoin('invoice_payment_details', 'invoice_payment_details.invoice_payment_id', '=', 'invoice_payments.id')
|
||||
->leftJoin('claim_requests', 'claim_requests.id', '=', 'invoice_payment_details.claim_request_id')
|
||||
->whereNotNull('claim_requests.request_log_id')
|
||||
->pluck('claim_requests.request_log_id')
|
||||
->unique()
|
||||
->values();
|
||||
|
||||
if ($requestLogIds->isEmpty()) {
|
||||
$this->benefits = [];
|
||||
return;
|
||||
}
|
||||
|
||||
$this->benefits = DB::table('request_log_benefits')
|
||||
->join('benefits', 'benefits.id', '=', 'request_log_benefits.benefit_id')
|
||||
->whereIn('request_log_benefits.request_log_id', $requestLogIds)
|
||||
->select('benefits.id', 'benefits.description')
|
||||
->distinct()
|
||||
->orderBy('benefits.id')
|
||||
->pluck('benefits.description', 'benefits.id')
|
||||
->toArray();
|
||||
|
||||
$this->benefitInitialized = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
14
app/Services/ExportExcelService.php
Normal file
14
app/Services/ExportExcelService.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Exports\ReportExport;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
|
||||
class ExportExcelService
|
||||
{
|
||||
public function exportReport(array $filters = [], string $filename = 'report.xlsx')
|
||||
{
|
||||
return Excel::download(new ReportExport($filters), $filename);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user