diff --git a/app/adminapi/controller/project/ProjectTotalBudgetController.php b/app/adminapi/controller/project/ProjectTotalBudgetController.php new file mode 100644 index 000000000..7aa4904b1 --- /dev/null +++ b/app/adminapi/controller/project/ProjectTotalBudgetController.php @@ -0,0 +1,108 @@ +dataLists(new ProjectTotalBudgetLists()); + } + + + /** + * @notes 添加项目总预算 + * @return \think\response\Json + * @author likeadmin + * @date 2024/01/08 14:25 + */ + public function add() + { + $params = (new ProjectTotalBudgetValidate())->post()->goCheck('add'); + $result = ProjectTotalBudgetLogic::add($params); + if (true === $result) { + return $this->success('添加成功', [], 1, 1); + } + return $this->fail(ProjectTotalBudgetLogic::getError()); + } + + + /** + * @notes 编辑项目总预算 + * @return \think\response\Json + * @author likeadmin + * @date 2024/01/08 14:25 + */ + public function edit() + { + $params = (new ProjectTotalBudgetValidate())->post()->goCheck('edit'); + $result = ProjectTotalBudgetLogic::edit($params); + if (true === $result) { + return $this->success('编辑成功', [], 1, 1); + } + return $this->fail(ProjectTotalBudgetLogic::getError()); + } + + + /** + * @notes 删除项目总预算 + * @return \think\response\Json + * @author likeadmin + * @date 2024/01/08 14:25 + */ + public function delete() + { + $params = (new ProjectTotalBudgetValidate())->post()->goCheck('delete'); + ProjectTotalBudgetLogic::delete($params); + return $this->success('删除成功', [], 1, 1); + } + + + /** + * @notes 获取项目总预算详情 + * @return \think\response\Json + * @author likeadmin + * @date 2024/01/08 14:25 + */ + public function detail() + { + $params = (new ProjectTotalBudgetValidate())->goCheck('detail'); + $result = ProjectTotalBudgetLogic::detail($params); + return $this->data($result); + } + + +} \ No newline at end of file diff --git a/app/adminapi/lists/project/ProjectLists.php b/app/adminapi/lists/project/ProjectLists.php index 29ef818fe..c8268cfd0 100644 --- a/app/adminapi/lists/project/ProjectLists.php +++ b/app/adminapi/lists/project/ProjectLists.php @@ -42,7 +42,7 @@ class ProjectLists extends BaseAdminDataLists implements ListsSearchInterface public function setSearch(): array { return [ - '=' => ['custom_id','status','project_type','project_content','strategic_significance','industry','unit_nature','information_sources'], + '=' => ['custom_id','status','project_type','project_content','strategic_significance','industry','unit_nature','information_sources','is_budget'], '%like%' => ['project_code','name','project_address','person'] ]; } diff --git a/app/adminapi/lists/project/ProjectTotalBudgetLists.php b/app/adminapi/lists/project/ProjectTotalBudgetLists.php new file mode 100644 index 000000000..e8a9cd09f --- /dev/null +++ b/app/adminapi/lists/project/ProjectTotalBudgetLists.php @@ -0,0 +1,91 @@ + ['project_id'], + '%like%' => ['total_cost_code', 'project_manager'], + + ]; + } + + + /** + * @notes 获取项目总预算列表 + * @return array + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + * @author likeadmin + * @date 2024/01/08 14:25 + */ + public function lists(): array + { + return ProjectTotalBudget::where($this->searchWhere) + ->field('id,project_id,total_cost_code,project_manager,budget_date,contract_amount,cl_cost,fb_cost,rg_cost,fy_cost,jj_cost,remark,budget_list') + ->limit($this->limitOffset, $this->limitLength) + ->order(['id' => 'desc']) + ->select()->each(function($data){ + $project = Project::field('name,project_code')->where('id',$data['project_id'])->findOrEmpty(); + $data['project_name'] = $project['name']; + $data['project_code'] = $project['project_code']; + //总成本 + $data['total_cost'] = $data['cl_cost'] + $data['fb_cost'] + $data['rg_cost'] + $data['fy_cost'] + $data['jj_cost']; + //项目利润 + $data['profit'] = $data['contract_amount'] - $data['total_cost']; + //利润率 + $data['profit_rate'] = $data['profit'] / $data['contract_amount']; + return $data; + }) + ->toArray(); + } + + + /** + * @notes 获取项目总预算数量 + * @return int + * @author likeadmin + * @date 2024/01/08 14:25 + */ + public function count(): int + { + return ProjectTotalBudget::where($this->searchWhere)->count(); + } + +} \ No newline at end of file diff --git a/app/adminapi/logic/project/ProjectLogic.php b/app/adminapi/logic/project/ProjectLogic.php index b44faf1a4..189d3879c 100644 --- a/app/adminapi/logic/project/ProjectLogic.php +++ b/app/adminapi/logic/project/ProjectLogic.php @@ -76,6 +76,7 @@ class ProjectLogic extends BaseLogic 'unit_nature' => $params['unit_nature'] ?? 0, 'annex' => $params['annex'] ?? null, 'status' => 0, + 'is_budget' => 0, 'add_user' => $adminId ]); Db::commit(); diff --git a/app/adminapi/logic/project/ProjectTotalBudgetLogic.php b/app/adminapi/logic/project/ProjectTotalBudgetLogic.php new file mode 100644 index 000000000..785e2c70f --- /dev/null +++ b/app/adminapi/logic/project/ProjectTotalBudgetLogic.php @@ -0,0 +1,159 @@ + $params['org_id'], + 'dept_id' => $params['dept_id'], + 'project_id' => $params['project_id'], + 'total_cost_code' => data_unique_code('项目总预算'), + 'contract_amount' => $params['contract_amount'], + 'cl_cost' => $params['cl_cost'] ?? 0, + 'fb_cost' => $params['fb_cost'] ?? 0, + 'rg_cost' => $params['rg_cost'] ?? 0, + 'fy_cost' => $params['fy_cost'] ?? 0, + 'jj_cost' => $params['jj_cost'] ?? 0, + 'remark' => $params['remark'] ?? '', + 'budget_list' => !empty($params['budget_list']) ? $params['budget_list'] : null, + 'budget_date' => strtotime($params['budget_date']), + 'project_manager' => $params['project_manager'], + ]); + Project::where('id',$params['project_id'])->update([ + 'is_budget' => 1, + 'update_time' => time(), + ]); + 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/08 14:25 + */ + public static function edit(array $params): bool + { + Db::startTrans(); + try { + ProjectTotalBudget::where('id', $params['id'])->update([ + 'contract_amount' => $params['contract_amount'], + 'cl_cost' => $params['cl_cost'] ?? 0, + 'fb_cost' => $params['fb_cost'] ?? 0, + 'rg_cost' => $params['rg_cost'] ?? 0, + 'fy_cost' => $params['fy_cost'] ?? 0, + 'jj_cost' => $params['jj_cost'] ?? 0, + 'remark' => $params['remark'] ?? '', + 'budget_list' => !empty($params['budget_list']) ? $params['budget_list'] : null, + 'budget_date' => strtotime($params['budget_date']), + 'project_manager' => $params['project_manager'], + 'update_time' => time(), + ]); + 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/08 14:25 + */ + public static function delete(array $params): bool + { + return ProjectTotalBudget::destroy($params['id']); + } + + + /** + * @notes 获取项目总预算详情 + * @param $params + * @return array + * @author likeadmin + * @date 2024/01/08 14:25 + */ + public static function detail($params): array + { + $data = ProjectTotalBudget::field('id,org_id,dept_id,project_id,total_cost_code,contract_amount,cl_cost,fb_cost,rg_cost,fy_cost,jj_cost,remark,budget_list,budget_date,project_manager') + ->findOrEmpty($params['id']); + $org = Orgs::field('name')->where('id',$data['org_id'])->findOrEmpty(); + $dept = Dept::field('name')->where('id',$data['dept_id'])->findOrEmpty(); + $project = Project::field('name,project_code')->where('id',$data['project_id'])->findOrEmpty(); + $data['org_name'] = $org['name']; + $data['dept_name'] = $dept['name']; + $data['project_name'] = $project['name']; + $data['project_code'] = $project['project_code']; + //总成本 + $data['total_cost'] = $data['cl_cost'] + $data['fb_cost'] + $data['rg_cost'] + $data['fy_cost'] + $data['jj_cost']; + //项目利润 + $data['profit'] = $data['contract_amount'] - $data['total_cost']; + //利润率 + $data['profit_rate'] = $data['profit'] / $data['contract_amount']; + //材料成本占比 + $data['cl_cost_ratio'] = number_format($data['cl_cost'] / $data['total_cost'],2); + //分包成本占比 + $data['fb_cost_ratio'] = number_format($data['fb_cost'] / $data['total_cost'],2); + //人工成本占比 + $data['rg_cost_ratio'] = number_format($data['rg_cost'] / $data['total_cost'],2); + //费用成本占比 + $data['fy_cost_ratio'] = number_format($data['fy_cost'] / $data['total_cost'],2); + //机具成本占比 + $data['jj_cost_ratio'] = number_format($data['jj_cost'] / $data['total_cost'],2); + return $data->toArray(); + } +} \ No newline at end of file diff --git a/app/adminapi/validate/project/ProjectTotalBudgetValidate.php b/app/adminapi/validate/project/ProjectTotalBudgetValidate.php new file mode 100644 index 000000000..c2a543fd8 --- /dev/null +++ b/app/adminapi/validate/project/ProjectTotalBudgetValidate.php @@ -0,0 +1,166 @@ + 'require', + 'org_id' => 'require|checkOrg', + 'dept_id' => 'require|checkDept', + 'project_id' => 'require|checkProject', + 'contract_amount' => 'require|float|egt:0', + 'cl_cost' => 'float|egt:0', + 'fb_cost' => 'float|egt:0', + 'rg_cost' => 'float|egt:0', + 'fy_cost' => 'float|egt:0', + 'jj_cost' => 'float|egt:0', + 'budget_list' => 'checkAnnex', + 'budget_date' => 'require|dateFormat:Y-m-d', + 'project_manager' => 'require', + ]; + + protected $message = [ + 'id.require' => '缺少必要参数', + 'org_id.require' => '请选择组织', + 'dept_id.require' => '请选择部门', + 'project_id.require' => '请选择项目', + 'contract_amount.require' => '请填写合同金额', + 'contract_amount.float' => '合同金额值必须是数字', + 'contract_amount.egt' => '合同金额值必须大于等于0', + 'cl_cost.float' => '材料成本值必须是数字', + 'cl_cost.egt' => '材料成本值必须大于等于0', + 'fb_cost.float' => '分包成本值必须是数字', + 'fb_cost.egt' => '分包成本值必须大于等于0', + 'rg_cost.float' => '人工成本值必须是数字', + 'rg_cost.egt' => '人工成本值必须大于等于0', + 'fy_cost.float' => '费用成本值必须是数字', + 'fy_cost.egt' => '费用成本值必须大于等于0', + 'jj_cost.float' => '机具成本值必须是数字', + 'jj_cost.egt' => '机具成本值必须大于等于0', + 'budget_date.dateFormat' => '预算日期数据格式错误', + 'project_manager' => '请填写项目经理', + ]; + + + /** + * @notes 添加场景 + * @return ProjectTotalBudgetValidate + * @author likeadmin + * @date 2024/01/08 14:25 + */ + public function sceneAdd() + { + return $this->remove('id',true); + } + + + /** + * @notes 编辑场景 + * @return ProjectTotalBudgetValidate + * @author likeadmin + * @date 2024/01/08 14:25 + */ + public function sceneEdit() + { + return $this->remove('org_id',true)->remove('dept_id',true)->remove('project_id',true); + } + + + /** + * @notes 删除场景 + * @return ProjectTotalBudgetValidate + * @author likeadmin + * @date 2024/01/08 14:25 + */ + public function sceneDelete() + { + return $this->only(['id']); + } + + + /** + * @notes 详情场景 + * @return ProjectTotalBudgetValidate + * @author likeadmin + * @date 2024/01/08 14:25 + */ + public function sceneDetail() + { + return $this->only(['id']); + } + + public function checkOrg($value): bool|string + { + $org = Orgs::where('id',$value)->findOrEmpty(); + if($org->isEmpty()){ + return '组织不存在'; + } + return true; + } + + public function checkDept($value,$rule,$data): bool|string + { + $dept = Dept::where('id',$value)->findOrEmpty(); + if($dept->isEmpty()){ + return '部门不存在'; + } + if($dept['org_id'] != $data['org_id']){ + return '部门无效'; + } + return true; + } + + public function checkProject($value): bool|string + { + $project = Project::where('id',$value)->findOrEmpty(); + if($project->isEmpty()){ + return '项目信息不存在'; + } + if($project['is_budget'] == 1){ + return '该项目已编制总预算'; + } + return true; + } + + public function checkAnnex($value): bool|string + { + if(!empty($value) && $value != ''){ + $annex = json_decode($value,true); + if(empty($annex) || !is_array($annex)){ + return '预算清单格式错误'; + } + } + return true; + } + +} \ No newline at end of file diff --git a/app/common/model/project/ProjectTotalBudget.php b/app/common/model/project/ProjectTotalBudget.php new file mode 100644 index 000000000..062feb66a --- /dev/null +++ b/app/common/model/project/ProjectTotalBudget.php @@ -0,0 +1,42 @@ +