| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- <?php
- namespace App\Services\Export;
- use App\Models\File;
- use App\Models\PricingCode;
- use App\Models\SparePart;
- use Illuminate\Support\Facades\Storage;
- use PhpOffice\PhpSpreadsheet\IOFactory;
- use PhpOffice\PhpSpreadsheet\Style\Border;
- use PhpOffice\PhpSpreadsheet\Style\Color;
- use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
- class ExportSparePartsService
- {
- public function handle(int $userId): string
- {
- $inputFileType = 'Xlsx';
- $inputFileName = './templates/SpareParts.xlsx';
- $reader = IOFactory::createReader($inputFileType);
- $spreadsheet = $reader->load($inputFileName);
- $sheet = $spreadsheet->getActiveSheet();
- // Получаем данные из модели (НЕ view!)
- // ВАЖНО: Вычисляемые поля учитывают текущий год из сессии
- $spareParts = SparePart::orderBy('article')->get();
- $i = 2;
- foreach ($spareParts as $sp) {
- $sheet->setCellValue('A' . $i, $sp->id);
- $sheet->setCellValue('B' . $i, $sp->article);
- $sheet->setCellValue('C' . $i, $sp->used_in_maf);
- $sheet->setCellValue('D' . $i, $sp->quantity_without_docs);
- $sheet->setCellValue('E' . $i, $sp->quantity_with_docs);
- $sheet->setCellValue('F' . $i, $sp->total_quantity);
- $sheet->setCellValue('G' . $i, $sp->note);
- $sheet->setCellValue('H' . $i, $sp->purchase_price);
- $sheet->setCellValue('I' . $i, $sp->customer_price);
- $sheet->setCellValue('J' . $i, $sp->expertise_price);
- $sheet->setCellValue('K' . $i, $sp->tsn_number);
- $sheet->setCellValue('L' . $i, $sp->pricing_code);
- $sheet->setCellValue('M' . $i, $sp->min_stock);
- $i++;
- }
- $sheet->getStyle('A1:M' . ($i - 1))
- ->getBorders()
- ->getAllBorders()
- ->setBorderStyle(Border::BORDER_THIN)
- ->setColor(new Color('777777'));
- // Создаём вторую вкладку для справочника расшифровок
- $pricingCodesSheet = $spreadsheet->createSheet(1);
- $pricingCodesSheet->setTitle('Справочник расшифровок');
- // Заголовки
- $pricingCodesSheet->setCellValue('A1', 'ID');
- $pricingCodesSheet->setCellValue('B1', 'Тип');
- $pricingCodesSheet->setCellValue('C1', 'Код');
- $pricingCodesSheet->setCellValue('D1', 'Расшифровка');
- // Стиль заголовков
- $pricingCodesSheet->getStyle('A1:D1')->getFont()->setBold(true);
- $pricingCodesSheet->getStyle('A1:D1')->getFill()
- ->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
- ->getStartColor()->setARGB('DDDDDD');
- // Данные справочника
- $pricingCodes = PricingCode::orderBy('type')->orderBy('code')->get();
- $j = 2;
- foreach ($pricingCodes as $pc) {
- $pricingCodesSheet->setCellValue('A' . $j, $pc->id);
- $pricingCodesSheet->setCellValue('B' . $j, $pc->type === PricingCode::TYPE_TSN_NUMBER ? '№ по ТСН' : 'Шифр расценки');
- $pricingCodesSheet->setCellValue('C' . $j, $pc->code);
- $pricingCodesSheet->setCellValue('D' . $j, $pc->description);
- $j++;
- }
- // Границы для справочника
- if ($j > 2) {
- $pricingCodesSheet->getStyle('A1:D' . ($j - 1))
- ->getBorders()
- ->getAllBorders()
- ->setBorderStyle(Border::BORDER_THIN)
- ->setColor(new Color('777777'));
- }
- // Автоширина колонок
- foreach (range('A', 'D') as $col) {
- $pricingCodesSheet->getColumnDimension($col)->setAutoSize(true);
- }
- // Возвращаемся на первую вкладку
- $spreadsheet->setActiveSheetIndex(0);
- $fileName = 'export_spare_parts_' . date('Y-m-d_H-i-s') . '.xlsx';
- $writer = new Xlsx($spreadsheet);
- $fd = 'export/spare_parts';
- Storage::disk('public')->makeDirectory($fd);
- $fp = storage_path('app/public/' . $fd . '/') . $fileName;
- Storage::disk('public')->delete($fd . '/' . $fileName);
- $writer->save($fp);
- $link = url('/storage/' . $fd . '/' . $fileName);
- // Создаём запись в таблице files
- File::query()->create([
- 'link' => $link,
- 'path' => $fp,
- 'user_id' => $userId,
- 'original_name' => $fileName,
- 'mime_type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
- ]);
- return $link;
- }
- }
|