You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
6.0 KiB
199 lines
6.0 KiB
<?php
|
|
// +----------------------------------------------------------------------
|
|
// | Niucloud-admin 企业快速开发的多应用管理平台
|
|
// +----------------------------------------------------------------------
|
|
// | 官方网址:https://www.niucloud.com
|
|
// +----------------------------------------------------------------------
|
|
// | niucloud团队 版权所有 开源版本可自由商用
|
|
// +----------------------------------------------------------------------
|
|
// | Author: Niucloud Team
|
|
// +----------------------------------------------------------------------
|
|
|
|
namespace app\service\admin\salary;
|
|
|
|
use app\model\salary\Salary;
|
|
use app\model\personnel\Personnel;
|
|
use app\model\campus\Campus;
|
|
use core\base\BaseAdminService;
|
|
use core\exception\AdminException;
|
|
|
|
/**
|
|
* 工资条服务类
|
|
* Class PayrollService
|
|
* @package app\service\admin\salary
|
|
*/
|
|
class PayrollService extends BaseAdminService
|
|
{
|
|
public function __construct()
|
|
{
|
|
parent::__construct();
|
|
$this->model = new Salary();
|
|
}
|
|
|
|
/**
|
|
* 获取工资条分页列表
|
|
* @param array $where
|
|
* @return array
|
|
*/
|
|
public function getPage(array $where = [])
|
|
{
|
|
$field = 's.*, p.name as staff_name, c.campus_name as campus_name';
|
|
|
|
$search_model = $this->model
|
|
->alias('s')
|
|
->join('school_personnel p', 's.staff_id = p.id', 'left')
|
|
->leftJoin('school_campus_person_role cpr', 'p.id = cpr.person_id')
|
|
->leftJoin('school_campus c', 'cpr.campus_id = c.id')
|
|
->field($field)
|
|
->order('s.created_at desc');
|
|
|
|
// 筛选条件
|
|
if (!empty($where['campus_id'])) {
|
|
$search_model->where('cpr.campus_id', $where['campus_id']);
|
|
}
|
|
if (!empty($where['salary_month'])) {
|
|
$search_model->where('s.salary_month', 'like', $where['salary_month'] . '%');
|
|
}
|
|
if (!empty($where['staff_name'])) {
|
|
$search_model->where('p.name', 'like', '%' . $where['staff_name'] . '%');
|
|
}
|
|
if (!empty($where['status'])) {
|
|
$search_model->where('s.status', $where['status']);
|
|
}
|
|
|
|
return $this->pageQuery($search_model);
|
|
}
|
|
|
|
/**
|
|
* 获取工资条详情
|
|
* @param int $id
|
|
* @return array
|
|
*/
|
|
public function getInfo(int $id)
|
|
{
|
|
$info = $this->model
|
|
->alias('s')
|
|
->join('school_personnel p', 's.staff_id = p.id', 'left')
|
|
->leftJoin('school_campus_person_role cpr', 'p.id = cpr.person_id')
|
|
->leftJoin('school_campus c', 'cpr.campus_id = c.id')
|
|
->field('s.*, p.name as staff_name, c.campus_name as campus_name')
|
|
->where('s.id', $id)
|
|
->findOrEmpty()
|
|
->toArray();
|
|
|
|
if (empty($info)) {
|
|
throw new AdminException('工资条不存在');
|
|
}
|
|
|
|
return $info;
|
|
}
|
|
|
|
/**
|
|
* 添加工资条
|
|
* @param array $data
|
|
* @return int
|
|
*/
|
|
public function add(array $data)
|
|
{
|
|
// 获取员工校区信息
|
|
$campusInfo = $this->getStaffCampus($data['staff_id']);
|
|
$data['campus_id'] = $campusInfo['campus_id'];
|
|
|
|
// 计算工资
|
|
$calculated = $this->calculateSalary($data);
|
|
$data = array_merge($data, $calculated);
|
|
|
|
$data['created_at'] = date('Y-m-d H:i:s');
|
|
$data['updated_at'] = date('Y-m-d H:i:s');
|
|
|
|
$res = $this->model->create($data);
|
|
return $res->id;
|
|
}
|
|
|
|
/**
|
|
* 编辑工资条
|
|
* @param int $id
|
|
* @param array $data
|
|
* @return bool
|
|
*/
|
|
public function edit(int $id, array $data)
|
|
{
|
|
// 获取员工校区信息
|
|
$campusInfo = $this->getStaffCampus($data['staff_id']);
|
|
$data['campus_id'] = $campusInfo['campus_id'];
|
|
|
|
// 计算工资
|
|
$calculated = $this->calculateSalary($data);
|
|
$data = array_merge($data, $calculated);
|
|
|
|
$data['updated_at'] = date('Y-m-d H:i:s');
|
|
|
|
unset($data['id']); // 移除ID字段,避免更新主键
|
|
$this->model->where('id', $id)->update($data);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 删除工资条
|
|
* @param int $id
|
|
* @return bool
|
|
*/
|
|
public function del(int $id)
|
|
{
|
|
$this->model->where('id', $id)->delete();
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 获取员工校区信息
|
|
* @param int $staffId
|
|
* @return array
|
|
*/
|
|
private function getStaffCampus(int $staffId)
|
|
{
|
|
$campusInfo = Personnel::alias('p')
|
|
->leftJoin('school_campus_person_role cpr', 'p.id = cpr.person_id')
|
|
->leftJoin('school_campus c', 'cpr.campus_id = c.id')
|
|
->field('IFNULL(cpr.campus_id, 0) as campus_id, CASE WHEN cpr.campus_id IS NULL OR cpr.campus_id = 0 THEN "总部" ELSE c.campus_name END as campus_name')
|
|
->where('p.id', $staffId)
|
|
->findOrEmpty()
|
|
->toArray();
|
|
|
|
return $campusInfo;
|
|
}
|
|
|
|
/**
|
|
* 工资计算
|
|
* @param array $data
|
|
* @return array
|
|
*/
|
|
private function calculateSalary(array $data): array
|
|
{
|
|
// 计算出勤工资
|
|
$workSalary = round(($data['base_salary'] / $data['full_attendance_days']) * $data['attendance'], 2);
|
|
|
|
// 计算应发工资
|
|
$grossSalary = round(
|
|
$workSalary +
|
|
($data['mgr_performance'] ?? 0) +
|
|
($data['performance_bonus'] ?? 0) +
|
|
($data['other_subsidies'] ?? 0) -
|
|
($data['deductions'] ?? 0),
|
|
2
|
|
);
|
|
|
|
// 计算实发工资
|
|
$netSalary = round(
|
|
$grossSalary -
|
|
($data['social_security'] ?? 0) -
|
|
($data['individual_income_tax'] ?? 0),
|
|
2
|
|
);
|
|
|
|
return [
|
|
'work_salary' => $workSalary,
|
|
'gross_salary' => $grossSalary,
|
|
'net_salary' => $netSalary
|
|
];
|
|
}
|
|
}
|