Ver Fonte

小高薪

cqp há 2 meses atrás
pai
commit
1cfb6b8688
1 ficheiros alterados com 40 adições e 84 exclusões
  1. 40 84
      app/Exports/ResearchExpenseSummarySheetExport.php

+ 40 - 84
app/Exports/ResearchExpenseSummarySheetExport.php

@@ -15,7 +15,7 @@ class ResearchExpenseSummarySheetExport implements WithEvents, WithTitle
     protected $items;
     protected $taxId;
     protected $companyName;
-    protected $dynamicHeaders; // 动态传入的明细科目
+    protected $dynamicHeaders;
 
     public function __construct($year, array $payload, array $dynamicHeaders = [])
     {
@@ -23,7 +23,6 @@ class ResearchExpenseSummarySheetExport implements WithEvents, WithTitle
         $this->items = $payload['items'] ?? [];
         $this->taxId = $payload['tax_id'] ?? '';
         $this->companyName = $payload['company_name'] ?? '';
-        // 确保至少包含基础的:人员人工, 折旧
         $this->dynamicHeaders = $dynamicHeaders ?: ['人员人工费用', '折旧费用'];
     }
 
@@ -35,42 +34,33 @@ class ResearchExpenseSummarySheetExport implements WithEvents, WithTitle
             AfterSheet::class => function (AfterSheet $event) {
                 $sheet = $event->sheet->getDelegate();
 
-                // 1. 计算关键列的字母索引
-                $baseColCount = 4; // A:编号, B:名称, C:完成, D:类型
+                // 1. 计算列索引
                 $totalDynamic = count($this->dynamicHeaders);
+                $startDetailIdx = 6; // F列
 
-                // 允许加计扣除合计列 (E)
                 $col_E = 'E';
-                // 明细科目起始列 (F开始)
-                $startDetailIdx = 6;
-                // 小计列 (6列)
                 $col_6 = Coordinate::stringFromColumnIndex($startDetailIdx + $totalDynamic);
-                // 7.1列 (其他相关费用合计)
                 $col_7_1 = Coordinate::stringFromColumnIndex($startDetailIdx + $totalDynamic + 1);
-                // 7.2列 (调整后)
                 $col_7_2 = Coordinate::stringFromColumnIndex($startDetailIdx + $totalDynamic + 2);
-                // 8.1列 (委托境内)
                 $col_8_1 = Coordinate::stringFromColumnIndex($startDetailIdx + $totalDynamic + 3);
-                // 8.2列 (8.1*80%)
                 $col_8_2 = Coordinate::stringFromColumnIndex($startDetailIdx + $totalDynamic + 4);
-                // 8.3列 (委托境外)
                 $col_8_3 = Coordinate::stringFromColumnIndex($startDetailIdx + $totalDynamic + 5);
-                // 8.4列 (调整后境外)
                 $col_8_4 = Coordinate::stringFromColumnIndex($startDetailIdx + $totalDynamic + 6);
 
                 $highestColumn = $col_8_4;
 
-                // 2. 设置列宽
+                // 2. 设置布局
                 $sheet->getColumnDimension('B')->setWidth(40);
-                for ($i = 1; $i <= Coordinate::columnIndexFromString($highestColumn); $i++) {
+                $lastColNum = Coordinate::columnIndexFromString($highestColumn);
+                for ($i = 1; $i <= $lastColNum; $i++) {
                     $col = Coordinate::stringFromColumnIndex($i);
-                    if ($col != 'B') $sheet->getColumnDimension($col)->setWidth(12);
+                    if ($col != 'B') $sheet->getColumnDimension($col)->setWidth(13);
                 }
 
                 // 3. 绘制表头
                 $this->drawDynamicHeader($sheet, $col_E, $col_6, $col_7_1, $col_8_1, $highestColumn);
 
-                // 4. 填充明细数据
+                // 4. 填充明细
                 $currentRow = 8;
                 $capRows = []; $expRows = [];
 
@@ -80,13 +70,13 @@ class ResearchExpenseSummarySheetExport implements WithEvents, WithTitle
                     $sheet->setCellValue("C{$currentRow}", $item['status'] == 3 ? '已完成' : '进行中');
                     $sheet->setCellValue("D{$currentRow}", $item['type']);
 
-                    // 填充动态明细列 (F -> 小计前)
+                    // 动态明细
                     foreach ($this->dynamicHeaders as $idx => $header) {
                         $col = Coordinate::stringFromColumnIndex($startDetailIdx + $idx);
                         $sheet->setCellValue("{$col}{$currentRow}", $item['values'][$idx] ?? 0);
                     }
 
-                    // 填充固定逻辑
+                    // 固定数值
                     $sheet->setCellValue("{$col_7_1}{$currentRow}", $item['val7_1'] ?? 0);
                     $sheet->setCellValue("{$col_8_1}{$currentRow}", $item['val8_1'] ?? 0);
                     $sheet->setCellValue("{$col_8_3}{$currentRow}", $item['val8_3'] ?? 0);
@@ -98,16 +88,20 @@ class ResearchExpenseSummarySheetExport implements WithEvents, WithTitle
                     $sheet->setCellValue("{$col_6}{$currentRow}", "=SUM({$firstDetailCol}{$currentRow}:{$lastDetailCol}{$currentRow})");
                     $sheet->setCellValue("{$col_7_2}{$currentRow}", "={$col_7_1}{$currentRow}");
                     $sheet->setCellValue("{$col_8_2}{$currentRow}", "={$col_8_1}{$currentRow}*0.8");
-                    $sheet->setCellValue("{$col_8_4}{$currentRow}", "={$col_8_3}{$currentRow}");
-                    // E = 6 + 7.2 + 8.2 + 8.4
+                    $sheet->setCellValue("{$col_8_4}{$currentRow}", "={$col_8_3}{$currentRow}*0.8");
                     $sheet->setCellValue("{$col_E}{$currentRow}", "={$col_6}{$currentRow}+{$col_7_2}{$currentRow}+{$col_8_2}{$currentRow}+{$col_8_4}{$currentRow}");
 
-                    if ($item['type'] == '资本化支出' && $item['status'] == 3) $capRows[] = $currentRow;
-                    elseif ($item['type'] == '费用化支出') $expRows[] = $currentRow;
+                    // 严格清洗类型字符串进行归集
+                    $cleanType = preg_replace('/[\s\v\t\r\n]+/u', '', (string)$item['type']);
+                    if ($cleanType === '资本化支出' && $item['status'] == 3) {
+                        $capRows[] = $currentRow;
+                    } elseif ($cleanType === '费用化支出') {
+                        $expRows[] = $currentRow;
+                    }
                     $currentRow++;
                 }
 
-                // 5. 应用合计勾稽逻辑
+                // 5. 应用合计逻辑
                 $this->applyDynamicSummaryLogic($sheet, $currentRow, $capRows, $expRows, $startDetailIdx, $totalDynamic, $col_E, $col_6, $col_7_1, $col_7_2, $col_8_1, $col_8_2, $col_8_3, $col_8_4);
 
                 // 6. 最终样式
@@ -121,44 +115,30 @@ class ResearchExpenseSummarySheetExport implements WithEvents, WithTitle
 
     private function drawDynamicHeader($sheet, $col_E, $col_6, $col_7_1, $col_8_1, $highestColumn)
     {
-        // --- 1. 大标题 (第2行) ---
         $sheet->mergeCells("A2:{$highestColumn}2");
         $sheet->setCellValue('A2', '研发支出辅助账汇总表');
-        $sheet->getStyle('A2')->applyFromArray([
-            'font' => ['size' => 16, 'bold' => true],
-            'alignment' => [
-                'horizontal' => Alignment::HORIZONTAL_CENTER,
-                'vertical' => Alignment::VERTICAL_CENTER,
-            ],
-        ]);
-
-        // --- 2. 项目信息行 (第3行) ---
-        // 纳税人识别号 (靠左)
+        $sheet->getStyle('A2')->applyFromArray(['font' => ['size' => 16, 'bold' => true], 'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER]]);
+
+        // 第3行布局修复
+        $totalCols = Coordinate::columnIndexFromString($highestColumn);
         $sheet->setCellValue('A3', '纳税人识别号(统一社会信用代码):' . $this->taxId);
 
-        // 纳税人名称 (居中偏右,通常定位在 J 列附近,或者根据动态列数灵活调整)
-        $nameCol = Coordinate::stringFromColumnIndex(max(10, count($this->dynamicHeaders) + 4));
+        $nameCol = Coordinate::stringFromColumnIndex(max(7, floor($totalCols * 0.55)));
         $sheet->setCellValue($nameCol . '3', '纳税人名称:' . $this->companyName);
 
-        // 属期 (定位在倒数第 2 或第 3 列)
-        $periodCol = Coordinate::stringFromColumnIndex(Coordinate::columnIndexFromString($highestColumn) - 2);
+        $periodCol = Coordinate::stringFromColumnIndex($totalCols - 3);
         $sheet->setCellValue($periodCol . '3', "属期:{$this->year}年");
 
-        // 单位 (固定最右侧)
         $sheet->setCellValue($highestColumn . '3', '单位:元');
         $sheet->getStyle($highestColumn . '3')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_RIGHT);
 
-        // --- 3. 第4行留空 (保持默认即可,不赋值) ---
-
-        // --- 4. 表头 (5-7行) ---
-        // A-E 固定列
+        // 表头 5-7 行
         $vHeaders = ['A'=>'项目编号', 'B'=>'项目名称', 'C'=>'完成情况', 'D'=>'支出类型', 'E'=>"允许加计\n扣除金额合计"];
         foreach ($vHeaders as $col => $text) {
             $sheet->mergeCells("{$col}5:{$col}7");
             $sheet->setCellValue("{$col}5", $text);
         }
 
-        // 动态明细表头 (F列开始)
         $startIdx = 6;
         foreach ($this->dynamicHeaders as $idx => $text) {
             $col = Coordinate::stringFromColumnIndex($startIdx + $idx);
@@ -167,42 +147,26 @@ class ResearchExpenseSummarySheetExport implements WithEvents, WithTitle
             $sheet->setCellValue("{$col}7", $idx + 1);
         }
 
-        // 小计列
         $sheet->mergeCells("{$col_6}5:{$col_6}6");
-        $sheet->setCellValue("{$col_6}5", "前" . count($this->dynamicHeaders) . "项 小计");
+        $sheet->setCellValue("{$col_6}5", "前" . count($this->dynamicHeaders) . "项小计");
         $sheet->setCellValue("{$col_6}7", count($this->dynamicHeaders) + 1);
 
-        // 其他相关费用 (7.1, 7.2)
         $col_7_2 = Coordinate::stringFromColumnIndex(Coordinate::columnIndexFromString($col_7_1) + 1);
         $sheet->mergeCells("{$col_7_1}5:{$col_7_2}5");
         $sheet->setCellValue("{$col_7_1}5", '其他相关费用及限额');
-        $sheet->setCellValue("{$col_7_1}6", '其他相关费用合计');
-        $sheet->setCellValue("{$col_7_1}7", '7.1');
-        $sheet->setCellValue("{$col_7_2}6", "经限额调整后的其他相关费用");
-        $sheet->setCellValue("{$col_7_2}7", '7.2');
+        $sheet->setCellValue("{$col_7_1}6", '其他相关费用合计'); $sheet->setCellValue("{$col_7_1}7", '7.1');
+        $sheet->setCellValue("{$col_7_2}6", "经限额调整后的其他相关费用"); $sheet->setCellValue("{$col_7_2}7", '7.2');
 
-        // 委托研发 (8.1-8.4)
         $sheet->mergeCells("{$col_8_1}5:{$highestColumn}5");
         $sheet->setCellValue("{$col_8_1}5", '委托研发费用及限额');
-
-        $startColIdx = Coordinate::columnIndexFromString($col_8_1);
-        $subHeaderNames = [
-            '委托境内机构或个人进行研发活动所发生的费用',
-            '允许加计扣除的委托境内机构或个人进行研发活动所发生的费用',
-            '委托境外机构进行研发活动所发生的费用',
-            '经限额调整后的委托境外机构进行研发活动所发生的费用'
-        ];
+        $sIdx = Coordinate::columnIndexFromString($col_8_1);
+        $subs = ['委托境内机构或个人进行研发活动所发生的费用', '允许加计扣除的委托境内机构或个人进行研发活动所发生的费用', '委托境外机构进行研发活动所发生的费用', '经限额调整后的委托境外机构进行研发活动所发生的费用'];
         $nums = ['8.1','8.2','8.3','8.4'];
-
-        for($i=0; $i<4; $i++) {
-            $colLetter = Coordinate::stringFromColumnIndex($startColIdx + $i);
-            $sheet->setCellValue($colLetter . '6', $subHeaderNames[$i]);
-            $sheet->setCellValue($colLetter . '7', $nums[$i]);
+        for($i=0;$i<4;$i++) {
+            $c = Coordinate::stringFromColumnIndex($sIdx + $i);
+            $sheet->setCellValue($c . '6', $subs[$i]);
+            $sheet->setCellValue($c . '7', $nums[$i]);
         }
-
-        // 设置第3行行高和垂直居中
-        $sheet->getRowDimension('3')->setRowHeight(25);
-        $sheet->getStyle("A3:{$highestColumn}3")->getAlignment()->setVertical(Alignment::VERTICAL_CENTER);
     }
 
     private function applyDynamicSummaryLogic($sheet, $r, $capRows, $expRows, $startIdx, $dynamicCount, $col_E, $col_6, $col_7_1, $col_7_2, $col_8_1, $col_8_2, $col_8_3, $col_8_4)
@@ -214,42 +178,34 @@ class ResearchExpenseSummarySheetExport implements WithEvents, WithTitle
             $sheet->setCellValue("A" . ($r+$i), $label);
         }
 
-        // 所有需要汇总计算的数值列
         $allValCols = [];
         for($i=0; $i<$dynamicCount; $i++) { $allValCols[] = Coordinate::stringFromColumnIndex($startIdx + $i); }
         $allValCols = array_merge($allValCols, [$col_7_1, $col_8_1, $col_8_3]);
 
         foreach ($allValCols as $col) {
             $f_cap = !empty($capRows) ? "=SUM(".implode(',', array_map(fn($row)=>"{$col}{$row}", $capRows)).")" : "0";
-            $f_exp = !empty($expRows) ? "=SUM(".implode(',', array_map(fn($row)=>"{$col}{$row}", $expRows)).") + {$col}{$r_oth}" : "{$col}{$r_oth}";
+            $f_exp_base = !empty($expRows) ? "SUM(".implode(',', array_map(fn($row)=>"{$col}{$row}", $expRows)).")" : "0";
             $sheet->setCellValue("{$col}{$r_cap}", $f_cap);
-            $sheet->setCellValue("{$col}{$r_exp}", $f_exp);
+            $sheet->setCellValue("{$col}{$r_exp}", "={$f_exp_base}+{$col}{$r_oth}");
             $sheet->setCellValue("{$col}{$r_all}", "={$col}{$r_cap}+{$col}{$r_exp}");
         }
 
-        // 核心勾稽公式应用
-        $firstDetailCol = Coordinate::stringFromColumnIndex($startIdx);
-        $lastDetailCol = Coordinate::stringFromColumnIndex($startIdx + $dynamicCount - 1);
+        $fCol = Coordinate::stringFromColumnIndex($startIdx);
+        $lCol = Coordinate::stringFromColumnIndex($startIdx + $dynamicCount - 1);
 
         foreach ([$r_cap, $r_exp, $r_all] as $row) {
-            $sheet->setCellValue("{$col_6}{$row}", "=SUM({$firstDetailCol}{$row}:{$lastDetailCol}{$row})");
+            $sheet->setCellValue("{$col_6}{$row}", "=SUM({$fCol}{$row}:{$lCol}{$row})");
             $sheet->setCellValue("{$col_8_2}{$row}", "={$col_8_1}{$row}*0.8");
-
-            // 规则六:7.2列 (限额调整)
             if ($row == $r_all) {
                 $sheet->setCellValue("{$col_7_2}{$row}", "=MIN({$col_7_1}{$row}, {$col_6}{$row}*0.1/0.9)");
             } else {
                 $sheet->setCellValue("{$col_7_2}{$row}", "=IF({$col_7_1}{$r_all}>0, ({$col_7_2}{$r_all}/{$col_7_1}{$r_all})*{$col_7_1}{$row}, 0)");
             }
-
-            // 规则八:8.4列 (境外限额)
             if ($row == $r_all) {
                 $sheet->setCellValue("{$col_8_4}{$row}", "=MIN(({$col_6}{$row}+{$col_7_2}{$row}+{$col_8_2}{$row})*2/3, {$col_8_3}{$row}*0.8)");
             } else {
                 $sheet->setCellValue("{$col_8_4}{$row}", "=IF({$col_8_3}{$r_all}>0, ({$col_8_4}{$r_all}/{$col_8_3}{$r_all})*{$col_8_3}{$row}, 0)");
             }
-
-            // 最终合计列 E
             $sheet->setCellValue("{$col_E}{$row}", "={$col_6}{$row}+{$col_7_2}{$row}+{$col_8_2}{$row}+{$col_8_4}{$row}");
         }
     }