Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

ExportService.php 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. <?php
  2. namespace App\Services;
  3. use App\Contracts\ExportableReport;
  4. use App\Models\Company;
  5. use App\Transformers\CashFlowStatementReportTransformer;
  6. use Barryvdh\Snappy\Facades\SnappyPdf;
  7. use Carbon\Exceptions\InvalidFormatException;
  8. use Illuminate\Support\Carbon;
  9. use League\Csv\Bom;
  10. use League\Csv\CannotInsertRecord;
  11. use League\Csv\Exception;
  12. use League\Csv\Writer;
  13. use Symfony\Component\HttpFoundation\StreamedResponse;
  14. class ExportService
  15. {
  16. public function exportToCsv(Company $company, ExportableReport $report, ?string $startDate = null, ?string $endDate = null): StreamedResponse
  17. {
  18. if ($startDate && $endDate) {
  19. $formattedStartDate = Carbon::parse($startDate)->toDateString();
  20. $formattedEndDate = Carbon::parse($endDate)->toDateString();
  21. $dateLabel = $formattedStartDate . ' to ' . $formattedEndDate;
  22. } else {
  23. $formattedAsOfDate = Carbon::parse($endDate)->toDateString();
  24. $dateLabel = $formattedAsOfDate;
  25. }
  26. $timestamp = Carbon::now()->format('Y-m-d_H-i-s');
  27. $filename = $company->name . ' ' . $report->getTitle() . ' ' . $dateLabel . ' ' . $timestamp . '.csv';
  28. $headers = [
  29. 'Content-Type' => 'text/csv',
  30. 'Content-Disposition' => 'attachment; filename="' . $filename . '"',
  31. ];
  32. $callback = function () use ($startDate, $endDate, $report, $company) {
  33. $csv = Writer::createFromStream(fopen('php://output', 'wb'));
  34. $csv->setOutputBOM(Bom::Utf8);
  35. if ($startDate && $endDate) {
  36. $defaultStartDateFormat = Carbon::parse($startDate)->toDefaultDateFormat();
  37. $defaultEndDateFormat = Carbon::parse($endDate)->toDefaultDateFormat();
  38. $dateLabel = 'Date Range: ' . $defaultStartDateFormat . ' to ' . $defaultEndDateFormat;
  39. } else {
  40. $dateLabel = 'As of ' . Carbon::parse($endDate)->toDefaultDateFormat();
  41. }
  42. $csv->insertOne([$report->getTitle()]);
  43. $csv->insertOne([$company->name]);
  44. $csv->insertOne([$dateLabel]);
  45. $csv->insertOne([]);
  46. $csv->insertOne($report->getHeaders());
  47. foreach ($report->getCategories() as $category) {
  48. $this->writeDataRowsToCsv($csv, $category->header, $category->data, $report->getColumns());
  49. foreach ($category->types ?? [] as $type) {
  50. $this->writeDataRowsToCsv($csv, $type->header, $type->data, $report->getColumns());
  51. if (filled($type->summary)) {
  52. $csv->insertOne($type->summary);
  53. }
  54. }
  55. if (filled($category->summary)) {
  56. $csv->insertOne($category->summary);
  57. }
  58. $csv->insertOne([]);
  59. }
  60. if ($report->getTitle() === 'Cash Flow Statement') {
  61. $this->writeOverviewTableToCsv($csv, $report);
  62. }
  63. if (filled($report->getOverallTotals())) {
  64. $csv->insertOne($report->getOverallTotals());
  65. }
  66. };
  67. return response()->streamDownload($callback, $filename, $headers);
  68. }
  69. /**
  70. * @throws CannotInsertRecord
  71. * @throws Exception
  72. */
  73. protected function writeOverviewTableToCsv(Writer $csv, ExportableReport $report): void
  74. {
  75. /** @var CashFlowStatementReportTransformer $report */
  76. $headers = $report->getOverviewHeaders();
  77. if (filled($headers)) {
  78. $csv->insertOne($headers);
  79. }
  80. foreach ($report->getOverview() as $overviewCategory) {
  81. if (filled($overviewCategory->header)) {
  82. $this->writeDataRowsToCsv($csv, $overviewCategory->header, $overviewCategory->data, $report->getColumns());
  83. }
  84. if (filled($overviewCategory->summary)) {
  85. $csv->insertOne($overviewCategory->summary);
  86. }
  87. if ($overviewCategory->header['account_name'] === 'Starting Balance') {
  88. foreach ($report->getOverviewAlignedWithColumns() as $summaryRow) {
  89. $row = [];
  90. foreach ($report->getColumns() as $column) {
  91. $columnName = $column->getName();
  92. $row[] = $summaryRow[$columnName] ?? '';
  93. }
  94. if (array_filter($row)) {
  95. $csv->insertOne($row);
  96. }
  97. }
  98. }
  99. }
  100. }
  101. public function exportToPdf(Company $company, ExportableReport $report, ?string $startDate = null, ?string $endDate = null): StreamedResponse
  102. {
  103. if ($startDate && $endDate) {
  104. $formattedStartDate = Carbon::parse($startDate)->toDateString();
  105. $formattedEndDate = Carbon::parse($endDate)->toDateString();
  106. $dateLabel = $formattedStartDate . ' to ' . $formattedEndDate;
  107. } else {
  108. $formattedAsOfDate = Carbon::parse($endDate)->toDateString();
  109. $dateLabel = $formattedAsOfDate;
  110. }
  111. $timestamp = Carbon::now()->format('Y-m-d_H-i-s');
  112. $filename = $company->name . ' ' . $report->getTitle() . ' ' . $dateLabel . ' ' . $timestamp . '.pdf';
  113. $pdf = SnappyPdf::loadView($report->getPdfView(), [
  114. 'company' => $company,
  115. 'report' => $report,
  116. 'startDate' => $startDate ? Carbon::parse($startDate)->toDefaultDateFormat() : null,
  117. 'endDate' => $endDate ? Carbon::parse($endDate)->toDefaultDateFormat() : null,
  118. ]);
  119. return response()->streamDownload(function () use ($pdf) {
  120. echo $pdf->inline();
  121. }, $filename);
  122. }
  123. /**
  124. * @throws CannotInsertRecord
  125. * @throws Exception
  126. */
  127. protected function writeDataRowsToCsv(Writer $csv, array $header, array $data, array $columns): void
  128. {
  129. if (isset($header[0]) && is_array($header[0])) {
  130. foreach ($header as $headerRow) {
  131. $csv->insertOne($headerRow);
  132. }
  133. } else {
  134. $csv->insertOne($header);
  135. }
  136. // Output data rows
  137. foreach ($data as $rowData) {
  138. $row = [];
  139. foreach ($columns as $column) {
  140. $columnName = $column->getName();
  141. $cell = $rowData[$columnName] ?? '';
  142. if ($column->isDate()) {
  143. try {
  144. $row[] = Carbon::parse($cell)->toDateString();
  145. } catch (InvalidFormatException) {
  146. $row[] = $cell;
  147. }
  148. } elseif (is_array($cell)) {
  149. $row[] = $cell['name'] ?? $cell['description'] ?? '';
  150. } else {
  151. $row[] = $cell;
  152. }
  153. }
  154. $csv->insertOne($row);
  155. }
  156. }
  157. }