|
@@ -8,7 +8,6 @@ use App\Model\DailyPwOrderDetails;
|
|
|
use App\Model\Device;
|
|
use App\Model\Device;
|
|
|
use App\Model\Employee;
|
|
use App\Model\Employee;
|
|
|
use App\Model\EmployeeDepartPermission;
|
|
use App\Model\EmployeeDepartPermission;
|
|
|
-use App\Model\EmployeeRole;
|
|
|
|
|
use App\Model\ExpenseClaimsDetails;
|
|
use App\Model\ExpenseClaimsDetails;
|
|
|
use App\Model\Fee;
|
|
use App\Model\Fee;
|
|
|
use App\Model\Item;
|
|
use App\Model\Item;
|
|
@@ -287,7 +286,116 @@ class StatisticService extends StatisticCommonService
|
|
|
return [true, $result];
|
|
return [true, $result];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ public function itemDeviceMonthStatistic($data, $user)
|
|
|
|
|
+ {
|
|
|
|
|
+ // 1. 基础校验与时间初始化
|
|
|
|
|
+ list($status, $month_start, $month_end) = $this->commonRule($data);
|
|
|
|
|
+ if (!$status) return [false, $month_start];
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 获取设备工时数据 (项目+设备+月)
|
|
|
|
|
+ $month_device_list = DailyDwOrderDetails::Clear($user, $data)
|
|
|
|
|
+ ->where("order_time", ">=", $month_start)
|
|
|
|
|
+ ->where("order_time", "<", $month_end)
|
|
|
|
|
+ ->where('del_time', 0)
|
|
|
|
|
+ ->select(
|
|
|
|
|
+ "item_id",
|
|
|
|
|
+ "device_id",
|
|
|
|
|
+ DB::raw("FROM_UNIXTIME(order_time, '%Y-%m') as order_month"),
|
|
|
|
|
+ DB::raw("SUM(total_work_min) as total_work")
|
|
|
|
|
+ )
|
|
|
|
|
+ ->groupBy(DB::raw("FROM_UNIXTIME(order_time, '%Y-%m')"), "item_id", "device_id")->get()->toArray();
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 获取折旧费主表及详情
|
|
|
|
|
+ $monthly_dd_query = MonthlyDdOrder::Clear($user, $data)->where('del_time', 0)
|
|
|
|
|
+ ->where("month", ">=", $month_start)->where("month", "<", $month_end);
|
|
|
|
|
+
|
|
|
|
|
+ $monthly_dd_ids = $monthly_dd_query->pluck('id')->toArray();
|
|
|
|
|
+ $monthly_dd_months = $monthly_dd_query->select('id', DB::raw("FROM_UNIXTIME(month, '%Y-%m') as month_str"))
|
|
|
|
|
+ ->pluck("month_str", 'id')->toArray();
|
|
|
|
|
+
|
|
|
|
|
+ $device_salary_details = MonthlyDdOrderDetails::wherein('main_id', $monthly_dd_ids)
|
|
|
|
|
+ ->select("device_id", "depreciation_amount", "main_id")->get()->toArray();
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 构建高精度折旧池 (单位:分)
|
|
|
|
|
+ $depreciation_pool = [];
|
|
|
|
|
+ foreach ($device_salary_details as $val) {
|
|
|
|
|
+ $m = $monthly_dd_months[$val['main_id']] ?? '';
|
|
|
|
|
+ if ($m) {
|
|
|
|
|
+ $key = $val['device_id'] . '_' . $m;
|
|
|
|
|
+ // 同一个设备在同一个月可能存在多条折旧记录,需累加
|
|
|
|
|
+ $depreciation_pool[$key] = ($depreciation_pool[$key] ?? 0) + (int)round($val['depreciation_amount'] * 100);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 计算全月总工时及初始化余额池
|
|
|
|
|
+ $device_monthly_total_min = [];
|
|
|
|
|
+ foreach ($month_device_list as $row) {
|
|
|
|
|
+ $key = $row['device_id'] . '_' . $row['order_month'];
|
|
|
|
|
+ $device_monthly_total_min[$key] = ($device_monthly_total_min[$key] ?? 0) + $row['total_work'];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $rem_depreciation_cents = $depreciation_pool; // 折旧余额池
|
|
|
|
|
+ $rem_hours_cents = []; // 工时余额池 (小时*100)
|
|
|
|
|
+ foreach ($device_monthly_total_min as $key => $min) {
|
|
|
|
|
+ $rem_hours_cents[$key] = (int)round(($min / 60), 2) * 100;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 6. 统计项目数用于判断“最后一条”
|
|
|
|
|
+ $device_count = collect($month_device_list)->groupBy(fn($i) => $i['device_id'].'_'.$i['order_month'])
|
|
|
|
|
+ ->map(fn($g) => $g->count())->toArray();
|
|
|
|
|
+
|
|
|
|
|
+ // 7. 预加载设备与项目基础信息
|
|
|
|
|
+ $items_ids = collect($month_device_list)->pluck('item_id')->unique()->all();
|
|
|
|
|
+ $device_ids = collect($month_device_list)->pluck('device_id')->unique()->all();
|
|
|
|
|
+
|
|
|
|
|
+ $item_info = Item::TopClear($user, $data)->whereIn('id', $items_ids)->get()->keyBy('id');
|
|
|
|
|
+ $device_info = Device::TopClear($user, $data)->whereIn('id', $device_ids)->get()->keyBy('id');
|
|
|
|
|
|
|
|
|
|
+ // 8. 核心转换逻辑
|
|
|
|
|
+ $item_month_list = collect($month_device_list)->sortBy('order_month')->values()->transform(function ($item) use (
|
|
|
|
|
+ $item_info, $device_info, $depreciation_pool, $device_monthly_total_min,
|
|
|
|
|
+ &$device_count, &$rem_depreciation_cents, &$rem_hours_cents
|
|
|
|
|
+ ) {
|
|
|
|
|
+ $key = $item['device_id'] . '_' . $item['order_month'];
|
|
|
|
|
+ $total_min = $device_monthly_total_min[$key] ?? 0;
|
|
|
|
|
+
|
|
|
|
|
+ $item['item_title'] = $item_info[$item['item_id']]->title ?? "未知项目";
|
|
|
|
|
+ $item['item_code'] = $item_info[$item['item_id']]->code ?? "-";
|
|
|
|
|
+ $item['device_title'] = $device_info[$item['device_id']]->title ?? "未知设备";
|
|
|
|
|
+ $item['device_original'] = $device_info[$item['device_id']]->original_value ?? 0;
|
|
|
|
|
+
|
|
|
|
|
+ $item['month'] = $item['order_month'];
|
|
|
|
|
+ $item['total_depreciatio'] = ($depreciation_pool[$key] ?? 0) / 100;
|
|
|
|
|
+ $item['total_hours'] = round($total_min / 60, 2);
|
|
|
|
|
+
|
|
|
|
|
+ // 分摊比例计算
|
|
|
|
|
+ $ratio = $total_min > 0 ? ($item['total_work'] / $total_min) : 0;
|
|
|
|
|
+ $item['ratio'] = round($ratio, 4);
|
|
|
|
|
+
|
|
|
|
|
+ if (--$device_count[$key] > 0) {
|
|
|
|
|
+ // 非最后一条项目
|
|
|
|
|
+ $cur_hours = round($item['total_work'] / 60, 2);
|
|
|
|
|
+ $item['hours'] = $cur_hours;
|
|
|
|
|
+ $rem_hours_cents[$key] -= (int)round($cur_hours * 100);
|
|
|
|
|
+
|
|
|
|
|
+ $cur_depre = round($item['total_depreciatio'] * $ratio, 2);
|
|
|
|
|
+ $item['allocated_depreciatio'] = $cur_depre;
|
|
|
|
|
+ $rem_depreciation_cents[$key] -= (int)round($cur_depre * 100);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 最后一条项目,余额补平
|
|
|
|
|
+ $item['hours'] = round(($rem_hours_cents[$key] ?? 0) / 100, 2);
|
|
|
|
|
+ $item['allocated_depreciatio'] = round(($rem_depreciation_cents[$key] ?? 0) / 100, 2);
|
|
|
|
|
+ // 比例也做个平账展示
|
|
|
|
|
+ $item['ratio'] = round($item['hours'] / ($item['total_hours'] ?: 1), 4);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $item;
|
|
|
|
|
+ })->all();
|
|
|
|
|
+
|
|
|
|
|
+ return [true, $item_month_list];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //原方法---
|
|
|
public function employeeMonthSalaryStatistic1($data, $user)
|
|
public function employeeMonthSalaryStatistic1($data, $user)
|
|
|
{
|
|
{
|
|
|
//项目编码、项目名称、天数、工资、日期
|
|
//项目编码、项目名称、天数、工资、日期
|
|
@@ -560,115 +668,6 @@ class StatisticService extends StatisticCommonService
|
|
|
return [true, $item_month_list];
|
|
return [true, $item_month_list];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public function itemDeviceMonthStatistic($data, $user)
|
|
|
|
|
- {
|
|
|
|
|
- // 1. 基础校验与时间初始化
|
|
|
|
|
- list($status, $month_start, $month_end) = $this->commonRule($data);
|
|
|
|
|
- if (!$status) return [false, $month_start];
|
|
|
|
|
-
|
|
|
|
|
- // 2. 获取设备工时数据 (项目+设备+月)
|
|
|
|
|
- $month_device_list = DailyDwOrderDetails::Clear($user, $data)
|
|
|
|
|
- ->where("order_time", ">=", $month_start)
|
|
|
|
|
- ->where("order_time", "<", $month_end)
|
|
|
|
|
- ->where('del_time', 0)
|
|
|
|
|
- ->select(
|
|
|
|
|
- "item_id",
|
|
|
|
|
- "device_id",
|
|
|
|
|
- DB::raw("FROM_UNIXTIME(order_time, '%Y-%m') as order_month"),
|
|
|
|
|
- DB::raw("SUM(total_work_min) as total_work")
|
|
|
|
|
- )
|
|
|
|
|
- ->groupBy(DB::raw("FROM_UNIXTIME(order_time, '%Y-%m')"), "item_id", "device_id")->get()->toArray();
|
|
|
|
|
-
|
|
|
|
|
- // 3. 获取折旧费主表及详情
|
|
|
|
|
- $monthly_dd_query = MonthlyDdOrder::Clear($user, $data)->where('del_time', 0)
|
|
|
|
|
- ->where("month", ">=", $month_start)->where("month", "<", $month_end);
|
|
|
|
|
-
|
|
|
|
|
- $monthly_dd_ids = $monthly_dd_query->pluck('id')->toArray();
|
|
|
|
|
- $monthly_dd_months = $monthly_dd_query->select('id', DB::raw("FROM_UNIXTIME(month, '%Y-%m') as month_str"))
|
|
|
|
|
- ->pluck("month_str", 'id')->toArray();
|
|
|
|
|
-
|
|
|
|
|
- $device_salary_details = MonthlyDdOrderDetails::wherein('main_id', $monthly_dd_ids)
|
|
|
|
|
- ->select("device_id", "depreciation_amount", "main_id")->get()->toArray();
|
|
|
|
|
-
|
|
|
|
|
- // 4. 构建高精度折旧池 (单位:分)
|
|
|
|
|
- $depreciation_pool = [];
|
|
|
|
|
- foreach ($device_salary_details as $val) {
|
|
|
|
|
- $m = $monthly_dd_months[$val['main_id']] ?? '';
|
|
|
|
|
- if ($m) {
|
|
|
|
|
- $key = $val['device_id'] . '_' . $m;
|
|
|
|
|
- // 同一个设备在同一个月可能存在多条折旧记录,需累加
|
|
|
|
|
- $depreciation_pool[$key] = ($depreciation_pool[$key] ?? 0) + (int)round($val['depreciation_amount'] * 100);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 5. 计算全月总工时及初始化余额池
|
|
|
|
|
- $device_monthly_total_min = [];
|
|
|
|
|
- foreach ($month_device_list as $row) {
|
|
|
|
|
- $key = $row['device_id'] . '_' . $row['order_month'];
|
|
|
|
|
- $device_monthly_total_min[$key] = ($device_monthly_total_min[$key] ?? 0) + $row['total_work'];
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- $rem_depreciation_cents = $depreciation_pool; // 折旧余额池
|
|
|
|
|
- $rem_hours_cents = []; // 工时余额池 (小时*100)
|
|
|
|
|
- foreach ($device_monthly_total_min as $key => $min) {
|
|
|
|
|
- $rem_hours_cents[$key] = (int)round(($min / 60), 2) * 100;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 6. 统计项目数用于判断“最后一条”
|
|
|
|
|
- $device_count = collect($month_device_list)->groupBy(fn($i) => $i['device_id'].'_'.$i['order_month'])
|
|
|
|
|
- ->map(fn($g) => $g->count())->toArray();
|
|
|
|
|
-
|
|
|
|
|
- // 7. 预加载设备与项目基础信息
|
|
|
|
|
- $items_ids = collect($month_device_list)->pluck('item_id')->unique()->all();
|
|
|
|
|
- $device_ids = collect($month_device_list)->pluck('device_id')->unique()->all();
|
|
|
|
|
-
|
|
|
|
|
- $item_info = Item::TopClear($user, $data)->whereIn('id', $items_ids)->get()->keyBy('id');
|
|
|
|
|
- $device_info = Device::TopClear($user, $data)->whereIn('id', $device_ids)->get()->keyBy('id');
|
|
|
|
|
-
|
|
|
|
|
- // 8. 核心转换逻辑
|
|
|
|
|
- $item_month_list = collect($month_device_list)->sortBy('order_month')->values()->transform(function ($item) use (
|
|
|
|
|
- $item_info, $device_info, $depreciation_pool, $device_monthly_total_min,
|
|
|
|
|
- &$device_count, &$rem_depreciation_cents, &$rem_hours_cents
|
|
|
|
|
- ) {
|
|
|
|
|
- $key = $item['device_id'] . '_' . $item['order_month'];
|
|
|
|
|
- $total_min = $device_monthly_total_min[$key] ?? 0;
|
|
|
|
|
-
|
|
|
|
|
- $item['item_title'] = $item_info[$item['item_id']]->title ?? "未知项目";
|
|
|
|
|
- $item['item_code'] = $item_info[$item['item_id']]->code ?? "-";
|
|
|
|
|
- $item['device_title'] = $device_info[$item['device_id']]->title ?? "未知设备";
|
|
|
|
|
- $item['device_original'] = $device_info[$item['device_id']]->original_value ?? 0;
|
|
|
|
|
-
|
|
|
|
|
- $item['month'] = $item['order_month'];
|
|
|
|
|
- $item['total_depreciatio'] = ($depreciation_pool[$key] ?? 0) / 100;
|
|
|
|
|
- $item['total_hours'] = round($total_min / 60, 2);
|
|
|
|
|
-
|
|
|
|
|
- // 分摊比例计算
|
|
|
|
|
- $ratio = $total_min > 0 ? ($item['total_work'] / $total_min) : 0;
|
|
|
|
|
- $item['ratio'] = round($ratio, 4);
|
|
|
|
|
-
|
|
|
|
|
- if (--$device_count[$key] > 0) {
|
|
|
|
|
- // 非最后一条项目
|
|
|
|
|
- $cur_hours = round($item['total_work'] / 60, 2);
|
|
|
|
|
- $item['hours'] = $cur_hours;
|
|
|
|
|
- $rem_hours_cents[$key] -= (int)round($cur_hours * 100);
|
|
|
|
|
-
|
|
|
|
|
- $cur_depre = round($item['total_depreciatio'] * $ratio, 2);
|
|
|
|
|
- $item['allocated_depreciatio'] = $cur_depre;
|
|
|
|
|
- $rem_depreciation_cents[$key] -= (int)round($cur_depre * 100);
|
|
|
|
|
- } else {
|
|
|
|
|
- // 最后一条项目,余额补平
|
|
|
|
|
- $item['hours'] = round(($rem_hours_cents[$key] ?? 0) / 100, 2);
|
|
|
|
|
- $item['allocated_depreciatio'] = round(($rem_depreciation_cents[$key] ?? 0) / 100, 2);
|
|
|
|
|
- // 比例也做个平账展示
|
|
|
|
|
- $item['ratio'] = round($item['hours'] / ($item['total_hours'] ?: 1), 4);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return $item;
|
|
|
|
|
- })->all();
|
|
|
|
|
-
|
|
|
|
|
- return [true, $item_month_list];
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
public function itemDeviceMonthStatistic1($data, $user)
|
|
public function itemDeviceMonthStatistic1($data, $user)
|
|
|
{
|
|
{
|
|
|
//项目编码、项目名称、设备名称、项目工时、研发工时占比、设备原值、设备折旧额、本项目帐面归集的折旧额、确定的本项目折旧额、加计调整金额、当月工时、日期
|
|
//项目编码、项目名称、设备名称、项目工时、研发工时占比、设备原值、设备折旧额、本项目帐面归集的折旧额、确定的本项目折旧额、加计调整金额、当月工时、日期
|
|
@@ -804,70 +803,249 @@ class StatisticService extends StatisticCommonService
|
|
|
return [true, $item_month_list];
|
|
return [true, $item_month_list];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 根据前端 ISO 时间字符串获取该年份的起止日期和时间戳
|
|
|
|
|
- * 适配:2019-12-31T16:00:00.000Z 这种带时区的数据
|
|
|
|
|
- *
|
|
|
|
|
- * @param string $isoStr 前端传来的时间字符串
|
|
|
|
|
- * @return array|null
|
|
|
|
|
- */
|
|
|
|
|
- public function getYearRangeInfo($isoStr)
|
|
|
|
|
- {
|
|
|
|
|
- if (empty($isoStr)) return null;
|
|
|
|
|
-
|
|
|
|
|
- try {
|
|
|
|
|
- // 1. 解析 ISO 8601 字符串
|
|
|
|
|
- $date = new \DateTime($isoStr);
|
|
|
|
|
-
|
|
|
|
|
- // 2. 强制转为中国时区(PRC),处理 16:00:00Z 这种 UTC 偏移
|
|
|
|
|
- $date->setTimezone(new \DateTimeZone('PRC'));
|
|
|
|
|
-
|
|
|
|
|
- // 3. 提取年份
|
|
|
|
|
- $year = $date->format('Y');
|
|
|
|
|
-
|
|
|
|
|
- // 4. 构造日期字符串
|
|
|
|
|
- $startDate = $year . "-01-01";
|
|
|
|
|
- $endDate = $year . "-12-31";
|
|
|
|
|
-
|
|
|
|
|
- return [
|
|
|
|
|
- $startDate,
|
|
|
|
|
- $endDate,
|
|
|
|
|
- ];
|
|
|
|
|
- } catch (\Exception $e) {
|
|
|
|
|
-// var_dump($e->getMessage());die;
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
public function employeeAttendanceMonthStatistic($data, $user)
|
|
public function employeeAttendanceMonthStatistic($data, $user)
|
|
|
{
|
|
{
|
|
|
- //项目编码、项目名称、项目状态、支出类型、允许加计扣除金额合计、人员人工费用、折旧费用、其他费用、前N项小计、其他相关费用合计、委内费用、委外费用、
|
|
|
|
|
|
|
+ // 1. 基础规则验证
|
|
|
list($status, $month_start, $month_end) = $this->commonRule($data);
|
|
list($status, $month_start, $month_end) = $this->commonRule($data);
|
|
|
- if (!$status) {
|
|
|
|
|
- return [false, $month_start];
|
|
|
|
|
- }
|
|
|
|
|
- //第一步确定项目
|
|
|
|
|
- $item = Item::TopClear($user, $data);
|
|
|
|
|
- $item_list = $item->where('del_time', 0)
|
|
|
|
|
|
|
+ if (!$status) return [false, $month_start];
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 确定该区间内涉及的项目
|
|
|
|
|
+ $item_list = Item::TopClear($user, $data)
|
|
|
|
|
+ ->where('del_time', 0)
|
|
|
->where(function ($query) use ($month_start, $month_end) {
|
|
->where(function ($query) use ($month_start, $month_end) {
|
|
|
$query->where('start_time', '>=', $month_start)
|
|
$query->where('start_time', '>=', $month_start)
|
|
|
->where('end_time', '<', $month_end);
|
|
->where('end_time', '<', $month_end);
|
|
|
- })->select("code", "title", "start_time", "end_time", "id", "state")->orderby("start_time", "asc")->get()->toArray();
|
|
|
|
|
- $item_key_list = [];
|
|
|
|
|
- foreach ($item_list as $v) {
|
|
|
|
|
- $item_key_list[$v['id']] = $v;
|
|
|
|
|
- }
|
|
|
|
|
- //第二步确定人员费用
|
|
|
|
|
|
|
+ })
|
|
|
|
|
+ ->select("code", "title", "start_time", "end_time", "id", "state")
|
|
|
|
|
+ ->orderby("start_time", "asc")
|
|
|
|
|
+ ->get();
|
|
|
|
|
+
|
|
|
|
|
+ $item_key_list = $item_list->keyBy('id')->toArray();
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 获取精准分摊的人员费用(内部已处理精度,返回单位为:分)
|
|
|
$item_employee_list = $this->getEmployeeItemSalary($month_start, $month_end, $data, $user);
|
|
$item_employee_list = $this->getEmployeeItemSalary($month_start, $month_end, $data, $user);
|
|
|
- //第三步确定折旧费用
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 获取精准分摊的折旧费用(内部已处理精度,返回单位为:分)
|
|
|
$item_device_list = $this->getDeviceItemSalary($month_start, $month_end, $data, $user);
|
|
$item_device_list = $this->getDeviceItemSalary($month_start, $month_end, $data, $user);
|
|
|
- //第四步其他费用
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 获取其他报销费用
|
|
|
list($item_fee_list, $fee_type_list) = $this->getFeeItemSalary($month_start, $month_end, $data, $user);
|
|
list($item_fee_list, $fee_type_list) = $this->getFeeItemSalary($month_start, $month_end, $data, $user);
|
|
|
|
|
|
|
|
- //组合所有数据
|
|
|
|
|
- $return = [];
|
|
|
|
|
- foreach ($item_key_list as $v) {
|
|
|
|
|
|
|
+ // 6. 组合所有数据
|
|
|
|
|
+ $result = [];
|
|
|
|
|
+ foreach ($item_key_list as $itemId => $v) {
|
|
|
|
|
+
|
|
|
|
|
+ // 从分摊结果中取值,注意单位换算回“元”
|
|
|
|
|
+ $salary_cents = $item_employee_list[$itemId]['salary'] ?? 0;
|
|
|
|
|
+ $dep_cents = $item_device_list[$itemId]['depreciation'] ?? 0;
|
|
|
|
|
+
|
|
|
|
|
+ $item_value = [
|
|
|
|
|
+ "code" => $v['code'],
|
|
|
|
|
+ "title" => $v['title'],
|
|
|
|
|
+ "state" => $v['state'] == 3 ? "完结" : "进行中",
|
|
|
|
|
+ "employee_salary" => round($salary_cents / 100, 2),
|
|
|
|
|
+ "device_depreciation" => round($dep_cents / 100, 2),
|
|
|
|
|
+ "expense_type" => "费用化支出",
|
|
|
|
|
+ "fee_list" => collect($item_fee_list[$itemId] ?? [])->values()->all(),
|
|
|
|
|
+ ];
|
|
|
|
|
+ $result[] = $item_value;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return [true, ["list" => $result, "fee_type_list" => $fee_type_list]];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function getEmployeeItemSalary($month_start, $month_end, $data, $user)
|
|
|
|
|
+ {
|
|
|
|
|
+ // 获取工时明细(按月、人、项目分组)
|
|
|
|
|
+ $month_employee_list = DailyPwOrderDetails::Clear($user, $data)
|
|
|
|
|
+ ->where("order_time", ">=", $month_start)
|
|
|
|
|
+ ->where("order_time", "<", $month_end)
|
|
|
|
|
+ ->where('del_time', 0)
|
|
|
|
|
+ ->select(
|
|
|
|
|
+ "item_id",
|
|
|
|
|
+ "employee_id",
|
|
|
|
|
+ DB::raw("FROM_UNIXTIME(order_time, '%Y-%m') as order_month"),
|
|
|
|
|
+ DB::raw("SUM(total_work_min) as total_work")
|
|
|
|
|
+ )
|
|
|
|
|
+ ->groupBy("order_month", "item_id", "employee_id")
|
|
|
|
|
+ ->get()->toArray();
|
|
|
|
|
+
|
|
|
|
|
+ // 获取工资主表并建立月份映射
|
|
|
|
|
+ $ps_query = MonthlyPsOrder::Clear($user, $data)
|
|
|
|
|
+ ->where('del_time', 0)
|
|
|
|
|
+ ->where("month", ">=", $month_start)
|
|
|
|
|
+ ->where("month", "<", $month_end);
|
|
|
|
|
+
|
|
|
|
|
+ $ps_ids = $ps_query->pluck('id')->toArray();
|
|
|
|
|
+ $month_map = $ps_query->select('id', DB::raw("FROM_UNIXTIME(month, '%Y-%m') as month_str"))
|
|
|
|
|
+ ->pluck('month_str', 'id')->toArray();
|
|
|
|
|
+
|
|
|
|
|
+ // 获取工资明细并转为整数“分”
|
|
|
|
|
+ $salary_details = MonthlyPsOrderDetails::whereIn('main_id', $ps_ids)
|
|
|
|
|
+ ->select("employee_id", "main_id", DB::raw("(base_salary + performance_salary + bonus + other) as salary"))
|
|
|
|
|
+ ->get();
|
|
|
|
|
+
|
|
|
|
|
+ $all_salary_pool = []; // 存放 [人员_月份 => 总金额分]
|
|
|
|
|
+ foreach ($salary_details as $val) {
|
|
|
|
|
+ $m = $month_map[$val['main_id']] ?? '';
|
|
|
|
|
+ if ($m) {
|
|
|
|
|
+ $k = $val['employee_id'] . '_' . $m;
|
|
|
|
|
+ $all_salary_pool[$k] = (int)round($val['salary'] * 100);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 统计每个人每月的总工时和参与的项目数(用于尾差平账)
|
|
|
|
|
+ $emp_monthly_total_min = [];
|
|
|
|
|
+ $emp_item_count = [];
|
|
|
|
|
+ foreach ($month_employee_list as $row) {
|
|
|
|
|
+ $k = $row['employee_id'] . '_' . $row['order_month'];
|
|
|
|
|
+ $emp_monthly_total_min[$k] = ($emp_monthly_total_min[$k] ?? 0) + $row['total_work'];
|
|
|
|
|
+ $emp_item_count[$k] = ($emp_item_count[$k] ?? 0) + 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $rem_salary = $all_salary_pool; // 剩余金额池
|
|
|
|
|
+ $return_item_list = [];
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($month_employee_list as $item) {
|
|
|
|
|
+ $k = $item['employee_id'] . '_' . $item['order_month'];
|
|
|
|
|
+ $total_s = $all_salary_pool[$k] ?? 0;
|
|
|
|
|
+ $total_m = $emp_monthly_total_min[$k] ?? 0;
|
|
|
|
|
+
|
|
|
|
|
+ if ($total_m > 0 && --$emp_item_count[$k] > 0) {
|
|
|
|
|
+ // 非最后一个项目:按比例计算分值(取整,余额存入池子)
|
|
|
|
|
+ $allocated = (int)floor(($item['total_work'] / $total_m) * $total_s);
|
|
|
|
|
+ $rem_salary[$k] -= $allocated;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 最后一个项目:直接取剩余全部金额
|
|
|
|
|
+ $allocated = $rem_salary[$k] ?? 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $itemId = $item['item_id'];
|
|
|
|
|
+ if (!isset($return_item_list[$itemId])) $return_item_list[$itemId]['salary'] = 0;
|
|
|
|
|
+ $return_item_list[$itemId]['salary'] += $allocated;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $return_item_list;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function getDeviceItemSalary($month_start, $month_end, $data, $user)
|
|
|
|
|
+ {
|
|
|
|
|
+ // 获取设备工时明细
|
|
|
|
|
+ $month_device_list = DailyDwOrderDetails::Clear($user, $data)
|
|
|
|
|
+ ->where("order_time", ">=", $month_start)
|
|
|
|
|
+ ->where("order_time", "<", $month_end)
|
|
|
|
|
+ ->where('del_time', 0)
|
|
|
|
|
+ ->select(
|
|
|
|
|
+ "item_id",
|
|
|
|
|
+ "device_id",
|
|
|
|
|
+ DB::raw("FROM_UNIXTIME(order_time, '%Y-%m') as order_month"),
|
|
|
|
|
+ DB::raw("SUM(total_work_min) as total_work")
|
|
|
|
|
+ )
|
|
|
|
|
+ ->groupBy("order_month", "item_id", "device_id")
|
|
|
|
|
+ ->get()->toArray();
|
|
|
|
|
+
|
|
|
|
|
+ // 获取折旧主表
|
|
|
|
|
+ $dd_query = MonthlyDdOrder::Clear($user, $data)
|
|
|
|
|
+ ->where('del_time', 0)
|
|
|
|
|
+ ->where("month", ">=", $month_start)
|
|
|
|
|
+ ->where("month", "<", $month_end);
|
|
|
|
|
+
|
|
|
|
|
+ $dd_ids = $dd_query->pluck('id')->toArray();
|
|
|
|
|
+ $month_map = $dd_query->select('id', DB::raw("FROM_UNIXTIME(month, '%Y-%m') as month_str"))
|
|
|
|
|
+ ->pluck("month_str", 'id')->toArray();
|
|
|
|
|
+
|
|
|
|
|
+ // 获取折旧明细并转为整数“分”
|
|
|
|
|
+ $device_details = MonthlyDdOrderDetails::whereIn('main_id', $dd_ids)
|
|
|
|
|
+ ->select("device_id", "depreciation_amount", "main_id")
|
|
|
|
|
+ ->get();
|
|
|
|
|
+
|
|
|
|
|
+ $all_dep_pool = [];
|
|
|
|
|
+ foreach ($device_details as $val) {
|
|
|
|
|
+ $m = $month_map[$val['main_id']] ?? '';
|
|
|
|
|
+ if ($m) {
|
|
|
|
|
+ $k = $val['device_id'] . '_' . $m;
|
|
|
|
|
+ $all_dep_pool[$k] = (int)round($val['depreciation_amount'] * 100);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 统计设备每月总工时和项目数
|
|
|
|
|
+ $dev_monthly_total_min = [];
|
|
|
|
|
+ $dev_item_count = [];
|
|
|
|
|
+ foreach ($month_device_list as $row) {
|
|
|
|
|
+ $k = $row['device_id'] . '_' . $row['order_month'];
|
|
|
|
|
+ $dev_monthly_total_min[$k] = ($dev_monthly_total_min[$k] ?? 0) + $row['total_work'];
|
|
|
|
|
+ $dev_item_count[$k] = ($dev_item_count[$k] ?? 0) + 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $rem_dep = $all_dep_pool;
|
|
|
|
|
+ $return_item_list = [];
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($month_device_list as $item) {
|
|
|
|
|
+ $k = $item['device_id'] . '_' . $item['order_month'];
|
|
|
|
|
+ $total_d = $all_dep_pool[$k] ?? 0;
|
|
|
|
|
+ $total_m = $dev_monthly_total_min[$k] ?? 0;
|
|
|
|
|
+
|
|
|
|
|
+ if ($total_m > 0 && --$dev_item_count[$k] > 0) {
|
|
|
|
|
+ $allocated = (int)floor(($item['total_work'] / $total_m) * $total_d);
|
|
|
|
|
+ $rem_dep[$k] -= $allocated;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $allocated = $rem_dep[$k] ?? 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $itemId = $item['item_id'];
|
|
|
|
|
+ if (!isset($return_item_list[$itemId])) $return_item_list[$itemId]['depreciation'] = 0;
|
|
|
|
|
+ $return_item_list[$itemId]['depreciation'] += $allocated;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $return_item_list;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function getFeeItemSalary($month_start, $month_end, $data, $user)
|
|
|
|
|
+ {
|
|
|
|
|
+ //确认所有项目、费用
|
|
|
|
|
+ $expense = ExpenseClaimsDetails::Clear($user, $data);
|
|
|
|
|
+ $expense_list = $expense->where("claim_date", ">=", $month_start)->where("claim_date", "<", $month_end)
|
|
|
|
|
+ ->where('del_time', 0)
|
|
|
|
|
+ ->select(
|
|
|
|
|
+ "fee_id",
|
|
|
|
|
+ "amount",
|
|
|
|
|
+ "item_id",
|
|
|
|
|
+ "entrust_type"
|
|
|
|
|
+ )->get()->toArray();
|
|
|
|
|
+ //需要根据分类去汇总
|
|
|
|
|
+ $fee = Fee::TopClear($user, $data);
|
|
|
|
|
+ $fee = $fee->where('del_time', 0)->orderBy("sort", 'desc')->get()->toArray();
|
|
|
|
|
+ return $this->groupListByRoot($expense_list, $fee);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //原方法-------
|
|
|
|
|
+ public function employeeAttendanceMonthStatistic1($data, $user)
|
|
|
|
|
+ {
|
|
|
|
|
+ //项目编码、项目名称、项目状态、支出类型、允许加计扣除金额合计、人员人工费用、折旧费用、其他费用、前N项小计、其他相关费用合计、委内费用、委外费用、
|
|
|
|
|
+ list($status, $month_start, $month_end) = $this->commonRule($data);
|
|
|
|
|
+ if (!$status) return [false, $month_start];
|
|
|
|
|
+
|
|
|
|
|
+ //第一步确定项目
|
|
|
|
|
+ $item = Item::TopClear($user, $data);
|
|
|
|
|
+ $item_list = $item->where('del_time', 0)
|
|
|
|
|
+ ->where(function ($query) use ($month_start, $month_end) {
|
|
|
|
|
+ $query->where('start_time', '>=', $month_start)
|
|
|
|
|
+ ->where('end_time', '<', $month_end);
|
|
|
|
|
+ })->select("code", "title", "start_time", "end_time", "id", "state")->orderby("start_time", "asc")->get()->toArray();
|
|
|
|
|
+ $item_key_list = [];
|
|
|
|
|
+ foreach ($item_list as $v) {
|
|
|
|
|
+ $item_key_list[$v['id']] = $v;
|
|
|
|
|
+ }
|
|
|
|
|
+ //第二步确定人员费用
|
|
|
|
|
+ $item_employee_list = $this->getEmployeeItemSalary($month_start, $month_end, $data, $user);
|
|
|
|
|
+ //第三步确定折旧费用
|
|
|
|
|
+ $item_device_list = $this->getDeviceItemSalary($month_start, $month_end, $data, $user);
|
|
|
|
|
+ //第四步其他费用
|
|
|
|
|
+ list($item_fee_list, $fee_type_list) = $this->getFeeItemSalary($month_start, $month_end, $data, $user);
|
|
|
|
|
+
|
|
|
|
|
+ //组合所有数据
|
|
|
|
|
+ $return = [];
|
|
|
|
|
+ foreach ($item_key_list as $v) {
|
|
|
|
|
|
|
|
//其他费用是个数组
|
|
//其他费用是个数组
|
|
|
$item_value = [
|
|
$item_value = [
|
|
@@ -885,7 +1063,7 @@ class StatisticService extends StatisticCommonService
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private function getEmployeeItemSalary($month_start, $month_end, $data, $user)
|
|
|
|
|
|
|
+ private function getEmployeeItemSalary1($month_start, $month_end, $data, $user)
|
|
|
{
|
|
{
|
|
|
$month_employee = DailyPwOrderDetails::Clear($user, $data);
|
|
$month_employee = DailyPwOrderDetails::Clear($user, $data);
|
|
|
$month_employee_list = $month_employee->where("order_time", ">=", $month_start)->where("order_time", "<", $month_end)
|
|
$month_employee_list = $month_employee->where("order_time", ">=", $month_start)->where("order_time", "<", $month_end)
|
|
@@ -993,7 +1171,7 @@ class StatisticService extends StatisticCommonService
|
|
|
return $return_item_list;
|
|
return $return_item_list;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private function getDeviceItemSalary($month_start, $month_end, $data, $user)
|
|
|
|
|
|
|
+ private function getDeviceItemSalary1($month_start, $month_end, $data, $user)
|
|
|
{
|
|
{
|
|
|
//确认所有项目、设备、设备工时
|
|
//确认所有项目、设备、设备工时
|
|
|
$month_device = DailyDwOrderDetails::Clear($user, $data);
|
|
$month_device = DailyDwOrderDetails::Clear($user, $data);
|
|
@@ -1093,24 +1271,6 @@ class StatisticService extends StatisticCommonService
|
|
|
return $return_item_list;
|
|
return $return_item_list;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private function getFeeItemSalary($month_start, $month_end, $data, $user)
|
|
|
|
|
- {
|
|
|
|
|
- //确认所有项目、费用
|
|
|
|
|
- $expense = ExpenseClaimsDetails::Clear($user, $data);
|
|
|
|
|
- $expense_list = $expense->where("claim_date", ">=", $month_start)->where("claim_date", "<", $month_end)
|
|
|
|
|
- ->where('del_time', 0)
|
|
|
|
|
- ->select(
|
|
|
|
|
- "fee_id",
|
|
|
|
|
- "amount",
|
|
|
|
|
- "item_id",
|
|
|
|
|
- "entrust_type"
|
|
|
|
|
- )->get()->toArray();
|
|
|
|
|
- //需要根据分类去汇总
|
|
|
|
|
- $fee = Fee::TopClear($user, $data);
|
|
|
|
|
- $fee = $fee->where('del_time', 0)->orderBy("sort", 'desc')->get()->toArray();
|
|
|
|
|
- return $this->groupListByRoot($expense_list, $fee);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
/**
|
|
/**
|
|
|
* 将报销明细按照一级费用和项目分类进行分组
|
|
* 将报销明细按照一级费用和项目分类进行分组
|
|
|
* * @param array $list 报销明细列表 (含 fee_id, amount 等)
|
|
* * @param array $list 报销明细列表 (含 fee_id, amount 等)
|
|
@@ -1200,55 +1360,45 @@ class StatisticService extends StatisticCommonService
|
|
|
{
|
|
{
|
|
|
list($status, $month_start, $month_end) = $this->commonRule($data);
|
|
list($status, $month_start, $month_end) = $this->commonRule($data);
|
|
|
if (!$status) return [false, $month_start];
|
|
if (!$status) return [false, $month_start];
|
|
|
- //项目编码、项目名称、项目状态、凭证日期、凭证种类、凭证号数、凭证摘要、会计凭证归集金额、N个一级费用类型、委内、委外
|
|
|
|
|
|
|
|
|
|
- //确认所有项目
|
|
|
|
|
- $item = Item::TopClear($user, $data);
|
|
|
|
|
- $item_list = $item->where('del_time', 0)
|
|
|
|
|
|
|
+ // 1. 获取项目列表
|
|
|
|
|
+ $item_list = Item::TopClear($user, $data)->where('del_time', 0)
|
|
|
->where(function ($query) use ($month_start, $month_end) {
|
|
->where(function ($query) use ($month_start, $month_end) {
|
|
|
- $query->where('start_time', '>=', $month_start)
|
|
|
|
|
- ->where('end_time', '<', $month_end);
|
|
|
|
|
- })->select("code", "title", "start_time", "end_time", "id", "state")->orderby("start_time", "asc")->get()->toArray();
|
|
|
|
|
- $item_key_list = [];
|
|
|
|
|
- foreach ($item_list as $v) {
|
|
|
|
|
- $item_key_list[$v['id']] = $v;
|
|
|
|
|
- }
|
|
|
|
|
- //获取该区间内所有项目人工费、折旧费
|
|
|
|
|
|
|
+ $query->where('start_time', '>=', $month_start)->where('end_time', '<', $month_end);
|
|
|
|
|
+ })->select("code", "title", "id", "state")->orderby("start_time", "asc")->get()->keyBy('id')->toArray();
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 获取分摊的人工和折旧 (此时结果内部已是“分”)
|
|
|
$item_salary = $this->auxiliaryEmployee($user, $data, $month_start, $month_end);
|
|
$item_salary = $this->auxiliaryEmployee($user, $data, $month_start, $month_end);
|
|
|
$device_depreciation = $this->auxiliaryDevice($user, $data, $month_start, $month_end);
|
|
$device_depreciation = $this->auxiliaryDevice($user, $data, $month_start, $month_end);
|
|
|
- $fee = Fee::TopClear($user, $data);
|
|
|
|
|
- $fee = $fee->where('del_time', 0)->orderBy("sort", 'desc')->get()->toArray();
|
|
|
|
|
- $auxiliary = AuxiliaryAccountDetails::Clear($user, $data);
|
|
|
|
|
- $auxiliary_list = $auxiliary->where("voucher_date", ">=", $month_start)->where("voucher_date", "<", $month_end)
|
|
|
|
|
- ->where('del_time', 0)
|
|
|
|
|
- ->select(
|
|
|
|
|
- "item_id",
|
|
|
|
|
- "voucher_date",
|
|
|
|
|
- "voucher_type",
|
|
|
|
|
- "voucher_no",
|
|
|
|
|
- "voucher_remark",
|
|
|
|
|
- "voucher_amount",
|
|
|
|
|
- "aggregation_amount",
|
|
|
|
|
- "entrust_type",
|
|
|
|
|
- "entrust1_amount",
|
|
|
|
|
- "entrust2_amount",
|
|
|
|
|
- "entrust2_amount",
|
|
|
|
|
- "total_amount",
|
|
|
|
|
- "fee_id",
|
|
|
|
|
- "type"
|
|
|
|
|
- )->get()->toArray();
|
|
|
|
|
- list($fee_amount, $fee_type_list) = $this->auxiliaryGroupListByRoot($auxiliary_list, $fee);
|
|
|
|
|
|
|
|
|
|
- //找到项目和设备的费用然后进行比例计算
|
|
|
|
|
|
|
+ // 3. 处理凭证费用
|
|
|
|
|
+ $fee = Fee::TopClear($user, $data)->where('del_time', 0)->orderBy("sort", 'desc')->get()->toArray();
|
|
|
|
|
+ $auxiliary_list = AuxiliaryAccountDetails::Clear($user, $data)
|
|
|
|
|
+ ->where("voucher_date", ">=", $month_start)->where("voucher_date", "<", $month_end)
|
|
|
|
|
+ ->where('del_time', 0)->get()->toArray();
|
|
|
|
|
+
|
|
|
|
|
+ list($fee_amount, $fee_type_list) = $this->auxiliaryGroupListByRoot($auxiliary_list, $fee);
|
|
|
|
|
|
|
|
$return = [];
|
|
$return = [];
|
|
|
foreach ($fee_amount as $v) {
|
|
foreach ($fee_amount as $v) {
|
|
|
- //人工费用
|
|
|
|
|
|
|
+ $v_month = date("Y-m", $v['voucher_date']);
|
|
|
|
|
+
|
|
|
|
|
+ // 类型 1(人工) 或 2(折旧) 需要遍历项目进行分摊显示
|
|
|
if ($v['type'] == 1 || $v['type'] == 2) {
|
|
if ($v['type'] == 1 || $v['type'] == 2) {
|
|
|
-// var_dump();
|
|
|
|
|
- foreach ($item_key_list as $vv) {
|
|
|
|
|
- if(!isset($item_salary[$vv['id'] . "_" . date("Y-m", $v['voucher_date'])]['allocated_salary'])) continue;
|
|
|
|
|
- $detail = [
|
|
|
|
|
|
|
+ foreach ($item_list as $itemId => $vv) {
|
|
|
|
|
+ $search_key = $itemId . "_" . $v_month;
|
|
|
|
|
+
|
|
|
|
|
+ // 只有当该项目在该月有实际分摊金额时才产生记录
|
|
|
|
|
+ $allocated_amount = 0;
|
|
|
|
|
+ if ($v['type'] == 1) {
|
|
|
|
|
+ $allocated_amount = $item_salary[$search_key]['allocated_salary'] ?? 0;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $allocated_amount = $device_depreciation[$search_key]['depreciation'] ?? 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if ($allocated_amount <= 0) continue;
|
|
|
|
|
+
|
|
|
|
|
+ $return[] = [
|
|
|
"code" => $vv['code'],
|
|
"code" => $vv['code'],
|
|
|
"title" => $vv['title'],
|
|
"title" => $vv['title'],
|
|
|
"state" => $vv['state'] == 3 ? "进行中" : "已完成",
|
|
"state" => $vv['state'] == 3 ? "进行中" : "已完成",
|
|
@@ -1258,19 +1408,18 @@ class StatisticService extends StatisticCommonService
|
|
|
"voucher_remark" => $v['voucher_remark'],
|
|
"voucher_remark" => $v['voucher_remark'],
|
|
|
"voucher_amount" => $v['voucher_amount'],
|
|
"voucher_amount" => $v['voucher_amount'],
|
|
|
"aggregation_amount" => $v['aggregation_amount'],
|
|
"aggregation_amount" => $v['aggregation_amount'],
|
|
|
- "total_amount" => $v['type'] == 1 ?round( $item_salary[$vv['id'] . "_" . date("Y-m", $v['voucher_date'])]['allocated_salary']/100,2) : (isset($device_depreciation[$vv['id'] . "_" . date("Y-m", $v['voucher_date'])]['depreciation']) ?round($device_depreciation[$vv['id'] . "_" . date("Y-m", $v['voucher_date'])]['depreciation']/100,2) : 0),
|
|
|
|
|
|
|
+ "total_amount" => round($allocated_amount / 100, 2), // 转回元
|
|
|
"fee_id" => $v['fee_id'],
|
|
"fee_id" => $v['fee_id'],
|
|
|
"entrust1_amount" => $v['entrust1_amount'],
|
|
"entrust1_amount" => $v['entrust1_amount'],
|
|
|
"entrust2_amount" => $v['entrust2_amount'],
|
|
"entrust2_amount" => $v['entrust2_amount'],
|
|
|
"type" => $v['type'],
|
|
"type" => $v['type'],
|
|
|
];
|
|
];
|
|
|
- $return[] = $detail;
|
|
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
} else {
|
|
} else {
|
|
|
- if (!isset($item_key_list[$v['item_id']])) continue;
|
|
|
|
|
- $item_value = $item_key_list[$v['item_id']];
|
|
|
|
|
- $detail = [
|
|
|
|
|
|
|
+ // 普通凭证费用
|
|
|
|
|
+ if (!isset($item_list[$v['item_id']])) continue;
|
|
|
|
|
+ $item_value = $item_list[$v['item_id']];
|
|
|
|
|
+ $return[] = [
|
|
|
"code" => $item_value['code'],
|
|
"code" => $item_value['code'],
|
|
|
"title" => $item_value['title'],
|
|
"title" => $item_value['title'],
|
|
|
"state" => $item_value['state'] == 3 ? "进行中" : "已完成",
|
|
"state" => $item_value['state'] == 3 ? "进行中" : "已完成",
|
|
@@ -1286,78 +1435,15 @@ class StatisticService extends StatisticCommonService
|
|
|
"entrust2_amount" => $v['entrust2_amount'],
|
|
"entrust2_amount" => $v['entrust2_amount'],
|
|
|
"type" => $v['type'],
|
|
"type" => $v['type'],
|
|
|
];
|
|
];
|
|
|
- $return[] = $detail;
|
|
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return [true, [
|
|
return [true, [
|
|
|
'fee_type_list' => $fee_type_list,
|
|
'fee_type_list' => $fee_type_list,
|
|
|
'list' => $return,
|
|
'list' => $return,
|
|
|
]];
|
|
]];
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 将报销明细按照一级费用和项目分类进行分组
|
|
|
|
|
- * * @param array $list 报销明细列表 (含 fee_id, amount 等)
|
|
|
|
|
- * @param array $fee_type_list 费用类型树 (含 id, parent_id, title)
|
|
|
|
|
- * @return array
|
|
|
|
|
- */
|
|
|
|
|
- public function auxiliaryGroupListByRoot(array $list, array $fee_type_list)
|
|
|
|
|
- {
|
|
|
|
|
- // 1. 建立 ID 索引,方便快速查找
|
|
|
|
|
- $idMap = array_column($fee_type_list, null, 'id');
|
|
|
|
|
-
|
|
|
|
|
- // 2. 预处理映射表:让所有子 ID 直接指向它的最顶层“祖宗” ID
|
|
|
|
|
- $childToRoot = [];
|
|
|
|
|
- foreach ($fee_type_list as $type) {
|
|
|
|
|
- $current = $type;
|
|
|
|
|
- // 向上追溯直到 parent_id 为 0,即找到一级分类
|
|
|
|
|
- while ($current['parent_id'] != 0) {
|
|
|
|
|
- $current = $idMap[$current['parent_id']];
|
|
|
|
|
- }
|
|
|
|
|
- $childToRoot[$type['id']] = [
|
|
|
|
|
- 'id' => $current['id'],
|
|
|
|
|
- 'title' => $current['title'],
|
|
|
|
|
- 'sort' => $current['sort']
|
|
|
|
|
- ];
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 3. 遍历明细数据进行分组
|
|
|
|
|
- $type_list = [];
|
|
|
|
|
- foreach ($list as $k => $item) {
|
|
|
|
|
- if ($item['item_id'] == 0 || $item['fee_id'] == 0) {
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
- $feeId = $item['fee_id'];
|
|
|
|
|
- // 获取该费用对应的一级分类信息
|
|
|
|
|
- if (!isset($childToRoot[$feeId])) continue;
|
|
|
|
|
- $rootId = $childToRoot[$feeId]['id'];
|
|
|
|
|
- $title = $childToRoot[$feeId]['title'];
|
|
|
|
|
- $sort = $childToRoot[$feeId]['sort'];
|
|
|
|
|
- $item['fee_id'] = $rootId;
|
|
|
|
|
- $list[$k] = $item;
|
|
|
|
|
-
|
|
|
|
|
- //这边需要拿到头部所有的一级费用类型
|
|
|
|
|
- if (!isset($type_list[$rootId])) {
|
|
|
|
|
- $type_list[$rootId] = [
|
|
|
|
|
- 'sort' => $sort,
|
|
|
|
|
- 'id' => $rootId,
|
|
|
|
|
- 'title' => $title,
|
|
|
|
|
- ];
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- // 使用 values() 丢弃原始键名,重新从 0 开始建立索引
|
|
|
|
|
- $type_list = collect($type_list)->sortBy('sort')->values()->all();
|
|
|
|
|
- // 4. 重置数组索引并返回
|
|
|
|
|
- return [$list, $type_list];
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
public function auxiliaryEmployee($user, $data, $month_start, $month_end)
|
|
public function auxiliaryEmployee($user, $data, $month_start, $month_end)
|
|
|
{
|
|
{
|
|
|
//确认所有项目、人员、人员工时
|
|
//确认所有项目、人员、人员工时
|
|
@@ -1574,6 +1660,289 @@ class StatisticService extends StatisticCommonService
|
|
|
return $return_item_list;
|
|
return $return_item_list;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ //原方法----
|
|
|
|
|
+ public function auxiliaryStatistic1($data, $user)
|
|
|
|
|
+ {
|
|
|
|
|
+ list($status, $month_start, $month_end) = $this->commonRule($data);
|
|
|
|
|
+ if (!$status) return [false, $month_start];
|
|
|
|
|
+ //项目编码、项目名称、项目状态、凭证日期、凭证种类、凭证号数、凭证摘要、会计凭证归集金额、N个一级费用类型、委内、委外
|
|
|
|
|
+
|
|
|
|
|
+ //确认所有项目
|
|
|
|
|
+ $item = Item::TopClear($user, $data);
|
|
|
|
|
+ $item_list = $item->where('del_time', 0)
|
|
|
|
|
+ ->where(function ($query) use ($month_start, $month_end) {
|
|
|
|
|
+ $query->where('start_time', '>=', $month_start)
|
|
|
|
|
+ ->where('end_time', '<', $month_end);
|
|
|
|
|
+ })->select("code", "title", "start_time", "end_time", "id", "state")->orderby("start_time", "asc")->get()->toArray();
|
|
|
|
|
+ $item_key_list = [];
|
|
|
|
|
+ foreach ($item_list as $v) {
|
|
|
|
|
+ $item_key_list[$v['id']] = $v;
|
|
|
|
|
+ }
|
|
|
|
|
+ //获取该区间内所有项目人工费、折旧费
|
|
|
|
|
+ $item_salary = $this->auxiliaryEmployee($user, $data, $month_start, $month_end);
|
|
|
|
|
+ $device_depreciation = $this->auxiliaryDevice($user, $data, $month_start, $month_end);
|
|
|
|
|
+ $fee = Fee::TopClear($user, $data);
|
|
|
|
|
+ $fee = $fee->where('del_time', 0)->orderBy("sort", 'desc')->get()->toArray();
|
|
|
|
|
+ $auxiliary = AuxiliaryAccountDetails::Clear($user, $data);
|
|
|
|
|
+ $auxiliary_list = $auxiliary->where("voucher_date", ">=", $month_start)->where("voucher_date", "<", $month_end)
|
|
|
|
|
+ ->where('del_time', 0)
|
|
|
|
|
+ ->select(
|
|
|
|
|
+ "item_id",
|
|
|
|
|
+ "voucher_date",
|
|
|
|
|
+ "voucher_type",
|
|
|
|
|
+ "voucher_no",
|
|
|
|
|
+ "voucher_remark",
|
|
|
|
|
+ "voucher_amount",
|
|
|
|
|
+ "aggregation_amount",
|
|
|
|
|
+ "entrust_type",
|
|
|
|
|
+ "entrust1_amount",
|
|
|
|
|
+ "entrust2_amount",
|
|
|
|
|
+ "entrust2_amount",
|
|
|
|
|
+ "total_amount",
|
|
|
|
|
+ "fee_id",
|
|
|
|
|
+ "type"
|
|
|
|
|
+ )->get()->toArray();
|
|
|
|
|
+ list($fee_amount, $fee_type_list) = $this->auxiliaryGroupListByRoot($auxiliary_list, $fee);
|
|
|
|
|
+
|
|
|
|
|
+ //找到项目和设备的费用然后进行比例计算
|
|
|
|
|
+
|
|
|
|
|
+ $return = [];
|
|
|
|
|
+ foreach ($fee_amount as $v) {
|
|
|
|
|
+ //人工费用
|
|
|
|
|
+ if ($v['type'] == 1 || $v['type'] == 2) {
|
|
|
|
|
+// var_dump();
|
|
|
|
|
+ foreach ($item_key_list as $vv) {
|
|
|
|
|
+ if(!isset($item_salary[$vv['id'] . "_" . date("Y-m", $v['voucher_date'])]['allocated_salary'])) continue;
|
|
|
|
|
+ $detail = [
|
|
|
|
|
+ "code" => $vv['code'],
|
|
|
|
|
+ "title" => $vv['title'],
|
|
|
|
|
+ "state" => $vv['state'] == 3 ? "进行中" : "已完成",
|
|
|
|
|
+ "voucher_date" => date("Y-m-d", $v['voucher_date']),
|
|
|
|
|
+ "voucher_type" => $v['voucher_type'],
|
|
|
|
|
+ "voucher_no" => $v['voucher_no'],
|
|
|
|
|
+ "voucher_remark" => $v['voucher_remark'],
|
|
|
|
|
+ "voucher_amount" => $v['voucher_amount'],
|
|
|
|
|
+ "aggregation_amount" => $v['aggregation_amount'],
|
|
|
|
|
+ "total_amount" => $v['type'] == 1 ?round( $item_salary[$vv['id'] . "_" . date("Y-m", $v['voucher_date'])]['allocated_salary']/100,2) : (isset($device_depreciation[$vv['id'] . "_" . date("Y-m", $v['voucher_date'])]['depreciation']) ?round($device_depreciation[$vv['id'] . "_" . date("Y-m", $v['voucher_date'])]['depreciation']/100,2) : 0),
|
|
|
|
|
+ "fee_id" => $v['fee_id'],
|
|
|
|
|
+ "entrust1_amount" => $v['entrust1_amount'],
|
|
|
|
|
+ "entrust2_amount" => $v['entrust2_amount'],
|
|
|
|
|
+ "type" => $v['type'],
|
|
|
|
|
+ ];
|
|
|
|
|
+ $return[] = $detail;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (!isset($item_key_list[$v['item_id']])) continue;
|
|
|
|
|
+ $item_value = $item_key_list[$v['item_id']];
|
|
|
|
|
+ $detail = [
|
|
|
|
|
+ "code" => $item_value['code'],
|
|
|
|
|
+ "title" => $item_value['title'],
|
|
|
|
|
+ "state" => $item_value['state'] == 3 ? "进行中" : "已完成",
|
|
|
|
|
+ "voucher_date" => date("Y-m-d", $v['voucher_date']),
|
|
|
|
|
+ "voucher_type" => $v['voucher_type'],
|
|
|
|
|
+ "voucher_no" => $v['voucher_no'],
|
|
|
|
|
+ "voucher_remark" => $v['voucher_remark'],
|
|
|
|
|
+ "voucher_amount" => $v['voucher_amount'],
|
|
|
|
|
+ "aggregation_amount" => $v['aggregation_amount'],
|
|
|
|
|
+ "total_amount" => $v['total_amount'],
|
|
|
|
|
+ "fee_id" => $v['fee_id'],
|
|
|
|
|
+ "entrust1_amount" => $v['entrust1_amount'],
|
|
|
|
|
+ "entrust2_amount" => $v['entrust2_amount'],
|
|
|
|
|
+ "type" => $v['type'],
|
|
|
|
|
+ ];
|
|
|
|
|
+ $return[] = $detail;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return [true, [
|
|
|
|
|
+ 'fee_type_list' => $fee_type_list,
|
|
|
|
|
+ 'list' => $return,
|
|
|
|
|
+ ]];
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function auxiliaryEmployee1($user, $data, $month_start, $month_end)
|
|
|
|
|
+ {
|
|
|
|
|
+ // 1. 获取工时明细
|
|
|
|
|
+ $month_employee_list = DailyPwOrderDetails::Clear($user, $data)
|
|
|
|
|
+ ->where("order_time", ">=", $month_start)->where("order_time", "<", $month_end)
|
|
|
|
|
+ ->where('del_time', 0)
|
|
|
|
|
+ ->select("item_id", "employee_id", DB::raw("FROM_UNIXTIME(order_time, '%Y-%m') as order_month"), DB::raw("SUM(total_work_min) as total_work"))
|
|
|
|
|
+ ->groupBy("order_month", "item_id", "employee_id")->get()->toArray();
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 获取工资并转为“分”
|
|
|
|
|
+ $monthly_ps_order_query = MonthlyPsOrder::Clear($user, $data)->where('del_time', 0)
|
|
|
|
|
+ ->where("month", ">=", $month_start)->where("month", "<", $month_end);
|
|
|
|
|
+ $monthly_ps_order_ids = $monthly_ps_order_query->pluck('id')->toArray();
|
|
|
|
|
+ $month_map = $monthly_ps_order_query->select('id', DB::raw("FROM_UNIXTIME(month, '%Y-%m') as month_str"))
|
|
|
|
|
+ ->pluck('month_str', 'id')->toArray();
|
|
|
|
|
+
|
|
|
|
|
+ $salary_details = MonthlyPsOrderDetails::whereIn('main_id', $monthly_ps_order_ids)
|
|
|
|
|
+ ->select("employee_id", "main_id", DB::raw("(base_salary + performance_salary + bonus + other) as salary"))
|
|
|
|
|
+ ->get();
|
|
|
|
|
+
|
|
|
|
|
+ $salary_pool = []; // [emp_month => salary_cents]
|
|
|
|
|
+ foreach ($salary_details as $val) {
|
|
|
|
|
+ $m = $month_map[$val['main_id']] ?? '';
|
|
|
|
|
+ if ($m) {
|
|
|
|
|
+ $k = $val['employee_id'] . '_' . $m;
|
|
|
|
|
+ $salary_pool[$k] = (int)round($val['salary'] * 100);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 计算个人月总工时及项目计数
|
|
|
|
|
+ $emp_total_min = [];
|
|
|
|
|
+ $emp_item_count = [];
|
|
|
|
|
+ foreach ($month_employee_list as $row) {
|
|
|
|
|
+ $k = $row['employee_id'] . '_' . $row['order_month'];
|
|
|
|
|
+ $emp_total_min[$k] = ($emp_total_min[$k] ?? 0) + $row['total_work'];
|
|
|
|
|
+ $emp_item_count[$k] = ($emp_item_count[$k] ?? 0) + 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 分摊(保留整数分)
|
|
|
|
|
+ $rem_salary = $salary_pool;
|
|
|
|
|
+ $return_item_list = [];
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($month_employee_list as $item) {
|
|
|
|
|
+ $k = $item['employee_id'] . '_' . $item['order_month'];
|
|
|
|
|
+ $total_s = $salary_pool[$k] ?? 0;
|
|
|
|
|
+ $total_m = $emp_total_min[$k] ?? 0;
|
|
|
|
|
+
|
|
|
|
|
+ if ($total_m > 0 && --$emp_item_count[$k] > 0) {
|
|
|
|
|
+ // 非最后一个项目,取地板值避免超支
|
|
|
|
|
+ $allocated = (int)floor(($item['total_work'] / $total_m) * $total_s);
|
|
|
|
|
+ $rem_salary[$k] -= $allocated;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 最后一个项目,取池子剩余所有钱
|
|
|
|
|
+ $allocated = $rem_salary[$k] ?? 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $res_key = $item['item_id'] . '_' . $item['order_month'];
|
|
|
|
|
+ $return_item_list[$res_key]['allocated_salary'] = ($return_item_list[$res_key]['allocated_salary'] ?? 0) + $allocated;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $return_item_list;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function auxiliaryDevice1($user, $data, $month_start, $month_end)
|
|
|
|
|
+ {
|
|
|
|
|
+ // 1. 获取设备工时
|
|
|
|
|
+ $month_device_list = DailyDwOrderDetails::Clear($user, $data)
|
|
|
|
|
+ ->where("order_time", ">=", $month_start)->where("order_time", "<", $month_end)->where('del_time', 0)
|
|
|
|
|
+ ->select("item_id", "device_id", DB::raw("FROM_UNIXTIME(order_time, '%Y-%m') as order_month"), DB::raw("SUM(total_work_min) as total_work"))
|
|
|
|
|
+ ->groupBy("order_month", "item_id", "device_id")->get()->toArray();
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 获取折旧费转为“分”
|
|
|
|
|
+ $monthly_dd_query = MonthlyDdOrder::Clear($user, $data)->where('del_time', 0)
|
|
|
|
|
+ ->where("month", ">=", $month_start)->where("month", "<", $month_end);
|
|
|
|
|
+ $monthly_dd_ids = $monthly_dd_query->pluck('id')->toArray();
|
|
|
|
|
+ $month_map = $monthly_dd_query->select('id', DB::raw("FROM_UNIXTIME(month, '%Y-%m') as month_str"))
|
|
|
|
|
+ ->pluck("month_str", 'id')->toArray();
|
|
|
|
|
+
|
|
|
|
|
+ $device_details = MonthlyDdOrderDetails::whereIn('main_id', $monthly_dd_ids)
|
|
|
|
|
+ ->select("device_id", "depreciation_amount", "main_id")->get();
|
|
|
|
|
+
|
|
|
|
|
+ $dep_pool = [];
|
|
|
|
|
+ foreach ($device_details as $val) {
|
|
|
|
|
+ $m = $month_map[$val['main_id']] ?? '';
|
|
|
|
|
+ if ($m) {
|
|
|
|
|
+ $k = $val['device_id'] . '_' . $m;
|
|
|
|
|
+ $dep_pool[$k] = (int)round($val['depreciation_amount'] * 100);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 统计设备月总工时及项目数
|
|
|
|
|
+ $dev_total_min = [];
|
|
|
|
|
+ $dev_item_count = [];
|
|
|
|
|
+ foreach ($month_device_list as $row) {
|
|
|
|
|
+ $k = $row['device_id'] . '_' . $row['order_month'];
|
|
|
|
|
+ $dev_total_min[$k] = ($dev_total_min[$k] ?? 0) + $row['total_work'];
|
|
|
|
|
+ $dev_item_count[$k] = ($dev_item_count[$k] ?? 0) + 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 分摊
|
|
|
|
|
+ $rem_dep = $dep_pool;
|
|
|
|
|
+ $return_item_list = [];
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($month_device_list as $item) {
|
|
|
|
|
+ $k = $item['device_id'] . '_' . $item['order_month'];
|
|
|
|
|
+ $total_d = $dep_pool[$k] ?? 0;
|
|
|
|
|
+ $total_m = $dev_total_min[$k] ?? 0;
|
|
|
|
|
+
|
|
|
|
|
+ if ($total_m > 0 && --$dev_item_count[$k] > 0) {
|
|
|
|
|
+ $allocated = (int)floor(($item['total_work'] / $total_m) * $total_d);
|
|
|
|
|
+ $rem_dep[$k] -= $allocated;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $allocated = $rem_dep[$k] ?? 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $res_key = $item['item_id'] . '_' . $item['order_month'];
|
|
|
|
|
+ $return_item_list[$res_key]['depreciation'] = ($return_item_list[$res_key]['depreciation'] ?? 0) + $allocated;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $return_item_list;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 将报销明细按照一级费用和项目分类进行分组
|
|
|
|
|
+ * * @param array $list 报销明细列表 (含 fee_id, amount 等)
|
|
|
|
|
+ * @param array $fee_type_list 费用类型树 (含 id, parent_id, title)
|
|
|
|
|
+ * @return array
|
|
|
|
|
+ */
|
|
|
|
|
+ public function auxiliaryGroupListByRoot(array $list, array $fee_type_list)
|
|
|
|
|
+ {
|
|
|
|
|
+ // 1. 建立 ID 索引,方便快速查找
|
|
|
|
|
+ $idMap = array_column($fee_type_list, null, 'id');
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 预处理映射表:让所有子 ID 直接指向它的最顶层“祖宗” ID
|
|
|
|
|
+ $childToRoot = [];
|
|
|
|
|
+ foreach ($fee_type_list as $type) {
|
|
|
|
|
+ $current = $type;
|
|
|
|
|
+ // 向上追溯直到 parent_id 为 0,即找到一级分类
|
|
|
|
|
+ while ($current['parent_id'] != 0) {
|
|
|
|
|
+ $current = $idMap[$current['parent_id']];
|
|
|
|
|
+ }
|
|
|
|
|
+ $childToRoot[$type['id']] = [
|
|
|
|
|
+ 'id' => $current['id'],
|
|
|
|
|
+ 'title' => $current['title'],
|
|
|
|
|
+ 'sort' => $current['sort']
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 遍历明细数据进行分组
|
|
|
|
|
+ $type_list = [];
|
|
|
|
|
+ foreach ($list as $k => $item) {
|
|
|
|
|
+ if ($item['item_id'] == 0 || $item['fee_id'] == 0) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ $feeId = $item['fee_id'];
|
|
|
|
|
+ // 获取该费用对应的一级分类信息
|
|
|
|
|
+ if (!isset($childToRoot[$feeId])) continue;
|
|
|
|
|
+ $rootId = $childToRoot[$feeId]['id'];
|
|
|
|
|
+ $title = $childToRoot[$feeId]['title'];
|
|
|
|
|
+ $sort = $childToRoot[$feeId]['sort'];
|
|
|
|
|
+ $item['fee_id'] = $rootId;
|
|
|
|
|
+ $list[$k] = $item;
|
|
|
|
|
+
|
|
|
|
|
+ //这边需要拿到头部所有的一级费用类型
|
|
|
|
|
+ if (!isset($type_list[$rootId])) {
|
|
|
|
|
+ $type_list[$rootId] = [
|
|
|
|
|
+ 'sort' => $sort,
|
|
|
|
|
+ 'id' => $rootId,
|
|
|
|
|
+ 'title' => $title,
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ // 使用 values() 丢弃原始键名,重新从 0 开始建立索引
|
|
|
|
|
+ $type_list = collect($type_list)->sortBy('sort')->values()->all();
|
|
|
|
|
+ // 4. 重置数组索引并返回
|
|
|
|
|
+ return [$list, $type_list];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
public function itemEmployeeSalaryStatistic($data, $user)
|
|
public function itemEmployeeSalaryStatistic($data, $user)
|
|
|
{
|
|
{
|
|
|
list($status, $month_start, $month_end) = $this->commonRule($data);
|
|
list($status, $month_start, $month_end) = $this->commonRule($data);
|