diff --git a/app/adminapi/controller/project/ProjectTravelReimbursementController.php b/app/adminapi/controller/project/ProjectTravelReimbursementController.php new file mode 100644 index 000000000..f6737b56a --- /dev/null +++ b/app/adminapi/controller/project/ProjectTravelReimbursementController.php @@ -0,0 +1,108 @@ +dataLists(new ProjectTravelReimbursementLists()); + } + + + /** + * @notes 添加差旅报销 + * @return \think\response\Json + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function add() + { + $params = (new ProjectTravelReimbursementValidate())->post()->goCheck('add'); + $result = ProjectTravelReimbursementLogic::add($params); + if (true === $result) { + return $this->success('添加成功', [], 1, 1); + } + return $this->fail(ProjectTravelReimbursementLogic::getError()); + } + + + /** + * @notes 编辑差旅报销 + * @return \think\response\Json + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function edit() + { + $params = (new ProjectTravelReimbursementValidate())->post()->goCheck('edit'); + $result = ProjectTravelReimbursementLogic::edit($params); + if (true === $result) { + return $this->success('编辑成功', [], 1, 1); + } + return $this->fail(ProjectTravelReimbursementLogic::getError()); + } + + + /** + * @notes 删除差旅报销 + * @return \think\response\Json + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function delete() + { + $params = (new ProjectTravelReimbursementValidate())->post()->goCheck('delete'); + ProjectTravelReimbursementLogic::delete($params); + return $this->success('删除成功', [], 1, 1); + } + + + /** + * @notes 获取差旅报销详情 + * @return \think\response\Json + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function detail() + { + $params = (new ProjectTravelReimbursementValidate())->goCheck('detail'); + $result = ProjectTravelReimbursementLogic::detail($params); + return $this->data($result); + } + + +} \ No newline at end of file diff --git a/app/adminapi/controller/project/ProjectTravelReimbursementDetailController.php b/app/adminapi/controller/project/ProjectTravelReimbursementDetailController.php new file mode 100644 index 000000000..5ba2eba9d --- /dev/null +++ b/app/adminapi/controller/project/ProjectTravelReimbursementDetailController.php @@ -0,0 +1,108 @@ +dataLists(new ProjectTravelReimbursementDetailLists()); + } + + + /** + * @notes 添加报销明细 + * @return \think\response\Json + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function add() + { + $params = (new ProjectTravelReimbursementDetailValidate())->post()->goCheck('add'); + $result = ProjectTravelReimbursementDetailLogic::add($params); + if (true === $result) { + return $this->success('添加成功', [], 1, 1); + } + return $this->fail(ProjectTravelReimbursementDetailLogic::getError()); + } + + + /** + * @notes 编辑报销明细 + * @return \think\response\Json + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function edit() + { + $params = (new ProjectTravelReimbursementDetailValidate())->post()->goCheck('edit'); + $result = ProjectTravelReimbursementDetailLogic::edit($params); + if (true === $result) { + return $this->success('编辑成功', [], 1, 1); + } + return $this->fail(ProjectTravelReimbursementDetailLogic::getError()); + } + + + /** + * @notes 删除报销明细 + * @return \think\response\Json + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function delete() + { + $params = (new ProjectTravelReimbursementDetailValidate())->post()->goCheck('delete'); + ProjectTravelReimbursementDetailLogic::delete($params); + return $this->success('删除成功', [], 1, 1); + } + + + /** + * @notes 获取报销明细详情 + * @return \think\response\Json + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function detail() + { + $params = (new ProjectTravelReimbursementDetailValidate())->goCheck('detail'); + $result = ProjectTravelReimbursementDetailLogic::detail($params); + return $this->data($result); + } + + +} \ No newline at end of file diff --git a/app/adminapi/controller/project/ProjectTravelReimbursementInvoiceDetailController.php b/app/adminapi/controller/project/ProjectTravelReimbursementInvoiceDetailController.php new file mode 100644 index 000000000..ed9747268 --- /dev/null +++ b/app/adminapi/controller/project/ProjectTravelReimbursementInvoiceDetailController.php @@ -0,0 +1,108 @@ +dataLists(new ProjectTravelReimbursementInvoiceDetailLists()); + } + + + /** + * @notes 添加发票明细 + * @return \think\response\Json + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function add() + { + $params = (new ProjectTravelReimbursementInvoiceDetailValidate())->post()->goCheck('add'); + $result = ProjectTravelReimbursementInvoiceDetailLogic::add($params); + if (true === $result) { + return $this->success('添加成功', [], 1, 1); + } + return $this->fail(ProjectTravelReimbursementInvoiceDetailLogic::getError()); + } + + + /** + * @notes 编辑发票明细 + * @return \think\response\Json + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function edit() + { + $params = (new ProjectTravelReimbursementInvoiceDetailValidate())->post()->goCheck('edit'); + $result = ProjectTravelReimbursementInvoiceDetailLogic::edit($params); + if (true === $result) { + return $this->success('编辑成功', [], 1, 1); + } + return $this->fail(ProjectTravelReimbursementInvoiceDetailLogic::getError()); + } + + + /** + * @notes 删除发票明细 + * @return \think\response\Json + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function delete() + { + $params = (new ProjectTravelReimbursementInvoiceDetailValidate())->post()->goCheck('delete'); + ProjectTravelReimbursementInvoiceDetailLogic::delete($params); + return $this->success('删除成功', [], 1, 1); + } + + + /** + * @notes 获取发票明细详情 + * @return \think\response\Json + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function detail() + { + $params = (new ProjectTravelReimbursementInvoiceDetailValidate())->goCheck('detail'); + $result = ProjectTravelReimbursementInvoiceDetailLogic::detail($params); + return $this->data($result); + } + + +} \ No newline at end of file diff --git a/app/adminapi/lists/project/ProjectTravelReimbursementDetailLists.php b/app/adminapi/lists/project/ProjectTravelReimbursementDetailLists.php new file mode 100644 index 000000000..247ec252e --- /dev/null +++ b/app/adminapi/lists/project/ProjectTravelReimbursementDetailLists.php @@ -0,0 +1,77 @@ + ['travel_reimbursement_id'], + ]; + } + + + /** + * @notes 获取报销明细列表 + * @return array + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function lists(): array + { + return ProjectTravelReimbursementDetail::where($this->searchWhere) + ->field(['id', 'travel_reimbursement_id', 'project_cost_temp_id', 'traffic_fee', 'stay_fee', 'restaurant_fee', 'subsidy_fee', 'other_fee', 'remark']) + ->limit($this->limitOffset, $this->limitLength) + ->order(['id' => 'desc']) + ->select() + ->toArray(); + } + + + /** + * @notes 获取报销明细数量 + * @return int + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function count(): int + { + return ProjectTravelReimbursementDetail::where($this->searchWhere)->count(); + } + +} \ No newline at end of file diff --git a/app/adminapi/lists/project/ProjectTravelReimbursementInvoiceDetailLists.php b/app/adminapi/lists/project/ProjectTravelReimbursementInvoiceDetailLists.php new file mode 100644 index 000000000..bf011c67c --- /dev/null +++ b/app/adminapi/lists/project/ProjectTravelReimbursementInvoiceDetailLists.php @@ -0,0 +1,77 @@ + ['travel_reimbursement_id', 'invoice_type', 'invoice_sn', 'invoice_form'], + ]; + } + + + /** + * @notes 获取发票明细列表 + * @return array + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function lists(): array + { + return ProjectTravelReimbursementInvoiceDetail::where($this->searchWhere) + ->field(['id', 'travel_reimbursement_id', 'invoice_type', 'invoice_sn', 'tax_rate', 'invoice_form', 'invoice_amount', 'tax_amount', 'annex', 'remark']) + ->limit($this->limitOffset, $this->limitLength) + ->order(['id' => 'desc']) + ->select() + ->toArray(); + } + + + /** + * @notes 获取发票明细数量 + * @return int + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function count(): int + { + return ProjectTravelReimbursementInvoiceDetail::where($this->searchWhere)->count(); + } + +} \ No newline at end of file diff --git a/app/adminapi/lists/project/ProjectTravelReimbursementLists.php b/app/adminapi/lists/project/ProjectTravelReimbursementLists.php new file mode 100644 index 000000000..82f6f62e9 --- /dev/null +++ b/app/adminapi/lists/project/ProjectTravelReimbursementLists.php @@ -0,0 +1,103 @@ + ['trip_apply_id', 'project_id', 'reimbursement_type'], + '%like%' => ['apply_user'], + ]; + } + + + /** + * @notes 获取差旅报销列表 + * @return array + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function lists(): array + { + $field = 'id,trip_apply_id,project_id,trip_reimbursement_code,reimbursement_type,loan_apply_id,reimbursement_amount,actual_reimbursement_amount,offset_loan_amount,apply_user,apply_date,remark'; + return ProjectTravelReimbursement::where($this->searchWhere) + ->field($field) + ->limit($this->limitOffset, $this->limitLength) + ->order(['id' => 'desc']) + ->select()->each(function($data){ + $trip_apply = ProjectTripApply::field('trip_apply_code')->where('id',$data['trip_apply_id'])->findOrEmpty(); + $project = Project::field('name,project_code')->where('id',$data['project_id'])->findOrEmpty(); + $manager = ProjectManagerAppointment::field('project_manager')->where('project_id',$data['project_id'])->findOrEmpty(); + $loan_apply = ProjectLoanApply::field('loan_apply_code,loan_amount')->where('id',$data['loan_apply_id'])->findOrEmpty(); + $data['trip_apply_code'] = $trip_apply['trip_apply_code']; + $data['project_name'] = $project['name']; + $data['project_code'] = $project['project_code']; + if($manager->isEmpty()){ + $data['project_manager'] = ''; + }else{ + $admin = Admin::field('name')->where('id',$manager['project_manager'])->findOrEmpty(); + $data['project_manager'] = $admin['name']; + } + $data['loan_apply_code'] = !$loan_apply->isEmpty() ? $loan_apply['loan_apply_code'] : '---'; + $data['loan_amount'] = !$loan_apply->isEmpty() ? $loan_apply['loan_amount'] : '---'; + $data['reimbursement_type'] = $data->reimbursement_type_text; + unset($data['trip_apply_id'],$data['loan_apply_id']); + return $data; + }) + ->toArray(); + } + + + /** + * @notes 获取差旅报销数量 + * @return int + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function count(): int + { + return ProjectTravelReimbursement::where($this->searchWhere)->count(); + } + +} \ No newline at end of file diff --git a/app/adminapi/logic/project/ProjectTravelReimbursementDetailLogic.php b/app/adminapi/logic/project/ProjectTravelReimbursementDetailLogic.php new file mode 100644 index 000000000..cf1bb032f --- /dev/null +++ b/app/adminapi/logic/project/ProjectTravelReimbursementDetailLogic.php @@ -0,0 +1,120 @@ + $params['travel_reimbursement_id'], + 'project_cost_temp_id' => $params['project_cost_temp_id'], + 'traffic_fee' => $params['traffic_fee'], + 'stay_fee' => $params['stay_fee'], + 'restaurant_fee' => $params['restaurant_fee'], + 'subsidy_fee' => $params['subsidy_fee'], + 'other_fee' => $params['other_fee'], + 'remark' => $params['remark'], + ]); + + Db::commit(); + return true; + } catch (\Exception $e) { + Db::rollback(); + self::setError($e->getMessage()); + return false; + } + } + + + /** + * @notes 编辑报销明细 + * @param array $params + * @return bool + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public static function edit(array $params): bool + { + Db::startTrans(); + try { + ProjectTravelReimbursementDetail::where('id', $params['id'])->update([ + 'travel_reimbursement_id' => $params['travel_reimbursement_id'], + 'project_cost_temp_id' => $params['project_cost_temp_id'], + 'traffic_fee' => $params['traffic_fee'], + 'stay_fee' => $params['stay_fee'], + 'restaurant_fee' => $params['restaurant_fee'], + 'subsidy_fee' => $params['subsidy_fee'], + 'other_fee' => $params['other_fee'], + 'remark' => $params['remark'], + ]); + + Db::commit(); + return true; + } catch (\Exception $e) { + Db::rollback(); + self::setError($e->getMessage()); + return false; + } + } + + + /** + * @notes 删除报销明细 + * @param array $params + * @return bool + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public static function delete(array $params): bool + { + return ProjectTravelReimbursementDetail::destroy($params['id']); + } + + + /** + * @notes 获取报销明细详情 + * @param $params + * @return array + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public static function detail($params): array + { + return ProjectTravelReimbursementDetail::findOrEmpty($params['id'])->toArray(); + } +} \ No newline at end of file diff --git a/app/adminapi/logic/project/ProjectTravelReimbursementInvoiceDetailLogic.php b/app/adminapi/logic/project/ProjectTravelReimbursementInvoiceDetailLogic.php new file mode 100644 index 000000000..11b26c2f0 --- /dev/null +++ b/app/adminapi/logic/project/ProjectTravelReimbursementInvoiceDetailLogic.php @@ -0,0 +1,122 @@ + $params['travel_reimbursement_id'], + 'invoice_type' => $params['invoice_type'], + 'invoice_sn' => $params['invoice_sn'], + 'tax_rate' => $params['tax_rate'], + 'invoice_form' => $params['invoice_form'], + 'invoice_amount' => $params['invoice_amount'], + 'tax_amount' => $params['tax_amount'], + 'annex' => $params['annex'], + 'remark' => $params['remark'], + ]); + + Db::commit(); + return true; + } catch (\Exception $e) { + Db::rollback(); + self::setError($e->getMessage()); + return false; + } + } + + + /** + * @notes 编辑发票明细 + * @param array $params + * @return bool + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public static function edit(array $params): bool + { + Db::startTrans(); + try { + ProjectTravelReimbursementInvoiceDetail::where('id', $params['id'])->update([ + 'travel_reimbursement_id' => $params['travel_reimbursement_id'], + 'invoice_type' => $params['invoice_type'], + 'invoice_sn' => $params['invoice_sn'], + 'tax_rate' => $params['tax_rate'], + 'invoice_form' => $params['invoice_form'], + 'invoice_amount' => $params['invoice_amount'], + 'tax_amount' => $params['tax_amount'], + 'annex' => $params['annex'], + 'remark' => $params['remark'], + ]); + + Db::commit(); + return true; + } catch (\Exception $e) { + Db::rollback(); + self::setError($e->getMessage()); + return false; + } + } + + + /** + * @notes 删除发票明细 + * @param array $params + * @return bool + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public static function delete(array $params): bool + { + return ProjectTravelReimbursementInvoiceDetail::destroy($params['id']); + } + + + /** + * @notes 获取发票明细详情 + * @param $params + * @return array + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public static function detail($params): array + { + return ProjectTravelReimbursementInvoiceDetail::findOrEmpty($params['id'])->toArray(); + } +} \ No newline at end of file diff --git a/app/adminapi/logic/project/ProjectTravelReimbursementLogic.php b/app/adminapi/logic/project/ProjectTravelReimbursementLogic.php new file mode 100644 index 000000000..2450f8709 --- /dev/null +++ b/app/adminapi/logic/project/ProjectTravelReimbursementLogic.php @@ -0,0 +1,261 @@ +where('id',$params['trip_apply_id'])->findOrEmpty(); + //初始报销金额 = 所有报销明细中的交通、住宿、餐饮、补助、其他金额之和 + $reimbursement_amount = 0; + foreach($params['reimbursement_detail'] as $v){ + $reimbursement_amount += ($v['traffic_fee'] + $v['stay_fee'] + $v['restaurant_fee'] + $v['subsidy_fee'] + $v['other_fee']); + } + //获取税率 + $tax_rate = DictData::where('type_value','tax_rate')->column('name','value'); + Db::startTrans(); + try { + $res = ProjectTravelReimbursement::create([ + 'trip_reimbursement_code' => data_unique_code('项目差旅报销'), + 'trip_apply_id' => $params['trip_apply_id'], + 'project_id' => $trip_apply['project_id'], + 'reimbursement_type' => $params['reimbursement_type'], + 'loan_apply_id' => $params['loan_apply_id'] ?? 0, + 'reimbursement_amount' => $reimbursement_amount,//初始报销金额 + 'actual_reimbursement_amount' => $reimbursement_amount - $params['offset_loan_amount'],//实际报销金额 + 'offset_loan_amount' => $params['offset_loan_amount'] ?? 0,//冲抵借款金额 + 'apply_user' => $params['apply_user'], + 'apply_date' => strtotime($params['apply_date']), + 'payee_name' => $params['payee_name'], + 'payee_bank' => $params['payee_bank'], + 'payee_account' => $params['payee_account'], + 'remark' => $params['remark'] ?? '', + 'annex' => $params['annex'] ? json_encode($params['annex']) : null, + 'bank_account_id' => $params['bank_account_id'], + ]); + foreach($params['reimbursement_detail'] as $item){ + ProjectTravelReimbursementDetail::create([ + 'travel_reimbursement_id' => $res->id, + 'project_cost_temp_id' => $item['project_cost_temp_id'], + 'traffic_fee' => $item['traffic_fee'] ?? 0, + 'stay_fee' => $item['stay_fee'] ?? 0, + 'restaurant_fee' => $item['restaurant_fee'] ?? 0, + 'subsidy_fee' => $item['subsidy_fee'] ?? 0, + 'other_fee' => $item['other_fee'] ?? 0, + 'total_amount' => $item['traffic_fee'] + $item['stay_fee'] + $item['restaurant_fee'] + $item['subsidy_fee'] + $item['other_fee'], + 'remark' => $item['remark'] ?? '', + ]); + } + foreach($params['invoice_detail'] as $item){ + ProjectTravelReimbursementInvoiceDetail::create([ + 'travel_reimbursement_id' => $res->id, + 'invoice_type' => $item['invoice_type'], + 'invoice_sn' => $item['invoice_sn'], + 'tax_rate' => $item['tax_rate'], + 'invoice_form' => $item['invoice_form'], + 'invoice_amount' => $item['invoice_amount'], + 'tax_amount' => $tax_rate[$item['tax_rate']] / 100 * $item['invoice_amount'], + 'annex' => $item['annex'] ? json_encode($item['annex']) : null, + 'remark' => $item['remark'] ?? '', + ]); + } + Db::commit(); + return true; + } catch (\Exception $e) { + Db::rollback(); + self::setError($e->getMessage()); + return false; + } + } + + + /** + * @notes 编辑差旅报销 + * @param array $params + * @return bool + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public static function edit(array $params): bool + { + $trip_apply = ProjectTripApply::field('project_id')->where('id',$params['trip_apply_id'])->findOrEmpty(); + //初始报销金额 = 所有报销明细中的交通、住宿、餐饮、补助、其他金额之和 + $reimbursement_amount = 0; + foreach($params['reimbursement_detail'] as $v){ + $reimbursement_amount += ($v['traffic_fee'] + $v['stay_fee'] + $v['restaurant_fee'] + $v['subsidy_fee'] + $v['other_fee']); + } + //获取税率 + $tax_rate = DictData::where('type_value','tax_rate')->column('name','value'); + Db::startTrans(); + try { + ProjectTravelReimbursement::where('id', $params['id'])->update([ + 'trip_apply_id' => $params['trip_apply_id'], + 'project_id' => $trip_apply['project_id'], + 'reimbursement_type' => $params['reimbursement_type'], + 'loan_apply_id' => $params['loan_apply_id'] ?? 0, + 'reimbursement_amount' => $reimbursement_amount,//初始报销金额 + 'actual_reimbursement_amount' => $reimbursement_amount - $params['offset_loan_amount'],//实际报销金额 + 'offset_loan_amount' => $params['offset_loan_amount'] ?? 0,//冲抵借款金额 + 'apply_user' => $params['apply_user'], + 'apply_date' => strtotime($params['apply_date']), + 'payee_name' => $params['payee_name'], + 'payee_bank' => $params['payee_bank'], + 'payee_account' => $params['payee_account'], + 'remark' => $params['remark'] ?? '', + 'annex' => $params['annex'] ? json_encode($params['annex']) : null, + 'bank_account_id' => $params['bank_account_id'], + 'update_time' => time(), + ]); + foreach($params['reimbursement_detail'] as $item){ + if(isset($item['id']) && $item['id'] != ''){ + ProjectTravelReimbursementDetail::where('id',$item['id'])->update([ + 'travel_reimbursement_id' => $params['id'], + 'project_cost_temp_id' => $item['project_cost_temp_id'], + 'traffic_fee' => $item['traffic_fee'] ?? 0, + 'stay_fee' => $item['stay_fee'] ?? 0, + 'restaurant_fee' => $item['restaurant_fee'] ?? 0, + 'subsidy_fee' => $item['subsidy_fee'] ?? 0, + 'other_fee' => $item['other_fee'] ?? 0, + 'total_amount' => $item['traffic_fee'] + $item['stay_fee'] + $item['restaurant_fee'] + $item['subsidy_fee'] + $item['other_fee'], + 'remark' => $item['remark'] ?? '', + 'update_time' => time(), + ]); + }else{ + ProjectTravelReimbursementDetail::create([ + 'travel_reimbursement_id' => $params['id'], + 'project_cost_temp_id' => $item['project_cost_temp_id'], + 'traffic_fee' => $item['traffic_fee'] ?? 0, + 'stay_fee' => $item['stay_fee'] ?? 0, + 'restaurant_fee' => $item['restaurant_fee'] ?? 0, + 'subsidy_fee' => $item['subsidy_fee'] ?? 0, + 'other_fee' => $item['other_fee'] ?? 0, + 'total_amount' => $item['traffic_fee'] + $item['stay_fee'] + $item['restaurant_fee'] + $item['subsidy_fee'] + $item['other_fee'], + 'remark' => $item['remark'] ?? '', + ]); + } + } + foreach($params['invoice_detail'] as $item){ + if(isset($item['id']) && $item['id'] != ''){ + ProjectTravelReimbursementInvoiceDetail::where('id',$item['id'])->update([ + 'travel_reimbursement_id' => $params['id'], + 'invoice_type' => $item['invoice_type'], + 'invoice_sn' => $item['invoice_sn'], + 'tax_rate' => $item['tax_rate'], + 'invoice_form' => $item['invoice_form'], + 'invoice_amount' => $item['invoice_amount'], + 'tax_amount' => $tax_rate[$item['tax_rate']] / 100 * $item['invoice_amount'], + 'annex' => $item['annex'] ? json_encode($item['annex']) : null, + 'remark' => $item['remark'] ?? '', + 'update_time' => time(), + ]); + }else{ + ProjectTravelReimbursementInvoiceDetail::create([ + 'travel_reimbursement_id' => $params['id'], + 'invoice_type' => $item['invoice_type'], + 'invoice_sn' => $item['invoice_sn'], + 'tax_rate' => $item['tax_rate'], + 'invoice_form' => $item['invoice_form'], + 'invoice_amount' => $item['invoice_amount'], + 'tax_amount' => $tax_rate[$item['tax_rate']] / 100 * $item['invoice_amount'], + 'annex' => $item['annex'] ? json_encode($item['annex']) : null, + 'remark' => $item['remark'] ?? '', + ]); + } + } + Db::commit(); + return true; + } catch (\Exception $e) { + Db::rollback(); + self::setError($e->getMessage()); + return false; + } + } + + + /** + * @notes 删除差旅报销 + * @param array $params + * @return bool + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public static function delete(array $params): bool + { + return ProjectTravelReimbursement::destroy($params['id']); + } + + + /** + * @notes 获取差旅报销详情 + * @param $params + * @return array + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public static function detail($params): array + { + $field = 'id,trip_apply_id,project_id,trip_reimbursement_code,reimbursement_type,loan_apply_id,reimbursement_amount,actual_reimbursement_amount,offset_loan_amount,apply_user,apply_date,payee_name,payee_bank,payee_account,remark,annex,bank_account_id'; + $data = ProjectTravelReimbursement::field($field) + ->findOrEmpty($params['id']); + $trip_apply = ProjectTripApply::field('trip_apply_code')->where('id',$data['trip_apply_id'])->findOrEmpty(); + $project = Project::field('name,project_code')->where('id',$data['project_id'])->findOrEmpty(); + $manager = ProjectManagerAppointment::field('project_manager')->where('project_id',$data['project_id'])->findOrEmpty(); + $loan_apply = ProjectLoanApply::field('loan_apply_code,loan_amount')->where('id',$data['loan_apply_id'])->findOrEmpty(); + $data['trip_apply_code'] = $trip_apply['trip_apply_code']; + $data['project_name'] = $project['name']; + $data['project_code'] = $project['project_code']; + if($manager->isEmpty()){ + $data['project_manager'] = ''; + }else{ + $admin = Admin::field('name')->where('id',$manager['project_manager'])->findOrEmpty(); + $data['project_manager'] = $admin['name']; + } + $data['loan_apply_code'] = !$loan_apply->isEmpty() ? $loan_apply['loan_apply_code'] : '---'; + $data['loan_amount'] = !$loan_apply->isEmpty() ? $loan_apply['loan_amount'] : '---'; + $data['reimbursement_type_text'] = $data->reimbursement_type_text; + $data['bank_account'] = BankAccount::field('account_sn,deposit_bank,account_name,account')->where('id',$data['bank_account_id'])->findOrEmpty(); + return $data->toArray(); + } +} \ No newline at end of file diff --git a/app/adminapi/validate/project/ProjectTravelReimbursementDetailValidate.php b/app/adminapi/validate/project/ProjectTravelReimbursementDetailValidate.php new file mode 100644 index 000000000..650effdab --- /dev/null +++ b/app/adminapi/validate/project/ProjectTravelReimbursementDetailValidate.php @@ -0,0 +1,108 @@ + 'require', + 'travel_reimbursement_id' => 'require', + 'project_cost_temp_id' => 'require', + 'traffic_fee' => 'require', + 'stay_fee' => 'require', + 'restaurant_fee' => 'require', + 'subsidy_fee' => 'require', + 'other_fee' => 'require', + ]; + + + /** + * 参数描述 + * @var string[] + */ + protected $field = [ + 'id' => 'id', + 'travel_reimbursement_id' => '差旅报销单id', + 'project_cost_temp_id' => '项目费用模板id', + 'traffic_fee' => '交通', + 'stay_fee' => '住宿', + 'restaurant_fee' => '餐饮', + 'subsidy_fee' => '补助', + 'other_fee' => '其它', + ]; + + + /** + * @notes 添加场景 + * @return ProjectTravelReimbursementDetailValidate + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function sceneAdd() + { + return $this->only(['travel_reimbursement_id','project_cost_temp_id','traffic_fee','stay_fee','restaurant_fee','subsidy_fee','other_fee']); + } + + + /** + * @notes 编辑场景 + * @return ProjectTravelReimbursementDetailValidate + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function sceneEdit() + { + return $this->only(['id','travel_reimbursement_id','project_cost_temp_id','traffic_fee','stay_fee','restaurant_fee','subsidy_fee','other_fee']); + } + + + /** + * @notes 删除场景 + * @return ProjectTravelReimbursementDetailValidate + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function sceneDelete() + { + return $this->only(['id']); + } + + + /** + * @notes 详情场景 + * @return ProjectTravelReimbursementDetailValidate + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function sceneDetail() + { + return $this->only(['id']); + } + +} \ No newline at end of file diff --git a/app/adminapi/validate/project/ProjectTravelReimbursementInvoiceDetailValidate.php b/app/adminapi/validate/project/ProjectTravelReimbursementInvoiceDetailValidate.php new file mode 100644 index 000000000..5b45a2997 --- /dev/null +++ b/app/adminapi/validate/project/ProjectTravelReimbursementInvoiceDetailValidate.php @@ -0,0 +1,108 @@ + 'require', + 'travel_reimbursement_id' => 'require', + 'invoice_type' => 'require', + 'invoice_sn' => 'require', + 'tax_rate' => 'require', + 'invoice_form' => 'require', + 'invoice_amount' => 'require', + 'tax_amount' => 'require', + ]; + + + /** + * 参数描述 + * @var string[] + */ + protected $field = [ + 'id' => 'id', + 'travel_reimbursement_id' => '差旅报销id', + 'invoice_type' => '发票类型', + 'invoice_sn' => '发票号', + 'tax_rate' => '发票税率', + 'invoice_form' => '发票形式', + 'invoice_amount' => '发票金额', + 'tax_amount' => '发票税额', + ]; + + + /** + * @notes 添加场景 + * @return ProjectTravelReimbursementInvoiceDetailValidate + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function sceneAdd() + { + return $this->only(['travel_reimbursement_id','invoice_type','invoice_sn','tax_rate','invoice_form','invoice_amount','tax_amount']); + } + + + /** + * @notes 编辑场景 + * @return ProjectTravelReimbursementInvoiceDetailValidate + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function sceneEdit() + { + return $this->only(['id','travel_reimbursement_id','invoice_type','invoice_sn','tax_rate','invoice_form','invoice_amount','tax_amount']); + } + + + /** + * @notes 删除场景 + * @return ProjectTravelReimbursementInvoiceDetailValidate + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function sceneDelete() + { + return $this->only(['id']); + } + + + /** + * @notes 详情场景 + * @return ProjectTravelReimbursementInvoiceDetailValidate + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function sceneDetail() + { + return $this->only(['id']); + } + +} \ No newline at end of file diff --git a/app/adminapi/validate/project/ProjectTravelReimbursementValidate.php b/app/adminapi/validate/project/ProjectTravelReimbursementValidate.php new file mode 100644 index 000000000..e7a9607fc --- /dev/null +++ b/app/adminapi/validate/project/ProjectTravelReimbursementValidate.php @@ -0,0 +1,286 @@ + 'require', + 'trip_apply_id' => 'require|checkTripApply', + 'reimbursement_type' => 'require|checkReimbursementType', + 'loan_apply_id' => 'requireCallback:check_require|checkLoanApply', + 'offset_loan_amount' => 'requireCallback:check_require|float|egt:0', + 'apply_user' => 'require', + 'apply_date' => 'require|dateFormat:Y-m-d', + 'payee_name' => 'require', + 'payee_bank' => 'require', + 'payee_account' => 'require', + 'annex' => 'checkAnnex', + 'bank_account_id' => 'require|checkBankAccount', + 'reimbursement_detail' => 'require|checkReimbursementDetail', + 'invoice_detail' => 'require|checkInvoiceDetail', + ]; + + + /** + * 参数描述 + * @var string[] + */ + protected $field = [ + 'id' => 'id', + 'trip_apply_id' => '出差申请单id', + 'reimbursement_type' => '报销类型', + 'loan_apply_id' => '借款申请id', + 'offset_loan_amount' => '冲抵借款金额', + 'apply_user' => '报销人', + 'apply_date' => '报销日期', + 'payee_name' => '收款人姓名', + 'payee_bank' => '收款银行', + 'payee_account' => '收款账号', + 'bank_account_id' => '付款银行账户id', + 'reimbursement_detail' => '报销明细', + 'invoice_detail' => '发票明细', + ]; + + + /** + * @notes 添加场景 + * @return ProjectTravelReimbursementValidate + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function sceneAdd() + { + return $this->remove('id',true); + } + + + /** + * @notes 编辑场景 + * @return ProjectTravelReimbursementValidate + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function sceneEdit() + {} + + + /** + * @notes 删除场景 + * @return ProjectTravelReimbursementValidate + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function sceneDelete() + { + return $this->only(['id']); + } + + + /** + * @notes 详情场景 + * @return ProjectTravelReimbursementValidate + * @author likeadmin + * @date 2024/01/18 13:57 + */ + public function sceneDetail() + { + return $this->only(['id']); + } + + public function checkTripApply($value): bool|string + { + $data = ProjectTripApply::where('id',$value)->findOrEmpty(); + if($data->isEmpty()){ + return '出差申请信息不存在'; + } + return true; + } + + public function checkReimbursementType($value): bool|string + { + $data = explode(',',$value); + if(empty($data)){ + return '报销类型数据格式错误'; + } + foreach ($data as $v) { + $dict = DictData::where('type_value','reimbursement_type')->column('value'); + if(!in_array($v,$dict)){ + return '报销类型数据无效'; + } + } + return true; + } + + function check_require($value,$data): bool + { + $reimbursement_type = explode(',',$data['reimbursement_type']); + return in_array(1,$reimbursement_type); + } + + public function checkLoanApply($value): bool|string + { + $loan_apply_data = ProjectLoanApply::where('id',$value)->findOrEmpty(); + if($loan_apply_data->isEmpty()){ + return '借款单信息不存在'; + } + return true; + } + + public function checkAnnex($value): bool|string + { + if(!empty($value) && $value != ''){ + if(!is_array($value)){ + return '附件格式错误'; + } + } + return true; + } + + public function checkBankAccount($value): bool|string + { + $data = BankAccount::where('id',$value)->findOrEmpty(); + if($data->isEmpty()){ + return '付款银行账户信息不存在'; + } + return true; + } + + public function checkReimbursementDetail($value): bool|string + { + if(empty($value) || !is_array($value)){ + return '报销明细数据格式错误'; + } + foreach($value as $v){ + if(isset($v['id']) && $v['id'] != ''){ + $reimbursement_detail = ProjectTravelReimbursementDetail::where('id',$v['id'])->findOrEmpty(); + if($reimbursement_detail->isEmpty()){ + return '报销明细信息不存在'; + } + } + if(empty($v['project_cost_temp_id'])){ + return '请选择项目费用模板'; + }else{ + $project_cost_temp = ProjectCostTempSet::where('id',$v['project_cost_temp_id'])->findOrEmpty(); + if($project_cost_temp->isEmpty()){ + return '项目费用模板信息不存在'; + } + } + if(isset($v['traffic_fee']) && $v['traffic_fee'] != ''){ + if(!is_numeric($v['traffic_fee'])){ + return '交通费用必须是数字'; + } + } + if(isset($v['stay_fee']) && $v['stay_fee'] != ''){ + if(!is_numeric($v['stay_fee'])){ + return '住宿费用必须是数字'; + } + } + if(isset($v['restaurant_fee']) && $v['restaurant_fee'] != ''){ + if(!is_numeric($v['restaurant_fee'])){ + return '餐饮费用必须是数字'; + } + } + if(isset($v['subsidy_fee']) && $v['subsidy_fee'] != ''){ + if(!is_numeric($v['subsidy_fee'])){ + return '补助费用必须是数字'; + } + } + if(isset($v['other_fee']) && $v['other_fee'] != ''){ + if(!is_numeric($v['other_fee'])){ + return '其他费用必须是数字'; + } + } + } + return true; + } + + public function checkInvoiceDetail($value): bool|string + { + if(empty($value) || !is_array($value)){ + return '发票明细数据格式错误'; + } + foreach($value as $v){ + if(isset($v['id']) && $v['id'] != ''){ + $invoice_detail = ProjectTravelReimbursementInvoiceDetail::where('id',$v['id'])->findOrEmpty(); + if($invoice_detail->isEmpty()){ + return '发票明细信息不存在'; + } + } + if(empty($v['invoice_type'])){ + return '请选择发票类型'; + }else{ + $invoice_type_dict = DictData::where('type_value','invoice_type')->column('value'); + if(!in_array($v['invoice_type'],$invoice_type_dict)){ + return '发票类型数据值无效'; + } + } + if(empty($v['invoice_sn'])){ + return '请填写发票号'; + } + if(empty($v['tax_rate'])){ + return '请选择发票税率'; + }else{ + $tax_rate_dict = DictData::where('type_value','tax_rate')->column('value'); + if(!in_array($v['tax_rate'],$tax_rate_dict)){ + return '发票税率数据值无效'; + } + } + if(empty($v['invoice_form'])){ + return '请选择发票形式'; + }else{ + $invoice_form_dict = DictData::where('type_value','invoice_form')->column('value'); + if(!in_array($v['invoice_form'],$invoice_form_dict)){ + return '发票形式数据值无效'; + } + } + if(empty($v['invoice_amount'])){ + return '请填写发票金额'; + }else{ + if(!is_numeric($v['invoice_amount']) || $v['invoice_amount'] < 0){ + return '发票金额必须是大于0的数字'; + } + } + if(isset($v['annex']) && $v['annex'] != ''){ + if(!is_array($v['annex'])){ + return '发票附件格式错误'; + } + } + } + return true; + } + +} \ No newline at end of file diff --git a/app/common/model/project/ProjectTravelReimbursement.php b/app/common/model/project/ProjectTravelReimbursement.php new file mode 100644 index 000000000..e97013c38 --- /dev/null +++ b/app/common/model/project/ProjectTravelReimbursement.php @@ -0,0 +1,46 @@ +whereIn('value',$data['reimbursement_type'])->column('name'); + return $data['reimbursement_type'] ? implode(',',$dictData) : ''; + } +} \ No newline at end of file diff --git a/app/common/model/project/ProjectTravelReimbursementDetail.php b/app/common/model/project/ProjectTravelReimbursementDetail.php new file mode 100644 index 000000000..98307f5d2 --- /dev/null +++ b/app/common/model/project/ProjectTravelReimbursementDetail.php @@ -0,0 +1,34 @@ +