Jelajahi Sumber

quality declaration generate

Alexander Musikhin 7 bulan lalu
induk
melakukan
6b73685b0b
4 mengubah file dengan 165 tambahan dan 13 penghapusan
  1. 98 0
      app/Helpers/ExcelHelper.php
  2. 67 13
      app/Services/GenerateDocumentsService.php
  3. TEMPAT SAMPAH
      templates/QualityDeclaration.xlsx
  4. TEMPAT SAMPAH
      templates/header.png

+ 98 - 0
app/Helpers/ExcelHelper.php

@@ -0,0 +1,98 @@
+<?php
+
+namespace App\Helpers;
+
+use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
+use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
+
+class ExcelHelper
+{
+    public static function copyRows( Worksheet $sheet, $srcRange, $dstCell, Worksheet $destSheet = null): void
+    {
+
+        if( !isset($destSheet)) {
+            $destSheet = $sheet;
+        }
+
+        if( !preg_match('/^([A-Z]+)(\d+):([A-Z]+)(\d+)$/', $srcRange, $srcRangeMatch) ) {
+            // Invalid src range
+            return;
+        }
+
+        if( !preg_match('/^([A-Z]+)(\d+)$/', $dstCell, $destCellMatch) ) {
+            // Invalid dest cell
+            return;
+        }
+
+        $srcColumnStart = $srcRangeMatch[1];
+        $srcRowStart = $srcRangeMatch[2];
+        $srcColumnEnd = $srcRangeMatch[3];
+        $srcRowEnd = $srcRangeMatch[4];
+
+        $destColumnStart = $destCellMatch[1];
+        $destRowStart = $destCellMatch[2];
+
+        $srcColumnStart = Coordinate::columnIndexFromString($srcColumnStart);
+        $srcColumnEnd = Coordinate::columnIndexFromString($srcColumnEnd);
+        $destColumnStart = Coordinate::columnIndexFromString($destColumnStart);
+
+        $rowCount = 0;
+        for ($row = $srcRowStart; $row <= $srcRowEnd; $row++) {
+            $colCount = 0;
+            for ($col = $srcColumnStart; $col <= $srcColumnEnd; $col++) {
+                $cell = $sheet->getCell([$col, $row]);
+                $style = $sheet->getStyle([$col, $row]);
+                $dstCell = Coordinate::stringFromColumnIndex($destColumnStart + $colCount) . (string)((int)$destRowStart + (int)$rowCount);
+                $destSheet->setCellValue($dstCell, $cell->getValue());
+                $destSheet->duplicateStyle($style, $dstCell);
+
+                // Set width of column, but only once per column
+                if ($rowCount === 0) {
+                    $w = $sheet->getColumnDimensionByColumn($col)->getWidth();
+                    $destSheet->getColumnDimensionByColumn ($destColumnStart + $colCount)->setAutoSize(false);
+                    $destSheet->getColumnDimensionByColumn ($destColumnStart + $colCount)->setWidth($w);
+                }
+
+                $colCount++;
+            }
+
+            $h = $sheet->getRowDimension($row)->getRowHeight();
+            $destSheet->getRowDimension((int)$destRowStart + $rowCount)->setRowHeight($h);
+
+            $rowCount++;
+        }
+
+        foreach ($sheet->getMergeCells() as $mergeCell) {
+            $mc = explode(":", $mergeCell);
+            $mergeColSrcStart = Coordinate::columnIndexFromString(preg_replace("/[0-9]*/", "", $mc[0]));
+            $mergeColSrcEnd = Coordinate::columnIndexFromString(preg_replace("/[0-9]*/", "", $mc[1]));
+            $mergeRowSrcStart = ((int)preg_replace("/[A-Z]*/", "", $mc[0]));
+            $mergeRowSrcEnd = ((int)preg_replace("/[A-Z]*/", "", $mc[1]));
+
+            $relativeColStart = $mergeColSrcStart - $srcColumnStart;
+            $relativeColEnd = $mergeColSrcEnd - $srcColumnStart;
+            $relativeRowStart = $mergeRowSrcStart - $srcRowStart;
+            $relativeRowEnd = $mergeRowSrcEnd - $srcRowStart;
+
+            if (0 <= $mergeRowSrcStart && $mergeRowSrcStart >= $srcRowStart && $mergeRowSrcEnd <= $srcRowEnd) {
+                $targetColStart = Coordinate::stringFromColumnIndex($destColumnStart + $relativeColStart);
+                $targetColEnd = Coordinate::stringFromColumnIndex($destColumnStart + $relativeColEnd);
+                $targetRowStart = (int)$destRowStart + $relativeRowStart;
+                $targetRowEnd = (int)$destRowStart + $relativeRowEnd;
+
+                $merge = (string)$targetColStart . (string)($targetRowStart) . ":" . (string)$targetColEnd . (string)($targetRowEnd);
+                //Merge target cells
+                $destSheet->mergeCells($merge);
+            }
+        }
+    }
+
+    public static function copyStyleXFCollection(Spreadsheet $sourceSheet, Spreadsheet $destSheet) {
+        $collection = $sourceSheet->getCellXfCollection();
+
+        foreach ($collection as $key => $item) {
+            $destSheet->addCellXf($item);
+        }
+    }
+}

+ 67 - 13
app/Services/GenerateDocumentsService.php

@@ -3,12 +3,15 @@
 namespace App\Services;
 
 use App\Helpers\DateHelper;
+use App\Helpers\ExcelHelper;
 use App\Models\Contract;
 use App\Models\Order;
 use Exception;
 use Illuminate\Support\Facades\Storage;
 use Illuminate\Support\Str;
+use PhpOffice\PhpSpreadsheet\Cell\Cell;
 use PhpOffice\PhpSpreadsheet\IOFactory;
+use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
 use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
 
 class GenerateDocumentsService
@@ -30,11 +33,11 @@ class GenerateDocumentsService
         Storage::disk('public')->makeDirectory('orders/' . $order->id . '/tmp/Схемы сборки/');
 
         foreach ($products_sku as $sku) {
-            if(!in_array($sku->product->article, $articles)) {
+            if (!in_array($sku->product->article, $articles)) {
                 $articles[] = $sku->product->article;
                 // find and copy scheme files to installation directory
-                if(file_exists($techDocsPath . $sku->product->article . '/')) {
-                    foreach(Storage::disk('base')->allFiles('tech-docs/' . $sku->product->article) as $p) {
+                if (file_exists($techDocsPath . $sku->product->article . '/')) {
+                    foreach (Storage::disk('base')->allFiles('tech-docs/' . $sku->product->article) as $p) {
                         $content = Storage::disk('base')->get($p);
                         Storage::disk('public')->put('orders/' . $order->id . '/tmp/Схемы сборки/' . basename($p), $content);
                     }
@@ -73,7 +76,7 @@ class GenerateDocumentsService
         $sheet->setCellValue('L10', $order->district->shortname);
         $sheet->setCellValue('W10', $order->area->name);
 
-        if($order->area->responsible) {
+        if ($order->area->responsible) {
             // ответственный
             $sheet->setCellValue('C12', $order->area->responsible?->name
                 . ', ' . $order->area->responsible?->phone . ', ' . $order->area->responsible?->post);
@@ -93,7 +96,7 @@ class GenerateDocumentsService
         $writer = new Xlsx($spreadsheet);
         Storage::disk('public')->makeDirectory('orders/' . $order->id . '/tmp');
 
-        $writer->save(storage_path('app/public/orders/') . $order->id .'/tmp/' . $fileName);
+        $writer->save(storage_path('app/public/orders/') . $order->id . '/tmp/' . $fileName);
     }
 
 
@@ -112,26 +115,26 @@ class GenerateDocumentsService
         foreach ($order->photos as $photo) {
             $from = $photo->path;
             $to = 'orders/' . $order->id . '/tmp/ФОТО ПСТ/photos/' . $photo->original_name;
-            if(!Storage::disk('public')->exists($to)) {
+            if (!Storage::disk('public')->exists($to)) {
                 Storage::disk('public')->copy($from, $to);
             }
         }
 
         foreach ($order->products_sku as $sku) {
             // copy certificates
-            if($sku->product->certificate_id) {
+            if ($sku->product->certificate_id) {
                 $from = $sku->product->certificate->path;
                 $to = 'orders/' . $order->id . '/tmp/СЕРТИФИКАТ/' . $sku->product->certificate->original_name;
-                if(!Storage::disk('public')->exists($to)) {
+                if (!Storage::disk('public')->exists($to)) {
                     Storage::disk('public')->copy($from, $to);
                 }
             }
 
             // copy passport
-            if($sku->passport_id) {
+            if ($sku->passport_id) {
                 $from = $sku->passport->path;
                 $to = 'orders/' . $order->id . '/tmp/ПАСПОРТ/' . $sku->passport->original_name;
-                if(!Storage::disk('public')->exists($to)) {
+                if (!Storage::disk('public')->exists($to)) {
                     Storage::disk('public')->copy($from, $to);
                 }
             }
@@ -140,7 +143,7 @@ class GenerateDocumentsService
 
         // generate xlsx order files
         $this->generateStatement($order);
-
+        $this->generateQualityDeclaration($order);
 
 
         // create zip archive
@@ -180,7 +183,7 @@ class GenerateDocumentsService
         $i = 9; // start of table
         $nn = 1; // string number
         foreach ($order->products_sku as $sku) {
-            if($nn > 1) { // inset row
+            if ($nn > 1) { // inset row
                 $sheet->insertNewRowBefore($i);
             }
             $sheet->setCellValue('A' . $i, $nn++);
@@ -198,8 +201,59 @@ class GenerateDocumentsService
         $writer = new Xlsx($spreadsheet);
         Storage::disk('public')->makeDirectory('orders/' . $order->id . '/tmp');
 
-        $writer->save(storage_path('app/public/orders/') . $order->id .'/tmp/' . $fileName);
+        $writer->save(storage_path('app/public/orders/') . $order->id . '/tmp/' . $fileName);
     }
 
+    public function generateQualityDeclaration(Order $order): void
+    {
+        $inputFileType = 'Xlsx';
+        $inputFileName = './templates/QualityDeclaration.xlsx';
+
+        $reader = IOFactory::createReader($inputFileType);
+        $spreadsheet = $reader->load($inputFileName);
+        $sheet = $spreadsheet->getActiveSheet();
+
+        $address = 'г. Москва, ' . $order->district->shortname . ', район ' . $order->area->name . ', по адресу: ' . $order->object_address;
+        $i = 1; // start of table
+        $n = 1;
+        foreach ($order->products_sku as $sku) {
+            if ($n++ > 1) {
+                $range = 'A' . $i . ':I' . $i + 56;
+                $i = $i + 57;
+                ExcelHelper::copyRows($sheet, $range, 'A' . $i);
+
+                // add header img
+                $drawing = new Drawing();
+                $drawing->setName('Header');
+                $drawing->setDescription('Header');
+                $drawing->setPath('templates/header.png');
+                $drawing->setCoordinates('A' . $i);
+                $drawing->setOffsetX(16);
+                $drawing->setOffsetY(8);
+                $drawing->setResizeProportional(true);
+                $drawing->setWidth(680);
+                $drawing->setWorksheet($sheet);
+
+            }
+
+            // document date?
+            $sheet->setCellValue('A' . $i + 7, DateHelper::getHumanDate(date('Y-m-d'), true));
+
+            $sheet->setCellValue('B' . $i + 16, $sku->product->passport_name);
+            $sheet->setCellValue('C' . $i + 18, $sku->rfid);
+            $sheet->setCellValue('C' . $i + 20, $address);
+
+            // add page break and copy prev page
+
+
+        }
+
+        // save file
+        $fileName = '2.Декларация качества.xlsx';
+        $writer = new Xlsx($spreadsheet);
+        Storage::disk('public')->makeDirectory('orders/' . $order->id . '/tmp');
+
+        $writer->save(storage_path('app/public/orders/') . $order->id . '/tmp/' . $fileName);
+    }
 
 }

TEMPAT SAMPAH
templates/QualityDeclaration.xlsx


TEMPAT SAMPAH
templates/header.png