ExportSparePartsService.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. <?php
  2. namespace App\Services\Export;
  3. use App\Models\File;
  4. use App\Models\PricingCode;
  5. use App\Models\SparePart;
  6. use Illuminate\Support\Facades\Storage;
  7. use PhpOffice\PhpSpreadsheet\IOFactory;
  8. use PhpOffice\PhpSpreadsheet\Style\Border;
  9. use PhpOffice\PhpSpreadsheet\Style\Color;
  10. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  11. class ExportSparePartsService
  12. {
  13. public function handle(int $userId): string
  14. {
  15. $inputFileType = 'Xlsx';
  16. $inputFileName = './templates/SpareParts.xlsx';
  17. $reader = IOFactory::createReader($inputFileType);
  18. $spreadsheet = $reader->load($inputFileName);
  19. $sheet = $spreadsheet->getActiveSheet();
  20. // Получаем данные из модели (НЕ view!)
  21. // ВАЖНО: Вычисляемые поля учитывают текущий год из сессии
  22. $spareParts = SparePart::orderBy('article')->get();
  23. $i = 2;
  24. foreach ($spareParts as $sp) {
  25. $sheet->setCellValue('A' . $i, $sp->id);
  26. $sheet->setCellValue('B' . $i, $sp->article);
  27. $sheet->setCellValue('C' . $i, $sp->used_in_maf);
  28. $sheet->setCellValue('D' . $i, $sp->quantity_without_docs);
  29. $sheet->setCellValue('E' . $i, $sp->quantity_with_docs);
  30. $sheet->setCellValue('F' . $i, $sp->total_quantity);
  31. $sheet->setCellValue('G' . $i, $sp->note);
  32. $sheet->setCellValue('H' . $i, $sp->purchase_price);
  33. $sheet->setCellValue('I' . $i, $sp->customer_price);
  34. $sheet->setCellValue('J' . $i, $sp->expertise_price);
  35. $sheet->setCellValue('K' . $i, $sp->tsn_number);
  36. $sheet->setCellValue('L' . $i, $sp->pricing_code);
  37. $sheet->setCellValue('M' . $i, $sp->min_stock);
  38. $i++;
  39. }
  40. $sheet->getStyle('A1:M' . ($i - 1))
  41. ->getBorders()
  42. ->getAllBorders()
  43. ->setBorderStyle(Border::BORDER_THIN)
  44. ->setColor(new Color('777777'));
  45. // Создаём вторую вкладку для справочника расшифровок
  46. $pricingCodesSheet = $spreadsheet->createSheet(1);
  47. $pricingCodesSheet->setTitle('Справочник расшифровок');
  48. // Заголовки
  49. $pricingCodesSheet->setCellValue('A1', 'ID');
  50. $pricingCodesSheet->setCellValue('B1', 'Тип');
  51. $pricingCodesSheet->setCellValue('C1', 'Код');
  52. $pricingCodesSheet->setCellValue('D1', 'Расшифровка');
  53. // Стиль заголовков
  54. $pricingCodesSheet->getStyle('A1:D1')->getFont()->setBold(true);
  55. $pricingCodesSheet->getStyle('A1:D1')->getFill()
  56. ->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
  57. ->getStartColor()->setARGB('DDDDDD');
  58. // Данные справочника
  59. $pricingCodes = PricingCode::orderBy('type')->orderBy('code')->get();
  60. $j = 2;
  61. foreach ($pricingCodes as $pc) {
  62. $pricingCodesSheet->setCellValue('A' . $j, $pc->id);
  63. $pricingCodesSheet->setCellValue('B' . $j, $pc->type === PricingCode::TYPE_TSN_NUMBER ? '№ по ТСН' : 'Шифр расценки');
  64. $pricingCodesSheet->setCellValue('C' . $j, $pc->code);
  65. $pricingCodesSheet->setCellValue('D' . $j, $pc->description);
  66. $j++;
  67. }
  68. // Границы для справочника
  69. if ($j > 2) {
  70. $pricingCodesSheet->getStyle('A1:D' . ($j - 1))
  71. ->getBorders()
  72. ->getAllBorders()
  73. ->setBorderStyle(Border::BORDER_THIN)
  74. ->setColor(new Color('777777'));
  75. }
  76. // Автоширина колонок
  77. foreach (range('A', 'D') as $col) {
  78. $pricingCodesSheet->getColumnDimension($col)->setAutoSize(true);
  79. }
  80. // Возвращаемся на первую вкладку
  81. $spreadsheet->setActiveSheetIndex(0);
  82. $fileName = 'export_spare_parts_' . date('Y-m-d_H-i-s') . '.xlsx';
  83. $writer = new Xlsx($spreadsheet);
  84. $fd = 'export/spare_parts';
  85. Storage::disk('public')->makeDirectory($fd);
  86. $fp = storage_path('app/public/' . $fd . '/') . $fileName;
  87. Storage::disk('public')->delete($fd . '/' . $fileName);
  88. $writer->save($fp);
  89. $link = url('/storage/' . $fd . '/' . $fileName);
  90. // Создаём запись в таблице files
  91. File::query()->create([
  92. 'link' => $link,
  93. 'path' => $fp,
  94. 'user_id' => $userId,
  95. 'original_name' => $fileName,
  96. 'mime_type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  97. ]);
  98. return $link;
  99. }
  100. }