feat: 项目成本分析报告工具
This commit is contained in:
@@ -16,7 +16,7 @@ class ProjectModel(BasicModel, table=True):
|
|||||||
name: str = Field(default=None, description="项目名称")
|
name: str = Field(default=None, description="项目名称")
|
||||||
description: str = Field(default=None, description="项目描述")
|
description: str = Field(default=None, description="项目描述")
|
||||||
budget: Decimal = Field(default=None, description="项目预算金额")
|
budget: Decimal = Field(default=None, description="项目预算金额")
|
||||||
version: int = Field(default=None, description="项目版本号")
|
# version: int = Field(default=None, description="项目版本号")
|
||||||
|
|
||||||
# /*---------------------------------------leader_id-------------------------------------------*/
|
# /*---------------------------------------leader_id-------------------------------------------*/
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ from app.tools.tool_add import tool_add
|
|||||||
from app.tools.tool_book_hotel import tool_book_hotel
|
from app.tools.tool_book_hotel import tool_book_hotel
|
||||||
from app.tools.tool_get_datetime import tool_get_datetime
|
from app.tools.tool_get_datetime import tool_get_datetime
|
||||||
from app.tools.tool_multiple import tool_multiply
|
from app.tools.tool_multiple import tool_multiply
|
||||||
|
from app.tools.tool_project_analysis import tool_project_analysis
|
||||||
from app.tools.tool_query_direct_subordinates import tool_query_direct_subordinates
|
from app.tools.tool_query_direct_subordinates import tool_query_direct_subordinates
|
||||||
from app.tools.tool_query_projects import tool_query_projects
|
from app.tools.tool_query_projects import tool_query_projects
|
||||||
|
|
||||||
@@ -12,4 +13,5 @@ tool_list = [
|
|||||||
tool_multiply,
|
tool_multiply,
|
||||||
tool_query_direct_subordinates,
|
tool_query_direct_subordinates,
|
||||||
tool_query_projects,
|
tool_query_projects,
|
||||||
|
tool_project_analysis,
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,15 +1,92 @@
|
|||||||
|
from decimal import Decimal
|
||||||
|
from typing import Annotated, List
|
||||||
|
|
||||||
from langchain_core.tools import tool
|
from langchain_core.tools import tool
|
||||||
|
|
||||||
|
from app.model.ProjectModel import ProjectService, ProjectModel
|
||||||
|
from app.model.ReimburseModel import ReimburseService, ReimburseModel
|
||||||
|
from app.model.ReimburseOtherModel import ReimburseOtherModel
|
||||||
|
from app.model.ReimburseTravelModel import ReimburseTravelModel
|
||||||
|
from app.utils.PageQueryParams import PageQueryParams
|
||||||
|
from app.utils.db_utils import async_session
|
||||||
|
|
||||||
|
|
||||||
@tool(
|
@tool(
|
||||||
name_or_callable="tool_project_analysis",
|
name_or_callable="tool_project_analysis",
|
||||||
description="做项目成本分析报告"
|
description="做项目成本分析报告"
|
||||||
)
|
)
|
||||||
def tool_project_analysis() -> float:
|
async def tool_project_analysis(project_name: Annotated[str, "项目名称"]) -> float:
|
||||||
return [
|
async with async_session() as session:
|
||||||
"",
|
project_cls: ProjectModel = await ProjectService.query_item(
|
||||||
{
|
session=session,
|
||||||
"component": "DirectSubordinates",
|
row_dict={"name": project_name}
|
||||||
"props": {},
|
)
|
||||||
|
if not project_cls:
|
||||||
|
return f"找不到名为「{project_name}」的项目"
|
||||||
|
|
||||||
|
query_cls_list, has_next, total = await ReimburseService.query_list(session=session, query_param=PageQueryParams(all=True, filters={"proj_id": project_cls.id}))
|
||||||
|
|
||||||
|
reimburse_list: List[ReimburseModel] = [item for item in query_cls_list if item.approve is not None and item.approve.status == 'approved']
|
||||||
|
|
||||||
|
member_amount = {} # 人员成本分析
|
||||||
|
member_cost_description_list = {} # 人员费用描述
|
||||||
|
|
||||||
|
reimburse_travel_list: List[ReimburseTravelModel] = []
|
||||||
|
reimburse_other_list: List[ReimburseOtherModel] = []
|
||||||
|
|
||||||
|
for reimburse_cls in reimburse_list:
|
||||||
|
reimburse_travel_list.extend(reimburse_cls.travel_list)
|
||||||
|
reimburse_other_list.extend(reimburse_cls.other_list)
|
||||||
|
|
||||||
|
if not member_amount.get(reimburse_cls.user.full_name, None):
|
||||||
|
member_amount[reimburse_cls.user.full_name] = Decimal(0)
|
||||||
|
if not member_cost_description_list.get(reimburse_cls.user.full_name, None):
|
||||||
|
member_cost_description_list[reimburse_cls.user.full_name] = []
|
||||||
|
|
||||||
|
member_amount[reimburse_cls.user.full_name] += reimburse_cls.amount
|
||||||
|
for item in reimburse_cls.travel_list:
|
||||||
|
member_cost_description_list[reimburse_cls.user.full_name].append(f"""
|
||||||
|
费用描述:{item.title},差旅费用——{item.type},{item.amount}元,{item.depart_time}——{item.arrive_time},{item.depart_city}——{item.arrive_city}
|
||||||
|
""")
|
||||||
|
for item in reimburse_cls.other_list:
|
||||||
|
member_cost_description_list[reimburse_cls.user.full_name].append(f"""
|
||||||
|
费用描述:{item.title},其他费用——{item.type},{item.amount}元
|
||||||
|
""")
|
||||||
|
|
||||||
|
cost_amount = {} # 费用类型成本分析
|
||||||
|
|
||||||
|
for item in reimburse_travel_list:
|
||||||
|
if not cost_amount.get(item.type, None):
|
||||||
|
cost_amount[item.type] = Decimal(0)
|
||||||
|
cost_amount[item.type] += item.amount
|
||||||
|
|
||||||
|
for item in reimburse_other_list:
|
||||||
|
if not cost_amount.get(item.type, None):
|
||||||
|
cost_amount[item.type] = Decimal(0)
|
||||||
|
cost_amount[item.type] += item.amount
|
||||||
|
|
||||||
|
member_description = '\n'.join([f"{user_full_name}:{user_spent}" for user_full_name, user_spent in member_amount.items()])
|
||||||
|
cost_description = '\n'.join([f"{cost_type}:{cost_amount}" for cost_type, cost_amount in cost_amount.items()])
|
||||||
|
member_cost_description = '\n'.join([f"{user_full_name}产生的费用:{''.join(user_cost_description)}" for user_full_name, user_cost_description in member_cost_description_list.items()])
|
||||||
|
|
||||||
|
description = f"""
|
||||||
|
项目预算:{project_cls.budget}
|
||||||
|
项目花费金额:{project_cls.spent}
|
||||||
|
项目预算余额:{project_cls.balance}
|
||||||
|
|
||||||
|
项目成员成本分析:
|
||||||
|
{member_description}
|
||||||
|
|
||||||
|
费用类型成本分析:
|
||||||
|
{cost_description}
|
||||||
|
|
||||||
|
人员费用清单:
|
||||||
|
|
||||||
|
{member_cost_description}
|
||||||
|
"""
|
||||||
|
|
||||||
|
return {
|
||||||
|
"member_amount": member_amount,
|
||||||
|
"cost_amount": cost_amount,
|
||||||
|
"description": description,
|
||||||
}
|
}
|
||||||
]
|
|
||||||
|
|||||||
Reference in New Issue
Block a user