diff --git a/app/adminapi/controller/project/ProjectPersonnelController.php b/app/adminapi/controller/project/ProjectPersonnelController.php index 4e558ac26..58fa3009c 100644 --- a/app/adminapi/controller/project/ProjectPersonnelController.php +++ b/app/adminapi/controller/project/ProjectPersonnelController.php @@ -27,10 +27,11 @@ use app\common\model\build\BuildReport; use app\common\model\build\BuildReportDetail; use app\common\model\project\Project; use app\common\model\project\ProjectAttendanceDetail; -use app\common\model\project\ProjectAttendanceRecord; use app\common\model\project\ProjectInsuranceManagement; use app\common\model\project\ProjectLaborContract; use app\common\model\project\ProjectPersonnel; +use app\common\model\project\ProjectSalaryDetail; +use app\common\model\project\ProjectSalaryPayment; /** @@ -248,7 +249,8 @@ class ProjectPersonnelController extends BaseAdminController } //某个员工下的施工记录列表 - public function buildworks() { + public function buildworks(): \think\response\Json + { $params = $this->request->get(['person_id','page_no','page_size']); if(empty($params['person_id'])){ return $this->fail('缺少必要参数'); @@ -291,5 +293,59 @@ class ProjectPersonnelController extends BaseAdminController ]; return $this->success('请求成功',$result); } - + + //某个人员下的工资付款列表 + public function payments(): \think\response\Json + { + $params = $this->request->get(['person_id','page_no','page_size']); + if(empty($params['person_id'])){ + return $this->fail('缺少必要参数'); + } + $pageNo = empty($params['page_no']) ? 1 : $params['page_no']; + $pageSize = empty($params['page_size']) ? 15 : $params['page_size']; + $person = ProjectPersonnel::field('id,name,idcard,work_type')->where('id',$params['person_id'])->findOrEmpty(); + if($person->isEmpty()){ + return $this->fail('项目人员信息不存在'); + } + $data = ProjectSalaryDetail::field(['id', 'salary_payment_id', 'person_id', 'apply_date', 'apply_amount', 'remark']) + ->where('person_id',$params['person_id']) + ->page($pageNo,$pageSize)->order('id desc') + ->select()->each(function($item)use($person){ + $payment = ProjectSalaryPayment::field('payment_code,project_id')->where('id',$item['salary_payment_id'])->findOrEmpty(); + $project = Project::field('name,project_code')->where('id',$payment['project_id'])->findOrEmpty(); + $person = ProjectPersonnel::field('name,idcard,work_type')->where('id',$item['person_id'])->findOrEmpty(); + $item['payment_code'] = $payment['payment_code']; + $item['project_name'] = $project['name']; + $item['project_code'] = $project['project_code']; + $item['person_name'] = $person['name']; + $item['person_idcard'] = $person['idcard']; + $item['person_work_type_text'] = $person->work_type_text; + //总考勤收入 + $daily_income = ProjectAttendanceDetail::where('person_id',$item['person_id'])->sum('daily_income'); + //总施工收入 + $build_report_details = BuildReportDetail::field('report_id,work_num')->where('person_id',$item['person_id'])->select()->each(function($item2){ + $report = BuildReport::field('plan_id')->where('id',$item2['report_id'])->findOrEmpty(); + $plan = BuildPlan::field('price')->where('id',$report['plan_id'])->findOrEmpty(); + $item2['amount'] = $item2['work_num'] * $plan['price']; + })->toArray(); + $work_income = 0; + foreach($build_report_details as $v){ + $work_income += $v['amount']; + } + $item['total_income'] = $daily_income + $work_income; + //总支出 + $item['total_pay_out'] = ProjectSalaryDetail::where('person_id',$item['person_id'])->sum('apply_amount'); + $item['balance'] = $item['total_income'] - $item['total_pay_out']; + return $item; + }) + ->toArray(); + $count = BuildReportDetail::field('id')->where('person_id',$params['person_id'])->count(); + $result = [ + 'count' => $count, + 'page_no' => $pageNo, + 'page_size' => $pageSize, + 'lists' => $data + ]; + return $this->success('请求成功',$result); + } } \ No newline at end of file diff --git a/app/adminapi/controller/project/ProjectSalaryDetailController.php b/app/adminapi/controller/project/ProjectSalaryDetailController.php new file mode 100644 index 000000000..b9e7a63d2 --- /dev/null +++ b/app/adminapi/controller/project/ProjectSalaryDetailController.php @@ -0,0 +1,45 @@ +dataLists(new ProjectSalaryDetailLists()); + } + +} \ No newline at end of file diff --git a/app/adminapi/controller/project/ProjectSalaryPaymentController.php b/app/adminapi/controller/project/ProjectSalaryPaymentController.php new file mode 100644 index 000000000..40ff67e49 --- /dev/null +++ b/app/adminapi/controller/project/ProjectSalaryPaymentController.php @@ -0,0 +1,77 @@ +dataLists(new ProjectSalaryPaymentLists()); + } + + + /** + * @notes 添加工资付款 + * @return \think\response\Json + * @author likeadmin + * @date 2023/12/27 16:08 + */ + public function add() + { + $params = (new ProjectSalaryPaymentValidate())->post()->goCheck('add'); + $result = ProjectSalaryPaymentLogic::add($params); + if (true === $result) { + return $this->success('添加成功', [], 1, 1); + } + return $this->fail(ProjectSalaryPaymentLogic::getError()); + } + + + /** + * @notes 获取工资付款详情 + * @return \think\response\Json + * @author likeadmin + * @date 2023/12/27 16:08 + */ + public function detail() + { + $params = (new ProjectSalaryPaymentValidate())->goCheck('detail'); + $result = ProjectSalaryPaymentLogic::detail($params); + return $this->data($result); + } + + +} \ No newline at end of file diff --git a/app/adminapi/lists/project/ProjectSalaryDetailLists.php b/app/adminapi/lists/project/ProjectSalaryDetailLists.php new file mode 100644 index 000000000..c66ef418d --- /dev/null +++ b/app/adminapi/lists/project/ProjectSalaryDetailLists.php @@ -0,0 +1,108 @@ +searchWhere) + ->field(['id', 'salary_payment_id', 'person_id', 'apply_date', 'apply_amount', 'remark']) + ->limit($this->limitOffset, $this->limitLength) + ->order(['id' => 'desc']) + ->select()->each(function($item){ + $payment = ProjectSalaryPayment::field('payment_code,project_id')->where('id',$item['salary_payment_id'])->findOrEmpty(); + $project = Project::field('name,project_code')->where('id',$payment['project_id'])->findOrEmpty(); + $person = ProjectPersonnel::field('name,idcard,work_type')->where('id',$item['person_id'])->findOrEmpty(); + $item['payment_code'] = $payment['payment_code']; + $item['project_name'] = $project['name']; + $item['project_code'] = $project['project_code']; + $item['person_name'] = $person['name']; + $item['person_idcard'] = $person['idcard']; + $item['person_work_type_text'] = $person->work_type_text; + //总考勤收入 + $daily_income = ProjectAttendanceDetail::where('person_id',$item['person_id'])->sum('daily_income'); + //总施工收入 + $build_report_details = BuildReportDetail::field('report_id,work_num')->where('person_id',$item['person_id'])->select()->each(function($item2){ + $report = BuildReport::field('plan_id')->where('id',$item2['report_id'])->findOrEmpty(); + $plan = BuildPlan::field('price')->where('id',$report['plan_id'])->findOrEmpty(); + $item2['amount'] = $item2['work_num'] * $plan['price']; + })->toArray(); + $work_income = 0; + foreach($build_report_details as $v){ + $work_income += $v['amount']; + } + $item['total_income'] = $daily_income + $work_income; + //总支出 + $item['total_pay_out'] = ProjectSalaryDetail::where('person_id',$item['person_id'])->sum('apply_amount'); + $item['balance'] = $item['total_income'] - $item['total_pay_out']; + }) + ->toArray(); + } + + + /** + * @notes 获取工资明细数量 + * @return int + * @author likeadmin + * @date 2023/12/27 16:12 + */ + public function count(): int + { + return ProjectSalaryDetail::where($this->searchWhere)->count(); + } + +} \ No newline at end of file diff --git a/app/adminapi/lists/project/ProjectSalaryPaymentLists.php b/app/adminapi/lists/project/ProjectSalaryPaymentLists.php new file mode 100644 index 000000000..a2cabb07b --- /dev/null +++ b/app/adminapi/lists/project/ProjectSalaryPaymentLists.php @@ -0,0 +1,84 @@ + ['payment_type', 'apply_date'], + '%like%' => ['payment_code'], + ]; + } + + + /** + * @notes 获取工资付款列表 + * @return array + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + * @author likeadmin + * @date 2023/12/27 16:08 + */ + public function lists(): array + { + return ProjectSalaryPayment::where($this->searchWhere) + ->field(['id', 'payment_code', 'project_id', 'payment_type', 'apply_date', 'total_amount', 'total_amount_uppercase', 'remark', 'annex']) + ->limit($this->limitOffset, $this->limitLength) + ->order(['id' => 'desc']) + ->select()->each(function($item){ + $project = Project::field('name,project_code')->where('id',$item['project_id'])->findOrEmpty(); + $item['project_name'] = $project['name']; + $item['project_code'] = $project['project_code']; + return $item; + }) + ->toArray(); + } + + + /** + * @notes 获取工资付款数量 + * @return int + * @author likeadmin + * @date 2023/12/27 16:08 + */ + public function count(): int + { + return ProjectSalaryPayment::where($this->searchWhere)->count(); + } + +} \ No newline at end of file diff --git a/app/adminapi/logic/project/ProjectPersonnelLogic.php b/app/adminapi/logic/project/ProjectPersonnelLogic.php index 1194bc123..2c7254d41 100644 --- a/app/adminapi/logic/project/ProjectPersonnelLogic.php +++ b/app/adminapi/logic/project/ProjectPersonnelLogic.php @@ -23,6 +23,7 @@ use app\common\model\project\Project; use app\common\model\project\ProjectAttendanceDetail; use app\common\model\project\ProjectPersonnel; use app\common\logic\BaseLogic; +use app\common\model\project\ProjectSalaryDetail; use think\facade\Db; @@ -156,7 +157,7 @@ class ProjectPersonnelLogic extends BaseLogic } $data['work_income'] = $work_income; $data['total_income'] = $data['daily_income'] + $data['work_income']; - $data['pay_out'] = 0; + $data['pay_out'] = ProjectSalaryDetail::where('person_id',$data['id'])->sum('apply_amount'); $data['balance'] = $data['total_income'] - $data['pay_out']; return $data->toArray(); } diff --git a/app/adminapi/logic/project/ProjectSalaryDetailLogic.php b/app/adminapi/logic/project/ProjectSalaryDetailLogic.php new file mode 100644 index 000000000..706ba39f0 --- /dev/null +++ b/app/adminapi/logic/project/ProjectSalaryDetailLogic.php @@ -0,0 +1,114 @@ + $params['salary_payment_id'], + 'apply_date' => $params['apply_date'], + 'apply_amount' => $params['apply_amount'], + 'remark' => $params['remark'], + 'person_id' => $params['person_id'], + ]); + + Db::commit(); + return true; + } catch (\Exception $e) { + Db::rollback(); + self::setError($e->getMessage()); + return false; + } + } + + + /** + * @notes 编辑工资明细 + * @param array $params + * @return bool + * @author likeadmin + * @date 2023/12/27 16:12 + */ + public static function edit(array $params): bool + { + Db::startTrans(); + try { + ProjectSalaryDetail::where('id', $params['id'])->update([ + 'salary_payment_id' => $params['salary_payment_id'], + 'apply_date' => $params['apply_date'], + 'apply_amount' => $params['apply_amount'], + 'remark' => $params['remark'], + 'person_id' => $params['person_id'], + ]); + + Db::commit(); + return true; + } catch (\Exception $e) { + Db::rollback(); + self::setError($e->getMessage()); + return false; + } + } + + + /** + * @notes 删除工资明细 + * @param array $params + * @return bool + * @author likeadmin + * @date 2023/12/27 16:12 + */ + public static function delete(array $params): bool + { + return ProjectSalaryDetail::destroy($params['id']); + } + + + /** + * @notes 获取工资明细详情 + * @param $params + * @return array + * @author likeadmin + * @date 2023/12/27 16:12 + */ + public static function detail($params): array + { + return ProjectSalaryDetail::findOrEmpty($params['id'])->toArray(); + } +} \ No newline at end of file diff --git a/app/adminapi/logic/project/ProjectSalaryPaymentLogic.php b/app/adminapi/logic/project/ProjectSalaryPaymentLogic.php new file mode 100644 index 000000000..fc9cd1c02 --- /dev/null +++ b/app/adminapi/logic/project/ProjectSalaryPaymentLogic.php @@ -0,0 +1,121 @@ + data_unique_code('项目工资付款单'), + 'project_id' => $params['project_id'], + 'payment_type' => $params['payment_type'], + 'apply_date' => strtotime($params['apply_date']), + 'total_amount' => $params['total_amount'], + 'total_amount_uppercase' => $params['total_amount_uppercase'], + 'remark' => $params['remark'] ?? '', + 'annex' => !empty($params['annex']) ? $params['annex'] : null, + ]); + foreach($payment_detail as $v){ + ProjectSalaryDetail::create([ + 'salary_payment_id' => $res->id, + 'person_id' => $v['person_id'], + 'apply_date' => strtotime($params['apply_date']), + 'apply_amount' => $v['apply_amount'], + 'remark' => $v['remark'] ?? '', + ]); + } + Db::commit(); + return true; + } catch (\Exception $e) { + Db::rollback(); + self::setError($e->getMessage()); + return false; + } + } + + + /** + * @notes 获取工资付款详情 + * @param $params + * @return array + * @author likeadmin + * @date 2023/12/27 16:08 + */ + public static function detail($params): array + { + $data = ProjectSalaryPayment::field('id,payment_code,project_id,payment_type,apply_date,total_amount,total_amount_uppercase,remark,annex')->findOrEmpty($params['id'])->toArray(); + $project = Project::field('name,project_code')->where('id',$data['project_id'])->findOrEmpty(); + $data['project_name'] = $project['name']; + $data['project_code'] = $project['project_code']; + $data['payment_detail'] = ProjectSalaryDetail::field('person_id,apply_amount,remark')->where('salary_payment_id',$data['id']) + ->select()->each(function($item){ + $person = ProjectPersonnel::field('name,idcard,work_type,deposit_bank,bank_no')->where('id',$item['person_id'])->findOrEmpty(); + $item['person_name'] = $person['name']; + $item['person_idcard'] = $person['idcard']; + $item['person_work_type_text'] = $person->work_type_text; + $item['person_deposit_bank'] = $person['deposit_bank']; + $item['person_bank_no'] = $person['bank_no']; + //总考勤收入 + $daily_income = ProjectAttendanceDetail::where('person_id',$item['person_id'])->sum('daily_income'); + //总施工收入 + $build_report_details = BuildReportDetail::field('report_id,work_num')->where('person_id',$item['person_id'])->select()->each(function($item2){ + $report = BuildReport::field('plan_id')->where('id',$item2['report_id'])->findOrEmpty(); + $plan = BuildPlan::field('price')->where('id',$report['plan_id'])->findOrEmpty(); + $item2['amount'] = $item2['work_num'] * $plan['price']; + })->toArray(); + $work_income = 0; + foreach($build_report_details as $v){ + $work_income += $v['amount']; + } + $item['total_income'] = $daily_income + $work_income; + //总支出 + $item['total_pay_out'] = ProjectSalaryDetail::where('person_id',$item['person_id'])->sum('apply_amount'); + $item['balance'] = $item['total_income'] - $item['total_pay_out']; + return $item; + }) + ->toArray(); + return $data; + } +} \ No newline at end of file diff --git a/app/adminapi/validate/project/ProjectSalaryDetailValidate.php b/app/adminapi/validate/project/ProjectSalaryDetailValidate.php new file mode 100644 index 000000000..cc4687bd6 --- /dev/null +++ b/app/adminapi/validate/project/ProjectSalaryDetailValidate.php @@ -0,0 +1,102 @@ + 'require', + 'salary_payment_id' => 'require', + 'apply_date' => 'require', + 'apply_amount' => 'require', + 'person_id' => 'require', + ]; + + + /** + * 参数描述 + * @var string[] + */ + protected $field = [ + 'id' => 'id', + 'salary_payment_id' => '工资付款记录id', + 'apply_date' => '申请日期', + 'apply_amount' => '申请付款金额', + 'person_id' => '项目人员id', + ]; + + + /** + * @notes 添加场景 + * @return ProjectSalaryDetailValidate + * @author likeadmin + * @date 2023/12/27 16:12 + */ + public function sceneAdd() + { + return $this->only(['salary_payment_id','apply_date','apply_amount','person_id']); + } + + + /** + * @notes 编辑场景 + * @return ProjectSalaryDetailValidate + * @author likeadmin + * @date 2023/12/27 16:12 + */ + public function sceneEdit() + { + return $this->only(['id','salary_payment_id','apply_date','apply_amount','person_id']); + } + + + /** + * @notes 删除场景 + * @return ProjectSalaryDetailValidate + * @author likeadmin + * @date 2023/12/27 16:12 + */ + public function sceneDelete() + { + return $this->only(['id']); + } + + + /** + * @notes 详情场景 + * @return ProjectSalaryDetailValidate + * @author likeadmin + * @date 2023/12/27 16:12 + */ + public function sceneDetail() + { + return $this->only(['id']); + } + +} \ No newline at end of file diff --git a/app/adminapi/validate/project/ProjectSalaryPaymentValidate.php b/app/adminapi/validate/project/ProjectSalaryPaymentValidate.php new file mode 100644 index 000000000..6cc5494e2 --- /dev/null +++ b/app/adminapi/validate/project/ProjectSalaryPaymentValidate.php @@ -0,0 +1,160 @@ + 'require', + 'project_id' => 'require|checkProject', + 'payment_type' => 'require|checkPaymentType', + 'apply_date' => 'require|dateFormat:Y-m-d', + 'total_amount' => 'require|float|egt:0', + 'total_amount_uppercase' => 'require', + 'annex' => 'checkFile', + 'payment_detail' => 'require|checkPaymentDetail' + ]; + + protected $message = [ + 'id.require' => '缺少必要参数', + 'project_id.require' => '请选择项目', + 'payment_type.require' => '请选择付款类型', + 'apply_date.require' => '请选择申请日期', + 'apply_date.dateFormat' => '申请日期格式错误', + 'total_amount.require' => '请填写合计金额', + 'total_amount.float' => '合计金额值必须是数字', + 'total_amount.egt' => '合计金额值必须大于等于0', + 'total_amount_uppercase.require' => '请填写合计金额大写文字', + 'payment_detail.require' => '工资支付明细不能为空', + ]; + + /** + * @notes 添加场景 + * @return ProjectSalaryPaymentValidate + * @author likeadmin + * @date 2023/12/27 16:08 + */ + public function sceneAdd() + { + return $this->remove('id',true); + } + + + /** + * @notes 编辑场景 + * @return ProjectSalaryPaymentValidate + * @author likeadmin + * @date 2023/12/27 16:08 + */ + public function sceneEdit() + {} + + + /** + * @notes 删除场景 + * @return ProjectSalaryPaymentValidate + * @author likeadmin + * @date 2023/12/27 16:08 + */ + public function sceneDelete() + { + return $this->only(['id']); + } + + + /** + * @notes 详情场景 + * @return ProjectSalaryPaymentValidate + * @author likeadmin + * @date 2023/12/27 16:08 + */ + public function sceneDetail() + { + return $this->only(['id']); + } + + public function checkProject($value): bool|string + { + $data = Project::where('id',$value)->findOrEmpty(); + if($data->isEmpty()){ + return '项目不存在'; + } + return true; + } + + public function checkPaymentType($value): bool|string + { + $dictData = DictData::where('type_value','salary_payment_type')->column('value'); + if(!in_array($value,$dictData)){ + return '付款类型无效'; + } + return true; + } + + public function checkFile($value): bool|string + { + if($value != ''){ + $file = json_decode($value,true); + if(empty($file)){ + return '附件必须是json数组'; + } + } + return true; + } + + public function checkPaymentDetail($value,$rule,$data): bool|string + { + $payment_detail = json_decode($value,true); + if(empty($payment_detail) || !is_array($payment_detail)){ + return '工资支付明细数据格式错误'; + } + foreach($payment_detail as $v) { + if(empty($v['person_id'])){ + return '请选择项目人员'; + }else{ + $person = ProjectPersonnel::where('id',$v['person_id'])->findOrEmpty(); + if($person->isEmpty() || $person['project_id'] != $data['project_id']){ + return '项目人员不存在'; + } + } + if(empty($v['apply_amount'])){ + return '申请付款金额不能为空'; + }else{ + if(!is_numeric($v['apply_amount']) || $v['apply_amount'] <= 0){ + return '申请付款金额必须是大于0的数字'; + } + } + } + return true; + } + +} \ No newline at end of file diff --git a/app/common/model/project/ProjectSalaryDetail.php b/app/common/model/project/ProjectSalaryDetail.php new file mode 100644 index 000000000..94e860068 --- /dev/null +++ b/app/common/model/project/ProjectSalaryDetail.php @@ -0,0 +1,37 @@ +column('name','value'); + return $dictData[$data['payment_type']]; + } +} \ No newline at end of file