312 lines
16 KiB
PHP
312 lines
16 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Incoming;
|
|
use App\Models\Invoice;
|
|
use App\Models\Payment;
|
|
use Illuminate\Database\Eloquent\Collection;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
|
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
|
use PhpOffice\PhpSpreadsheet\Style\Border;
|
|
use PhpOffice\PhpSpreadsheet\Style\NumberFormat\Wizard\Currency;
|
|
use PhpOffice\PhpSpreadsheet\Style\NumberFormat\Wizard\CurrencyBase;
|
|
use PhpOffice\PhpSpreadsheet\Style\NumberFormat\Wizard\Number;
|
|
use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
|
|
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
|
|
|
|
|
class ExcelController extends Controller
|
|
{
|
|
protected string $from;
|
|
protected string $end;
|
|
protected Xlsx $writer;
|
|
|
|
protected CurrencyBase $currencyMask;
|
|
|
|
public function export(Request $request): JsonResponse
|
|
{
|
|
$requestData = $request->validate([
|
|
'from' => 'required|date',
|
|
'end' => 'required|date',
|
|
'report' => 'required|in:invoice,payment,incoming,outgoing',
|
|
]);
|
|
|
|
$this->from = $requestData['from'];
|
|
$this->end = $requestData['end'];
|
|
$this->currencyMask = new Currency(
|
|
'€',
|
|
2,
|
|
Number::WITH_THOUSANDS_SEPARATOR,
|
|
Currency::TRAILING_SYMBOL,
|
|
Currency::SYMBOL_WITH_SPACING
|
|
);
|
|
|
|
switch ($requestData['report']) {
|
|
case 'invoice':
|
|
$this->invoice();
|
|
break;
|
|
case 'payment':
|
|
$this->payment();
|
|
break;
|
|
case 'incoming':
|
|
$this->incoming();
|
|
break;
|
|
case 'outgoing':
|
|
$this->outgoing();
|
|
break;
|
|
}
|
|
|
|
return response()->json($this->writer->save('php://output'));
|
|
}
|
|
|
|
protected function invoice(): void
|
|
{
|
|
$from = $this->from . ' 00:00:00';
|
|
$end = $this->end . ' 23:59:59';
|
|
$net = [];
|
|
$tax = [];
|
|
$gross = [];
|
|
|
|
$invoices = Invoice::whereBetween('created_at', [$from, $end])->where('status', '!=', 'created')->with(['address', 'customer'])->orderBy('created_at', 'desc')->get();
|
|
$spreadsheet = new Spreadsheet();
|
|
$worksheet = $spreadsheet->getActiveSheet();
|
|
$worksheet->setTitle(__('invoice.Invoices'));
|
|
$worksheet->getPageSetup()->setOrientation(PageSetup::ORIENTATION_LANDSCAPE);
|
|
$worksheet->getHeaderFooter()->setEvenHeader(__('invoice.Invoices from to', ['from' => $this->from, 'end' => $this->end]));
|
|
$worksheet->getHeaderFooter()->setOddHeader(__('invoice.Invoices from to', ['from' => $this->from, 'end' => $this->end]));
|
|
|
|
$worksheet->setCellValue('A1', __('invoice.Invoice Number'));
|
|
$worksheet->setCellValue('B1', __('customer.Customer'));
|
|
$worksheet->setCellValue('C1', __('common.Name'));
|
|
$worksheet->setCellValue('D1', __('invoice.Net'));
|
|
$worksheet->setCellValue('E1', __('invoice.Tax'));
|
|
$worksheet->setCellValue('F1', __('invoice.Gross'));
|
|
$worksheet->setCellValue('G1', __('common.Created at'));
|
|
$worksheet->getStyle('A1:G1')->getBorders()->getBottom()->applyFromArray(['borderStyle' => Border::BORDER_DOUBLE]);
|
|
$worksheet->getStyle('A1:G1')->getFont()->setBold(true);
|
|
$worksheet->getStyle('D1:G1')->getAlignment()->applyFromArray(['horizontal' => Alignment::HORIZONTAL_RIGHT]);
|
|
|
|
$row = 2;
|
|
foreach ($invoices as $invoice) {
|
|
foreach ($invoice->items as $item) {
|
|
if (!isset($net[$item->tax])) {
|
|
$net[$item->tax] = 0;
|
|
$tax[$item->tax] = 0;
|
|
$gross[$item->tax] = 0;
|
|
}
|
|
$net[$item->tax] += $item->amount * $item->price;
|
|
$tax[$item->tax] += $item->amount * $item->price * $item->tax / 100;
|
|
$gross[$item->tax] += $item->total;
|
|
}
|
|
$worksheet->setCellValue('A' . $row, $invoice->number);
|
|
$worksheet->setCellValue('B' . $row, $invoice->customer->name);
|
|
$worksheet->setCellValue('C' . $row, $invoice->address->name);
|
|
$worksheet->getCell('D' . $row)->getStyle()->getNumberFormat()->setFormatCode($this->currencyMask);
|
|
$worksheet->setCellValue('D' . $row, $invoice->sum - $invoice->tax);
|
|
$worksheet->getCell('E' . $row)->getStyle()->getNumberFormat()->setFormatCode($this->currencyMask);
|
|
$worksheet->setCellValue('E' . $row, $invoice->tax);
|
|
$worksheet->getCell('F' . $row)->getStyle()->getNumberFormat()->setFormatCode($this->currencyMask);
|
|
$worksheet->setCellValue('F' . $row, $invoice->sum);
|
|
$worksheet->setCellValue('G' . $row, Date::PHPToExcel(\DateTime::createFromFormat('!d.m.Y', $invoice->created)));
|
|
$worksheet->getCell('G' . $row)->getStyle()->getNumberFormat()->setFormatCode('dd.mm.yyyy');
|
|
$row++;
|
|
}
|
|
|
|
$worksheet->getStyle('A' . $row - 1 . ':G' . $row - 1)->getBorders()->getBottom()->applyFromArray(['borderStyle' => Border::BORDER_DOUBLE]);
|
|
|
|
foreach ($net as $tax_value => $amount) {
|
|
$worksheet->getStyle('A' . $row . ':G' . $row)->getFont()->setBold(true);
|
|
$worksheet->getStyle('D' . $row . ':G' . $row)->getAlignment()->applyFromArray(['horizontal' => Alignment::HORIZONTAL_RIGHT]);
|
|
$worksheet->setCellValue('B' . $row, __('invoice.Sails from vat', ['tax' => \Illuminate\Support\Number::percentage($tax_value)]));
|
|
$worksheet->getCell('D' . $row)->getStyle()->getNumberFormat()->setFormatCode($this->currencyMask);
|
|
$worksheet->setCellValue('D' . $row, $amount);
|
|
$worksheet->getCell('E' . $row)->getStyle()->getNumberFormat()->setFormatCode($this->currencyMask);
|
|
$worksheet->setCellValue('E' . $row, $tax[$tax_value]);
|
|
$worksheet->getCell('F' . $row)->getStyle()->getNumberFormat()->setFormatCode($this->currencyMask);
|
|
$worksheet->setCellValue('F' . $row, $gross[$tax_value]);
|
|
|
|
$row++;
|
|
}
|
|
|
|
foreach ($worksheet->getColumnIterator() as $column) {
|
|
$worksheet->getColumnDimension($column->getColumnIndex())->setAutoSize(true);
|
|
}
|
|
|
|
$this->writer = new Xlsx($spreadsheet);
|
|
}
|
|
|
|
protected function payment(): void
|
|
{
|
|
$net = [];
|
|
$tax = [];
|
|
$gross = [];
|
|
|
|
$payments = Payment::whereBetween('payment_date', [$this->from, $this->end])->with(['invoice'])->orderBy('payment_date', 'desc')->get();
|
|
$spreadsheet = new Spreadsheet();
|
|
$worksheet = $spreadsheet->getActiveSheet();
|
|
$worksheet->setTitle(__('invoice.Payments'));
|
|
$worksheet->getPageSetup()->setOrientation(PageSetup::ORIENTATION_LANDSCAPE);
|
|
$worksheet->getHeaderFooter()->setEvenHeader(__('invoice.Payments from to', ['from' => $this->from, 'end' => $this->end]));
|
|
$worksheet->getHeaderFooter()->setOddHeader(__('invoice.Payments from to', ['from' => $this->from, 'end' => $this->end]));
|
|
|
|
$worksheet->setCellValue('A1', __('invoice.Invoice Number'));
|
|
$worksheet->setCellValue('B1', __('customer.Customer'));
|
|
$worksheet->setCellValue('C1', __('common.Name'));
|
|
$worksheet->setCellValue('D1', __('invoice.Net'));
|
|
$worksheet->setCellValue('E1', __('invoice.Tax'));
|
|
$worksheet->setCellValue('F1', __('invoice.Gross'));
|
|
$worksheet->setCellValue('G1', __('invoice.Paid at'));
|
|
$worksheet->getStyle('A1:G1')->getBorders()->getBottom()->applyFromArray(['borderStyle' => Border::BORDER_DOUBLE]);
|
|
$worksheet->getStyle('A1:G1')->getFont()->setBold(true);
|
|
$worksheet->getStyle('D1:G1')->getAlignment()->applyFromArray(['horizontal' => Alignment::HORIZONTAL_RIGHT]);
|
|
|
|
$row = 2;
|
|
foreach ($payments as $payment) {
|
|
$invoice = $payment->invoice;
|
|
|
|
foreach ($invoice->items as $item) {
|
|
if (!isset($net[$item->tax])) {
|
|
$net[$item->tax] = 0;
|
|
$tax[$item->tax] = 0;
|
|
$gross[$item->tax] = 0;
|
|
}
|
|
$net[$item->tax] += $item->amount * $item->price * $payment->paid_amount / $invoice->sum;
|
|
$tax[$item->tax] += $item->amount * $item->price * $item->tax * $payment->paid_amount / ($invoice->sum * 100);
|
|
$gross[$item->tax] += $item->total * $payment->paid_amount / ($invoice->sum);
|
|
}
|
|
|
|
$worksheet->setCellValue('A' . $row, $invoice->number);
|
|
$worksheet->setCellValue('B' . $row, $invoice->customer->name);
|
|
$worksheet->setCellValue('C' . $row, $invoice->address->name);
|
|
$worksheet->getCell('D' . $row)->getStyle()->getNumberFormat()->setFormatCode($this->currencyMask);
|
|
$worksheet->setCellValue('D' . $row, ($invoice->sum - $invoice->tax) / ($invoice->sum / $payment->paid_amount));
|
|
$worksheet->getCell('E' . $row)->getStyle()->getNumberFormat()->setFormatCode($this->currencyMask);
|
|
$worksheet->setCellValue('E' . $row, $invoice->tax / ($invoice->sum / $payment->paid_amount));
|
|
$worksheet->getCell('F' . $row)->getStyle()->getNumberFormat()->setFormatCode($this->currencyMask);
|
|
$worksheet->setCellValue('F' . $row, $payment->paid_amount);
|
|
$worksheet->setCellValue('G' . $row, Date::PHPToExcel(\DateTime::createFromFormat('!Y-m-d', $payment->payment_date)));
|
|
$worksheet->getCell('G' . $row)->getStyle()->getNumberFormat()->setFormatCode('dd.mm.yyyy');
|
|
$row++;
|
|
}
|
|
|
|
$worksheet->getStyle('A' . $row - 1 . ':G' . $row - 1)->getBorders()->getBottom()->applyFromArray(['borderStyle' => Border::BORDER_DOUBLE]);
|
|
|
|
foreach ($net as $tax_value => $amount) {
|
|
$worksheet->getStyle('A' . $row . ':G' . $row)->getFont()->setBold(true);
|
|
$worksheet->getStyle('D' . $row . ':G' . $row)->getAlignment()->applyFromArray(['horizontal' => Alignment::HORIZONTAL_RIGHT]);
|
|
$worksheet->setCellValue('B' . $row, __('invoice.Sails from vat', ['tax' => \Illuminate\Support\Number::percentage($tax_value)]));
|
|
$worksheet->getCell('D' . $row)->getStyle()->getNumberFormat()->setFormatCode($this->currencyMask);
|
|
$worksheet->setCellValue('D' . $row, $amount);
|
|
$worksheet->getCell('E' . $row)->getStyle()->getNumberFormat()->setFormatCode($this->currencyMask);
|
|
$worksheet->setCellValue('E' . $row, $tax[$tax_value]);
|
|
$worksheet->getCell('F' . $row)->getStyle()->getNumberFormat()->setFormatCode($this->currencyMask);
|
|
$worksheet->setCellValue('F' . $row, $gross[$tax_value]);
|
|
|
|
$row++;
|
|
}
|
|
|
|
foreach ($worksheet->getColumnIterator() as $column) {
|
|
$worksheet->getColumnDimension($column->getColumnIndex())->setAutoSize(true);
|
|
}
|
|
|
|
$this->writer = new Xlsx($spreadsheet);
|
|
}
|
|
|
|
protected function incoming(): void
|
|
{
|
|
$incoming = Incoming::whereBetween('issue_date', [$this->from, $this->end])->with(['supplier', 'taxes'])->orderBy('issue_date', 'desc')->get();
|
|
$this->incomingToSheet($incoming);
|
|
}
|
|
|
|
protected function outgoing(): void
|
|
{
|
|
$incoming = Incoming::whereBetween('pay_date', [$this->from, $this->end])->with(['supplier', 'taxes'])->orderBy('pay_date', 'desc')->get();
|
|
$this->incomingToSheet($incoming);
|
|
}
|
|
|
|
protected function incomingToSheet(Collection $incoming): void
|
|
{
|
|
$net = [];
|
|
$tax = [];
|
|
$gross = [];
|
|
|
|
$spreadsheet = new Spreadsheet();
|
|
$worksheet = $spreadsheet->getActiveSheet();
|
|
$worksheet->setTitle(__('incoming.Incoming'));
|
|
$worksheet->getPageSetup()->setOrientation(PageSetup::ORIENTATION_LANDSCAPE);
|
|
$worksheet->getHeaderFooter()->setEvenHeader(__('incoming.Invoices from to', ['from' => $this->from, 'end' => $this->end]));
|
|
$worksheet->getHeaderFooter()->setOddHeader(__('incoming.Invoices from to', ['from' => $this->from, 'end' => $this->end]));
|
|
|
|
$worksheet->setCellValue('A1', __('invoice.Invoice Number'));
|
|
$worksheet->setCellValue('B1', __('customer.Customer'));
|
|
$worksheet->setCellValue('C1', __('common.Name'));
|
|
$worksheet->setCellValue('D1', __('invoice.Net'));
|
|
$worksheet->setCellValue('E1', __('invoice.Tax'));
|
|
$worksheet->setCellValue('F1', __('invoice.Gross'));
|
|
$worksheet->setCellValue('G1', __('common.Created at'));
|
|
$worksheet->setCellValue('H1', __('common.Paid at'));
|
|
$worksheet->getStyle('A1:H1')->getBorders()->getBottom()->applyFromArray(['borderStyle' => Border::BORDER_DOUBLE]);
|
|
$worksheet->getStyle('A1:H1')->getFont()->setBold(true);
|
|
$worksheet->getStyle('D1:H1')->getAlignment()->applyFromArray(['horizontal' => Alignment::HORIZONTAL_RIGHT]);
|
|
|
|
$row = 2;
|
|
foreach ($incoming as $invoice) {
|
|
foreach ($invoice->taxes as $item) {
|
|
if (!isset($net[$item->percentage])) {
|
|
$net[$item->percentage] = 0;
|
|
$tax[$item->percentage] = 0;
|
|
$gross[$item->percentage] = 0;
|
|
}
|
|
$net[$item->percentage] += $item->taxable_amount;
|
|
$tax[$item->percentage] += $item->amount;
|
|
$gross[$item->percentage] += $item->taxable_amount + $item->amount;
|
|
}
|
|
$worksheet->setCellValue('A' . $row, $invoice->invoice_number);
|
|
$worksheet->setCellValue('B' . $row, $invoice->supplier->name);
|
|
$worksheet->setCellValue('C' . $row, $invoice->supplier->email);
|
|
$worksheet->getCell('D' . $row)->getStyle()->getNumberFormat()->setFormatCode($this->currencyMask);
|
|
$worksheet->setCellValue('D' . $row, $invoice->net);
|
|
$worksheet->getCell('E' . $row)->getStyle()->getNumberFormat()->setFormatCode($this->currencyMask);
|
|
$worksheet->setCellValue('E' . $row, $invoice->tax);
|
|
$worksheet->getCell('F' . $row)->getStyle()->getNumberFormat()->setFormatCode($this->currencyMask);
|
|
$worksheet->setCellValue('F' . $row, $invoice->gross);
|
|
$worksheet->setCellValue('G' . $row, Date::PHPToExcel(\DateTime::createFromFormat('!Y-m-d', $invoice->issue_date)));
|
|
$worksheet->getCell('G' . $row)->getStyle()->getNumberFormat()->setFormatCode('dd.mm.yyyy');
|
|
if (is_null($invoice->pay_date)) {
|
|
$worksheet->setCellValue('H' . $row, '');
|
|
} else {
|
|
$worksheet->setCellValue('H' . $row, Date::PHPToExcel(\DateTime::createFromFormat('!Y-m-d', $invoice->pay_date)));
|
|
}
|
|
$worksheet->getCell('H' . $row)->getStyle()->getNumberFormat()->setFormatCode('dd.mm.yyyy');
|
|
$row++;
|
|
}
|
|
|
|
$worksheet->getStyle('A' . $row - 1 . ':H' . $row - 1)->getBorders()->getBottom()->applyFromArray(['borderStyle' => Border::BORDER_DOUBLE]);
|
|
|
|
foreach ($net as $tax_value => $amount) {
|
|
$worksheet->getStyle('A' . $row . ':G' . $row)->getFont()->setBold(true);
|
|
$worksheet->getStyle('D' . $row . ':G' . $row)->getAlignment()->applyFromArray(['horizontal' => Alignment::HORIZONTAL_RIGHT]);
|
|
$worksheet->setCellValue('B' . $row, __('invoice.Sails from vat', ['tax' => \Illuminate\Support\Number::percentage($tax_value)]));
|
|
$worksheet->getCell('D' . $row)->getStyle()->getNumberFormat()->setFormatCode($this->currencyMask);
|
|
$worksheet->setCellValue('D' . $row, $amount);
|
|
$worksheet->getCell('E' . $row)->getStyle()->getNumberFormat()->setFormatCode($this->currencyMask);
|
|
$worksheet->setCellValue('E' . $row, $tax[$tax_value]);
|
|
$worksheet->getCell('F' . $row)->getStyle()->getNumberFormat()->setFormatCode($this->currencyMask);
|
|
$worksheet->setCellValue('F' . $row, $gross[$tax_value]);
|
|
|
|
$row++;
|
|
}
|
|
|
|
foreach ($worksheet->getColumnIterator() as $column) {
|
|
$worksheet->getColumnDimension($column->getColumnIndex())->setAutoSize(true);
|
|
}
|
|
|
|
$this->writer = new Xlsx($spreadsheet);
|
|
}
|
|
}
|