xlsx output
This commit is contained in:
parent
b78ba2b1fc
commit
ef36f8d1e4
|
|
@ -34,8 +34,20 @@ class ReportExportController extends BaseController
|
||||||
return response()->json(['message' => 'Still working.....'], 409);
|
return response()->json(['message' => 'Still working.....'], 409);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$report = base64_decode($report);
|
||||||
|
|
||||||
Cache::forget($hash);
|
Cache::forget($hash);
|
||||||
|
|
||||||
|
if($this->isXlsxData($report)){
|
||||||
|
|
||||||
|
return response($report, 200, [
|
||||||
|
'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||||
|
'Content-Disposition' => 'inline; filename="report.xlsx"',
|
||||||
|
'Content-Length' => strlen($report)
|
||||||
|
]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the content starts with PDF signature (%PDF-)
|
// Check if the content starts with PDF signature (%PDF-)
|
||||||
$isPdf = str_starts_with(trim($report), '%PDF-');
|
$isPdf = str_starts_with(trim($report), '%PDF-');
|
||||||
|
|
||||||
|
|
@ -55,4 +67,23 @@ class ReportExportController extends BaseController
|
||||||
}, $attachment_name, $headers);
|
}, $attachment_name, $headers);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function isXlsxData($fileData)
|
||||||
|
{
|
||||||
|
// Check minimum size (XLSX files are typically > 1KB)
|
||||||
|
if (strlen($fileData) < 1024) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check ZIP signature
|
||||||
|
$header = substr($fileData, 0, 4);
|
||||||
|
if ($header !== 'PK' . chr(3) . chr(4)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for XLSX-specific content
|
||||||
|
return strpos($fileData, '[Content_Types].xml') !== false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ class PreviewReport implements ShouldQueue
|
||||||
$report = $export->run();
|
$report = $export->run();
|
||||||
}
|
}
|
||||||
|
|
||||||
Cache::put($this->hash, $report, 60 * 60);
|
Cache::put($this->hash, base64_encode($report), 60 * 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
// public function middleware()
|
// public function middleware()
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
namespace App\Services\Report;
|
namespace App\Services\Report;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
use App\Utils\Number;
|
use App\Utils\Number;
|
||||||
|
|
@ -21,15 +22,14 @@ use App\Models\Company;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Libraries\MultiDB;
|
use App\Libraries\MultiDB;
|
||||||
use App\Export\CSV\BaseExport;
|
use App\Export\CSV\BaseExport;
|
||||||
|
use App\Models\TransactionEvent;
|
||||||
use App\Utils\Traits\MakesDates;
|
use App\Utils\Traits\MakesDates;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
use App\Services\Template\TemplateService;
|
|
||||||
use Carbon\Carbon;
|
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
use App\Models\Invoice;
|
use App\Services\Template\TemplateService;
|
||||||
use App\Listeners\Invoice\InvoiceTransactionEventEntry;
|
use App\Listeners\Invoice\InvoiceTransactionEventEntry;
|
||||||
use App\Models\TransactionEvent;
|
use App\Listeners\Invoice\InvoiceTransactionEventEntryCash;
|
||||||
|
|
||||||
|
|
||||||
class TaxPeriodReport extends BaseExport
|
class TaxPeriodReport extends BaseExport
|
||||||
|
|
@ -44,8 +44,8 @@ class TaxPeriodReport extends BaseExport
|
||||||
|
|
||||||
private string $number_format;
|
private string $number_format;
|
||||||
|
|
||||||
//is_income_billed = accrual
|
private bool $cash_accounting = false;
|
||||||
//!is_invoice_billed = cash
|
|
||||||
/**
|
/**
|
||||||
@param array $input
|
@param array $input
|
||||||
[
|
[
|
||||||
|
|
@ -68,10 +68,24 @@ class TaxPeriodReport extends BaseExport
|
||||||
$t = app('translator');
|
$t = app('translator');
|
||||||
$t->replace(Ninja::transformTranslations($this->company->settings));
|
$t->replace(Ninja::transformTranslations($this->company->settings));
|
||||||
|
|
||||||
$this->calculateDateRange()
|
$this->spreadsheet = new Spreadsheet();
|
||||||
->initializeData()
|
|
||||||
->buildData();
|
|
||||||
|
|
||||||
|
return
|
||||||
|
$this->setAccountingType()
|
||||||
|
->setCurrencyFormat()
|
||||||
|
->calculateDateRange()
|
||||||
|
->initializeData()
|
||||||
|
->buildData()
|
||||||
|
->writeToSpreadsheet()
|
||||||
|
->getXlsFile();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private function setAccountingType(): self
|
||||||
|
{
|
||||||
|
$this->cash_accounting = $this->input['is_income_billed'] ? false : true;
|
||||||
|
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -96,7 +110,20 @@ class TaxPeriodReport extends BaseExport
|
||||||
(new InvoiceTransactionEventEntry())->run($invoice, \Carbon\Carbon::parse($invoice->date)->endOfMonth()->format('Y-m-d'));
|
(new InvoiceTransactionEventEntry())->run($invoice, \Carbon\Carbon::parse($invoice->date)->endOfMonth()->format('Y-m-d'));
|
||||||
}
|
}
|
||||||
elseif(in_array($invoice->status_id, [Invoice::STATUS_PAID, Invoice::STATUS_PARTIAL])){
|
elseif(in_array($invoice->status_id, [Invoice::STATUS_PAID, Invoice::STATUS_PARTIAL])){
|
||||||
|
|
||||||
|
//Harvest point in time records for cash payments.
|
||||||
|
\App\Models\Paymentable::where('paymentable_type', 'invoices')
|
||||||
|
->whereIn('payment_id', $invoice->payments->pluck('id'))
|
||||||
|
->get()
|
||||||
|
->groupBy(function ($paymentable) {
|
||||||
|
return $paymentable->paymentable_id . '-' . \Carbon\Carbon::parse($paymentable->created_at)->format('Y-m');
|
||||||
|
})
|
||||||
|
->map(function ($group) {
|
||||||
|
return $group->first();
|
||||||
|
})->each(function ($pp){
|
||||||
|
(new InvoiceTransactionEventEntryCash())->run($pp->paymentable, \Carbon\Carbon::parse($pp->created_at)->startOfMonth()->format('Y-m-d'), \Carbon\Carbon::parse($pp->created_at)->endOfMonth()->format('Y-m-d'));
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -111,21 +138,25 @@ class TaxPeriodReport extends BaseExport
|
||||||
->where('company_id', $this->company->id)
|
->where('company_id', $this->company->id)
|
||||||
->where('is_deleted', 0);
|
->where('is_deleted', 0);
|
||||||
|
|
||||||
if($this->input['is_income_billed']) //acrrual
|
if($this->cash_accounting) //accrual
|
||||||
{
|
|
||||||
$query->whereIn('status_id', [2,3,4])
|
|
||||||
->whereHas('transaction_events', function($query){
|
|
||||||
$query->where('event_id', TransactionEvent::INVOICE_UPDATED)
|
|
||||||
->whereBetween('period', [$this->start_date, $this->end_date]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else //cash
|
|
||||||
{
|
{
|
||||||
|
|
||||||
$query->whereIn('status_id', [3,4])
|
$query->whereIn('status_id', [3,4])
|
||||||
->whereHas('transaction_events', function($query){
|
->whereHas('transaction_events', function ($query) {
|
||||||
$query->where('event_id', TransactionEvent::PAYMENT_CASH)
|
$query->where('event_id', TransactionEvent::PAYMENT_CASH)
|
||||||
->whereBetween('period', [$this->start_date, $this->end_date]);
|
->whereBetween('period', [$this->start_date, $this->end_date]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
else //cash
|
||||||
|
{
|
||||||
|
|
||||||
|
$query->whereIn('status_id', [2,3,4])
|
||||||
|
->whereHas('transaction_events', function ($query) {
|
||||||
|
$query->where('event_id', TransactionEvent::INVOICE_UPDATED)
|
||||||
|
->whereBetween('period', [$this->start_date, $this->end_date]);
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$query->orderBy('balance', 'desc');
|
$query->orderBy('balance', 'desc');
|
||||||
|
|
@ -142,7 +173,7 @@ class TaxPeriodReport extends BaseExport
|
||||||
private function calculateDateRange(): self
|
private function calculateDateRange(): self
|
||||||
{
|
{
|
||||||
|
|
||||||
switch ($date_range) {
|
switch ($this->input['date_range']) {
|
||||||
case 'last7':
|
case 'last7':
|
||||||
case 'last30':
|
case 'last30':
|
||||||
case 'this_month':
|
case 'this_month':
|
||||||
|
|
@ -202,21 +233,6 @@ class TaxPeriodReport extends BaseExport
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function accrual()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function cash()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getXlsFile()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function setCurrencyFormat()
|
public function setCurrencyFormat()
|
||||||
{
|
{
|
||||||
$currency = $this->company->currency();
|
$currency = $this->company->currency();
|
||||||
|
|
@ -231,6 +247,15 @@ class TaxPeriodReport extends BaseExport
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function writeToSpreadsheet()
|
||||||
|
{
|
||||||
|
$this->createSummarySheet()
|
||||||
|
->createInvoiceSummarySheet();
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function createSummarySheet()
|
public function createSummarySheet()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -249,7 +274,7 @@ class TaxPeriodReport extends BaseExport
|
||||||
|
|
||||||
$worksheet = $this->spreadsheet->createSheet();
|
$worksheet = $this->spreadsheet->createSheet();
|
||||||
$worksheet->setTitle(ctrans('texts.invoice')." ".ctrans('texts.cash_vs_accrual'));
|
$worksheet->setTitle(ctrans('texts.invoice')." ".ctrans('texts.cash_vs_accrual'));
|
||||||
$worksheet->fromArray($this->data['accrual']['invoices'], null, 'A1');
|
$worksheet->fromArray($this->data['invoices'], null, 'A1');
|
||||||
|
|
||||||
$worksheet->getStyle('B:B')->getNumberFormat()->setFormatCode($this->company->date_format()); // Invoice date column
|
$worksheet->getStyle('B:B')->getNumberFormat()->setFormatCode($this->company->date_format()); // Invoice date column
|
||||||
$worksheet->getStyle('C:C')->getNumberFormat()->setFormatCode($this->currency_format); // Invoice total column
|
$worksheet->getStyle('C:C')->getNumberFormat()->setFormatCode($this->currency_format); // Invoice total column
|
||||||
|
|
@ -265,7 +290,7 @@ class TaxPeriodReport extends BaseExport
|
||||||
|
|
||||||
$worksheet = $this->spreadsheet->createSheet();
|
$worksheet = $this->spreadsheet->createSheet();
|
||||||
$worksheet->setTitle(ctrans('texts.invoice_item')." ".ctrans('texts.cash_vs_accrual'));
|
$worksheet->setTitle(ctrans('texts.invoice_item')." ".ctrans('texts.cash_vs_accrual'));
|
||||||
$worksheet->fromArray($this->data['accrual']['invoice_items'], null, 'A1');
|
$worksheet->fromArray($this->data['invoice_items'], null, 'A1');
|
||||||
|
|
||||||
$worksheet->getStyle('B:B')->getNumberFormat()->setFormatCode($this->company->date_format()); // Invoice date column
|
$worksheet->getStyle('B:B')->getNumberFormat()->setFormatCode($this->company->date_format()); // Invoice date column
|
||||||
$worksheet->getStyle('C:C')->getNumberFormat()->setFormatCode($this->currency_format); // Invoice total column
|
$worksheet->getStyle('C:C')->getNumberFormat()->setFormatCode($this->currency_format); // Invoice total column
|
||||||
|
|
@ -312,64 +337,41 @@ class TaxPeriodReport extends BaseExport
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
$this->data['accrual']['invoices'] = [$invoice_headers];
|
$this->data['invoices'] = [$invoice_headers];
|
||||||
$this->data['cash']['invoices'] = [$invoice_headers];
|
$this->data['invoice_items'] = [$invoice_item_headers];
|
||||||
$this->data['accrual']['invoice_items'] = [$invoice_item_headers];
|
|
||||||
$this->data['cash']['invoice_items'] = [$invoice_item_headers];
|
|
||||||
|
|
||||||
|
|
||||||
$query->cursor()
|
$query->cursor()
|
||||||
->each(function($invoice){
|
->each(function($invoice){
|
||||||
|
|
||||||
/** @var TransactionEvent $invoice_state */
|
/** @var TransactionEvent $state */
|
||||||
$invoice_state = $invoice->transaction_events()->where('event_id', TransactionEvent::INVOICE_UPDATED)->where('period', now()->endOfMonth()->format('Y-m-d'))->orderBy('timestamp', 'desc')->first();
|
$state = $invoice->transaction_events()->where('event_id', $this->cash_accounting ? TransactionEvent::PAYMENT_CASH : TransactionEvent::INVOICE_UPDATED)->whereBetween('period', [$this->start_date, $this->end_date])->orderBy('timestamp', 'desc')->first();
|
||||||
$payment_state = $invoice->transaction_events()->where('event_id', TransactionEvent::PAYMENT_CASH)->where('period', now()->endOfMonth()->format('Y-m-d'))->orderBy('timestamp', 'desc')->first();
|
$adjustments = $invoice->transaction_events()->whereIn('event_id',[TransactionEvent::PAYMENT_REFUNDED, TransactionEvent::PAYMENT_DELETED])->whereBetween('period', [$this->start_date, $this->end_date])->get();
|
||||||
$adjustments = $invoice->transaction_events()->whereIn('event_id',[TransactionEvent::PAYMENT_REFUNDED, TransactionEvent::PAYMENT_DELETED])->where('period', now()->endOfMonth()->format('Y-m-d'))->get();
|
|
||||||
|
|
||||||
|
|
||||||
if($invoice_state && $invoice_state->event_id == TransactionEvent::INVOICE_UPDATED){
|
$this->data['invoices'][] = [
|
||||||
$this->data['accrual']['invoices'][] = [
|
$invoice->number,
|
||||||
|
$invoice->date,
|
||||||
|
$invoice->amount,
|
||||||
|
$state->metadata->tax_report->payment_history?->sum('amount') ?? 0,
|
||||||
|
$state->metadata->tax_report->tax_summary->total_taxes,
|
||||||
|
$state->metadata->tax_report->tax_summary->total_paid,
|
||||||
|
'payable',
|
||||||
|
];
|
||||||
|
|
||||||
|
$_adjustments = [];
|
||||||
|
|
||||||
|
foreach($adjustments as $adjustment){
|
||||||
|
$_adjustments[] = [
|
||||||
$invoice->number,
|
$invoice->number,
|
||||||
$invoice->date,
|
$invoice->date,
|
||||||
$invoice->amount,
|
$invoice->amount,
|
||||||
|
$state->invoice_paid_to_date,
|
||||||
$invoice_state->metadata->tax_report->payment_history?->sum('amount') ?? 00,
|
$state->metadata->tax_report->tax_summary->total_taxes,
|
||||||
$invoice_state->metadata->tax_report->tax_summary->total_taxes,
|
$state->metadata->tax_report->tax_summary->adjustment,
|
||||||
$invoice_state->metadata->tax_report->tax_summary->total_paid,
|
'adjustment',
|
||||||
'payable',
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if($payment_state && $payment_state->event_id == TransactionEvent::PAYMENT_CASH){
|
$this->data['invoices'] = array_merge($this->data['invoices'], $_adjustments);
|
||||||
|
|
||||||
$this->data['cash']['invoices'][] = [
|
|
||||||
$invoice->number,
|
|
||||||
$invoice->date,
|
|
||||||
$invoice->amount,
|
|
||||||
|
|
||||||
$payment_state->metadata->tax_report->payment_history?->sum('amount') ?? 0,
|
|
||||||
$payment_state->metadata->tax_report->tax_summary->total_taxes,
|
|
||||||
$payment_state->metadata->tax_report->tax_summary->total_paid,
|
|
||||||
'payable',
|
|
||||||
];
|
|
||||||
|
|
||||||
}
|
|
||||||
$_adjustments = [];
|
|
||||||
|
|
||||||
foreach($adjustments as $adjustment){
|
|
||||||
$_adjustments[] = [
|
|
||||||
$invoice->number,
|
|
||||||
$invoice->date,
|
|
||||||
$invoice->amount,
|
|
||||||
$invoice_state->invoice_paid_to_date,
|
|
||||||
$invoice_state->metadata->tax_report->tax_summary->total_taxes,
|
|
||||||
$invoice_state->metadata->tax_report->tax_summary->adjustment,
|
|
||||||
'adjustment',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->data['accrual']['invoices'] = array_merge($this->data['accrual']['invoices'], $_adjustments);
|
|
||||||
$this->data['cash']['invoices'] = array_merge($this->data['cash']['invoices'], $_adjustments);
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue