cqp преди 1 седмица
родител
ревизия
01815c5e9b
променени са 1 файла, в които са добавени 265 реда и са изтрити 2 реда
  1. 265 2
      app/Service/ExportFileService.php

+ 265 - 2
app/Service/ExportFileService.php

@@ -790,7 +790,7 @@ class ExportFileService extends Service
     }
 
     // 年度研发支出辅助账汇总表
-    public function exportResearchExpense(array $data, $user)
+    public function exportResearchExpense1(array $data, $user)
     {
         $service = new StatisticService();
         list($status, $result) = $service->auxiliaryStatistic($data, $user);
@@ -869,8 +869,141 @@ class ExportFileService extends Service
         return [true, $filename];
     }
 
+    // 年度研发支出辅助账汇总表
+    public function exportResearchExpense(array $data, $user)
+    {
+        $service = new StatisticService();
+        list($status, $result) = $service->auxiliaryStatistic($data, $user);
+        if (!$status) return [false, $result];
+
+        $fee_type_list = $result['fee_type_list'];
+        $raw_list = $result['list'];
+        if(empty($raw_list)) return [false, '暂无导出数据'];
+
+        // 预读年份和基本信息
+        $year = date("Y", strtotime($raw_list[0]['voucher_date']));
+        $company = Depart::where('id', $user['top_depart_id'])->value('title');
+
+        // ================== 【核心修改 1:重构与排序所有金额列】 ==================
+        // 1. 定义固定的人员和折旧列配置并赋予 sort
+        $amountColumnsConfig = [
+            [
+                'type_key' => 'type_1', // 对应原逻辑 type == 1 (人员)
+                'title'    => '人员人工费用',
+                'sort'     => -1,
+            ],
+            [
+                'type_key' => 'type_2', // 对应原逻辑 type == 2 (折旧)
+                'title'    => '折旧费用',
+                'sort'     => 1,
+            ]
+        ];
+
+        // 2. 将动态费用类型塞入同一个配置池中
+        foreach ($fee_type_list as $feeId => $feeItem) {
+            $amountColumnsConfig[] = [
+                'type_key' => 'fee_' . $feeId, // 对应原逻辑 type == 3 && fee_id == $feeId
+                'fee_id'   => $feeId,
+                'title'    => $feeItem['title'] ?? '',
+                'sort'     => (int)($feeItem['sort'] ?? 0),
+            ];
+        }
+
+        // 3. 按照 sort 正序排序(值越小越靠前)
+        $sortedAmountColumns = collect($amountColumnsConfig)->sortBy('sort')->values()->all();
+
+        // 4. 提取出最终的动态表头名称供 Excel 使用
+        $dynamicHeaderTitles = array_column($sortedAmountColumns, 'title');
+
+        // 5. 计算总列数:
+        // 前面基础4列(日期、凭证种类、凭证号、摘要)
+        // 加上 2列(记账凭证金额、本期归集金额)
+        // 加上 排序后的所有科目列数
+        // 加上 2列(委托境内、委托境外)
+        $baseColCount = 6; // 前面基础共6列金额及非金额列
+        $sortedColCount = count($sortedAmountColumns);
+        $totalColCount = $baseColCount + $sortedColCount + 2;
+        // =========================================================================
+
+        $groupedData = [];
+
+        foreach ($raw_list as $row) {
+            $sheetKey = $year . $row['code'];
+
+            if (!isset($groupedData[$sheetKey])) {
+                $groupedData[$sheetKey] = [
+                    'project' => [
+                        'code' => $row['code'],
+                        'name' => $row['title'],
+                    ],
+                    'dynamic_headers' => $dynamicHeaderTitles,
+                    'data' => [],
+                    'year' => $company . $year,
+                    'totals' => array_fill(0, $totalColCount, 0)
+                ];
+                $groupedData[$sheetKey]['totals'][0] = '合计'; // 第一列标识
+            }
+
+            // 1. 初始化明细行的前 6 列(基础信息 + 基础金额)
+            $excelRow = [
+                $row['voucher_date'],
+                $row['voucher_type'],
+                $row['voucher_no'],
+                $row['voucher_remark'],
+                (float)($row['voucher_amount'] ?? 0),
+                (float)($row['aggregation_amount'] ?? 0),
+            ];
+
+            // ================== 【核心修改 2:依照排序配置填充科目金额】 ==================
+            foreach ($sortedAmountColumns as $col) {
+                $colValue = 0.0;
+
+                if ($col['type_key'] === 'type_1') {
+                    // 人员人工
+                    $colValue = ($row['type'] == 1 ? (float)$row['total_amount'] : 0);
+                } elseif ($col['type_key'] === 'type_2') {
+                    // 折旧费用
+                    $colValue = ($row['type'] == 2 ? (float)$row['total_amount'] : 0);
+                } else {
+                    // 动态费用科目
+                    $colValue = ($row['type'] == 3 && $row['fee_id'] == $col['fee_id']) ? (float)$row['total_amount'] : 0;
+                }
+
+                $excelRow[] = $colValue;
+            }
+            // =========================================================================
+
+            // 3. 追加尾部的委托列
+            $excelRow[] = (float)($row['entrust1_amount'] ?? 0);
+            $excelRow[] = (float)($row['entrust2_amount'] ?? 0);
+
+            // 同步累加金额 (从索引 4 [记账凭证金额] 开始一直到最后一列)
+            for ($i = 4; $i < $totalColCount; $i++) {
+                $groupedData[$sheetKey]['totals'][$i] += $excelRow[$i];
+            }
+
+            $groupedData[$sheetKey]['data'][] = $excelRow;
+        }
+
+        foreach ($groupedData as &$group) {
+            $group['data'][] = $group['totals'];
+            unset($group['totals']); // 释放内存
+        }
+
+        // 8. 导出逻辑保持不变
+        $file_name = "年度研发支出辅助账汇总统计表_" . date("Y-m-d") . "_". rand(1000,9999);
+        $filename =  $file_name . '.xlsx';
+
+        Excel::store(
+            new ResearchExpenseMultipleSheetExport($groupedData),
+            "public/export/{$filename}"
+        );
+
+        return [true, $filename];
+    }
+
     // 研发支出辅助帐汇总表
-    public function exportFormalSummary(array $data, $user)
+    public function exportFormalSummary1(array $data, $user)
     {
         $service = new StatisticService();
         // 1. 调用业务逻辑获取原始数据
@@ -906,6 +1039,7 @@ class ExportFileService extends Service
             // 遍历所有可能的费用类型,确保 values 数组长度与表头一致
             foreach ($feeTypes as $type) {
                 $feeData = $currentProjectFees->get($type['id']);
+                if($feeData == null) continue;
                 $amount = (float)($feeData['total_amount'] ?? 0);
                 // 2. 累加委托费用 (8.1 和 8.3)
                 $val8_1 += (float)($feeData['entrust1_amount'] ?? 0);
@@ -962,6 +1096,135 @@ class ExportFileService extends Service
         return [true, $filename];
     }
 
+    public function exportFormalSummary(array $data, $user)
+    {
+        $service = new StatisticService();
+        // 1. 调用业务逻辑获取原始数据
+        list($status, $result) = $service->employeeAttendanceMonthStatistic($data, $user);
+        if (!$status) return [false, $result];
+
+        $rawList = $result['list'] ?? [];
+        $feeTypes = $result['fee_type_list'] ?? [];
+
+        // ================== 1. 统一表头与排序 ==================
+        // 定义固定表头并赋予默认 sort
+        $allHeadersTemp = [
+            [
+                'id'       => 'employee_salary', // 用特殊标识代表固定列
+                'title'    => '人员人工费用',
+                'sort'     => -1,
+                'is_fixed' => true
+            ],
+            [
+                'id'       => 'device_depreciation',
+                'title'    => '折旧费用',
+                'sort'     => 1,
+                'is_fixed' => true
+            ]
+        ];
+
+        // 将符合条件的动态表头合并进来
+        foreach ($feeTypes as $value) {
+            if (!$value['is_after']) {
+                $allHeadersTemp[] = [
+                    'id'       => $value['id'],
+                    'title'    => $value['title'],
+                    'sort'     => (int)($value['sort'] ?? 0), // 确保是整型
+                    'is_fixed' => false
+                ];
+            }
+        }
+
+        // 使用 collect 按照 sort 正序排序(值越小越靠前)
+        $sortedHeaders = collect($allHeadersTemp)->sortBy('sort')->values()->all();
+
+        // 提取出最终传给 Excel 的纯文本表头数组
+        $dynamicHeaders = array_column($sortedHeaders, 'title');
+        // =======================================================
+
+        $items = [];
+        foreach ($rawList as $v) {
+            $rowValues = [];
+            $val8_1 = 0; // 委托境内合计
+            $val8_3 = 0; // 委托境外合计
+
+            // 1. 先把当前项目所有的 fee_list 进行全量费用累加(修复漏计 Bug)
+            $currentFeeList = $v['fee_list'] ?? [];
+            foreach ($currentFeeList as $feeData) {
+                $val8_1 += (float)($feeData['entrust1_amount'] ?? 0);
+                $val8_3 += (float)($feeData['entrust2_amount'] ?? 0);
+            }
+
+            // 2. 将当前项目的 fee_list 转为集合,以便按 ID 快速查找对齐
+            $currentProjectFees = collect($currentFeeList)->keyBy('id');
+
+            // 3. 依照排序后的表头填充 Excel 列数据
+            foreach ($sortedHeaders as $header) {
+                if ($header['is_fixed']) {
+                    // 如果是固定的基础两项(人员人工、折旧),直接从主记录 $v 中取值
+                    $rowValues[] = (float)($v[$header['id']] ?? 0);
+                } else {
+                    // 如果是动态科目列
+                    $feeData = $currentProjectFees->get($header['id']);
+                    if ($feeData == null) {
+                        $rowValues[] = 0.0; // 没数据补0,保证列对齐
+                        continue;
+                    }
+
+                    // 如果是其他费用,不填充到动态科目列中(填充 0 占位防错位)
+                    if ($feeData['is_other']) {
+                        $rowValues[] = 0.0;
+                        continue;
+                    }
+
+                    // 正常填充金额
+                    $rowValues[] = (float)($feeData['total_amount'] ?? 0);
+                }
+            }
+
+            $items[] = [
+                'no'     => $v['code'] ?? '',
+                'name'   => $v['title'] ?? '',
+                'status' => (($v['state'] ?? '') == "完结" ? 3 : 2),
+                'type'   => $v['expense_type'] ?? '费用化支出',
+                'values' => $rowValues,
+                'val7_1' => $v['other_amount'],
+                'val7_2' => $v['jj_other_amount'],
+                'val8_1' => $val8_1,
+                'val8_3' => $val8_3,
+            ];
+        }
+
+        // 年份获取逻辑
+        $year = Carbon::parse($data['year'])
+            ->setTimezone(config('app.timezone')) // 转换为 Laravel 配置的时区
+            ->format('Y');
+
+        //获取公司基本信息
+        $company = EmployeeService::getCompanyDetail($user);
+
+        // 3. 组织多 Sheet 格式数据
+        $monthsData = [
+            $year => [
+                'tax_id'          => $company['code'] ?? '',
+                'company_name'    => $company['title'] ?? '',
+                'items'           => $items,
+                'dynamic_headers' => $dynamicHeaders
+            ]
+        ];
+
+        // 4. 执行 Excel 存储
+        $file_name = "研发支出辅助账汇总表_" . date("YmdHis") . "_" . rand(1000, 9999);
+        $filename = $file_name . '.xlsx';
+
+        Excel::store(
+            new \App\Exports\ResearchExpenseSummaryMultipleSheetExport($monthsData),
+            "public/export/{$filename}"
+        );
+
+        return [true, $filename];
+    }
+
     // 人员活动考勤占比
     public function exportActivityTimeCard(array $data, $user)
     {