|
@@ -790,7 +790,7 @@ class ExportFileService extends Service
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 年度研发支出辅助账汇总表
|
|
// 年度研发支出辅助账汇总表
|
|
|
- public function exportResearchExpense(array $data, $user)
|
|
|
|
|
|
|
+ public function exportResearchExpense1(array $data, $user)
|
|
|
{
|
|
{
|
|
|
$service = new StatisticService();
|
|
$service = new StatisticService();
|
|
|
list($status, $result) = $service->auxiliaryStatistic($data, $user);
|
|
list($status, $result) = $service->auxiliaryStatistic($data, $user);
|
|
@@ -869,8 +869,141 @@ class ExportFileService extends Service
|
|
|
return [true, $filename];
|
|
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();
|
|
$service = new StatisticService();
|
|
|
// 1. 调用业务逻辑获取原始数据
|
|
// 1. 调用业务逻辑获取原始数据
|
|
@@ -906,6 +1039,7 @@ class ExportFileService extends Service
|
|
|
// 遍历所有可能的费用类型,确保 values 数组长度与表头一致
|
|
// 遍历所有可能的费用类型,确保 values 数组长度与表头一致
|
|
|
foreach ($feeTypes as $type) {
|
|
foreach ($feeTypes as $type) {
|
|
|
$feeData = $currentProjectFees->get($type['id']);
|
|
$feeData = $currentProjectFees->get($type['id']);
|
|
|
|
|
+ if($feeData == null) continue;
|
|
|
$amount = (float)($feeData['total_amount'] ?? 0);
|
|
$amount = (float)($feeData['total_amount'] ?? 0);
|
|
|
// 2. 累加委托费用 (8.1 和 8.3)
|
|
// 2. 累加委托费用 (8.1 和 8.3)
|
|
|
$val8_1 += (float)($feeData['entrust1_amount'] ?? 0);
|
|
$val8_1 += (float)($feeData['entrust1_amount'] ?? 0);
|
|
@@ -962,6 +1096,135 @@ class ExportFileService extends Service
|
|
|
return [true, $filename];
|
|
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)
|
|
public function exportActivityTimeCard(array $data, $user)
|
|
|
{
|
|
{
|