Merge pull request !8938 from 李鹏宇/dev
This commit is contained in:
@@ -42,6 +42,7 @@
|
||||
'views/monthly_maintenance_fee_report.xml',
|
||||
'views/yuthon_report_res_partner.xml',
|
||||
'views/att_report_view.xml',
|
||||
'views/staff_position_report.xml',
|
||||
],
|
||||
'installable': True,
|
||||
'application': True,
|
||||
|
||||
@@ -31,4 +31,5 @@ from . import monthly_expense_total_report
|
||||
from . import monthly_assessment_fee_report
|
||||
from . import monthly_other_expense_report
|
||||
from . import monthly_maintenance_fee_report
|
||||
from . import att_report
|
||||
from . import att_report
|
||||
from . import staff_position_report
|
||||
@@ -26,9 +26,7 @@ class CumulativeArrearsReport(models.Model):
|
||||
|
||||
date_start = params.get("date_start")
|
||||
date_end = params.get("date_end")
|
||||
if date_start:
|
||||
start_dt = datetime.datetime.fromisoformat(date_start).date()
|
||||
domain.append(("due_date", ">=", start_dt))
|
||||
# 累计欠收:只限定截止日期,包含截止日之前所有欠收
|
||||
if date_end:
|
||||
end_dt = datetime.datetime.fromisoformat(date_end).date()
|
||||
domain.append(("due_date", "<=", end_dt))
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
from odoo import api, models
|
||||
from datetime import datetime
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
|
||||
class StaffPositionReport(models.Model):
|
||||
_inherit = "hr.job"
|
||||
|
||||
@api.model
|
||||
def get_staff_position_report(self, params):
|
||||
"""人员岗位报表
|
||||
|
||||
返回当前有效岗位的编制、在岗、缺编等信息。
|
||||
"""
|
||||
domain = [
|
||||
("is_enable", "=", True),
|
||||
("establishment_quotas", ">", 0),
|
||||
]
|
||||
|
||||
company_id = params.get("company_id")
|
||||
department_id = params.get("department_id")
|
||||
keyword = params.get("keyword")
|
||||
|
||||
if company_id:
|
||||
domain.append(("company_id", "=", company_id))
|
||||
if department_id:
|
||||
domain.append(("department_id", "=", department_id))
|
||||
if keyword:
|
||||
domain += [
|
||||
"|",
|
||||
("name", "ilike", keyword),
|
||||
("department_id.name", "ilike", keyword),
|
||||
]
|
||||
|
||||
jobs = self.search(domain, order="department_id, name")
|
||||
|
||||
# 计算上月最后一天 23:59:59
|
||||
today = datetime.now().date()
|
||||
first_day_of_this_month = today.replace(day=1)
|
||||
last_day_of_last_month = first_day_of_this_month - relativedelta(days=1)
|
||||
last_moment_of_last_month = datetime.combine(last_day_of_last_month, datetime.max.time())
|
||||
|
||||
# selection 字段映射成中文
|
||||
compiling_status_field = self._fields.get("compiling_status")
|
||||
status_selection = dict(compiling_status_field.selection) if compiling_status_field else {}
|
||||
|
||||
rows = []
|
||||
for job in jobs:
|
||||
# 统计上月人数:上月最后一天 + active=True + 合同有效
|
||||
last_month_count = self.env['hr.employee'].search_count([
|
||||
('job_id', '=', job.id),
|
||||
('active', '=', True),
|
||||
('contract_id.date_start', '<=', last_day_of_last_month),
|
||||
'|',
|
||||
('contract_id.date_end', '>=', last_day_of_last_month),
|
||||
('contract_id.date_end', '=', False),
|
||||
])
|
||||
|
||||
# 当前在岗人数
|
||||
current_count = job.no_of_employee or 0
|
||||
|
||||
# 变动情况
|
||||
change = current_count - last_month_count
|
||||
if change > 0:
|
||||
change_text = f"新增 {change} 人"
|
||||
elif change < 0:
|
||||
change_text = f"减少 {abs(change)} 人"
|
||||
else:
|
||||
change_text = ""
|
||||
|
||||
rows.append({
|
||||
"部门": job.department_id.name if job.department_id else "",
|
||||
"岗位": job.name or "",
|
||||
"编制数": job.establishment_quotas or 0,
|
||||
"在岗人数": current_count,
|
||||
"上月人数": last_month_count,
|
||||
"变动情况": change_text,
|
||||
"缺岗人数": job.missing_number or 0,
|
||||
"编制外人数": job.compiling_external or 0,
|
||||
"状态": status_selection.get(job.compiling_status, "") if job.compiling_status else "",
|
||||
"在岗人员": job.job_personnel or "",
|
||||
"公司": job.company_id.name if job.company_id else "",
|
||||
})
|
||||
|
||||
return rows
|
||||
@@ -43,7 +43,30 @@ class ReceivableReport extends Component {
|
||||
theme: agGrid.themeMaterial,
|
||||
columnDefs: this.config.columns || [],
|
||||
rowData: [],
|
||||
sideBar: true,
|
||||
sideBar: {
|
||||
toolPanels: [
|
||||
{
|
||||
id: 'columns',
|
||||
labelDefault: '列',
|
||||
labelKey: 'columns',
|
||||
iconKey: 'columns',
|
||||
toolPanel: 'agColumnsToolPanel',
|
||||
toolPanelParams: {
|
||||
suppressValues: true,
|
||||
suppressPivots: true,
|
||||
suppressPivotMode: true,
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'filters',
|
||||
labelDefault: '过滤器',
|
||||
labelKey: 'filters',
|
||||
iconKey: 'filter',
|
||||
toolPanel: 'agFiltersToolPanel'
|
||||
}
|
||||
],
|
||||
defaultToolPanel: '',
|
||||
},
|
||||
enableCharts: true,
|
||||
cellSelection: true,
|
||||
defaultColDef: {
|
||||
@@ -141,14 +164,20 @@ class ReceivableReport extends Component {
|
||||
async onUpdateCompany(v) {
|
||||
this.state.selectCompany = v[0] || {}
|
||||
await this.searchDomain()
|
||||
// 自动搜索
|
||||
await this.onSearch()
|
||||
}
|
||||
|
||||
async onUpdateStructure(v) {
|
||||
this.state.selectStructure = v[0] || {}
|
||||
// 自动搜索
|
||||
await this.onSearch()
|
||||
}
|
||||
|
||||
async onUpdateDepartment(v) {
|
||||
this.state.selectDepartment = v[0]
|
||||
// 自动搜索
|
||||
await this.onSearch()
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -12,71 +12,71 @@
|
||||
|
||||
<!-- 筛选卡片 -->
|
||||
<div class="card mb-2">
|
||||
<div class="card-body">
|
||||
<div class="card-body py-2">
|
||||
<!-- 搜索区域 -->
|
||||
<div class="row mb-2" t-ref="search_area">
|
||||
|
||||
<!-- 应收日期范围 -->
|
||||
<div class="row align-items-end" t-ref="search_area">
|
||||
<!-- 日期范围 -->
|
||||
<div class="col-3">
|
||||
<label>日期范围</label>
|
||||
<label class="mb-1">日期范围</label>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<DateTimeInput
|
||||
range="true"
|
||||
range="true"
|
||||
value="state.startDate"
|
||||
type="'date'"
|
||||
placeholder="fromPlaceholder"
|
||||
onChange="(date) => this.onChangeStartDate(date)"
|
||||
/>
|
||||
<i class="oi oi-arrow-right"></i>
|
||||
<DateTimeInput
|
||||
range="true"
|
||||
range="true"
|
||||
value="state.endDate"
|
||||
type="'date'"
|
||||
placeholder="toPlaceholder"
|
||||
onChange="(date) => this.onChangeEndDate(date)"
|
||||
/>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 所属公司 -->
|
||||
<div class="col-3">
|
||||
<label>所属公司</label>
|
||||
<div class="col">
|
||||
<Many2XAutocomplete
|
||||
value="state.selectCompany?.display_name"
|
||||
getDomain="getDomainCompany"
|
||||
resModel="'res.company'"
|
||||
fieldString="'所属公司'"
|
||||
placeholder="'所属公司'"
|
||||
activeActions="{}"
|
||||
update.bind="onUpdateCompany"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<label>部门</label>
|
||||
|
||||
<!-- 部门 -->
|
||||
<div class="col">
|
||||
<Many2XAutocomplete
|
||||
value="state.selectDepartment?.display_name"
|
||||
getDomain.bind="getDomainDepartment"
|
||||
resModel="'hr.department'"
|
||||
fieldString="'部门'"
|
||||
placeholder="'部门'"
|
||||
activeActions="{}"
|
||||
update.bind="onUpdateDepartment"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<label>薪资分组</label>
|
||||
|
||||
<!-- 薪资分组 -->
|
||||
<div class="col">
|
||||
<Many2XAutocomplete
|
||||
value="state.selectStructure?.display_name"
|
||||
getDomain.bind="getDomainStructure"
|
||||
resModel="'yuthon.salary.group'"
|
||||
fieldString="'薪资分组'"
|
||||
placeholder="'薪资分组'"
|
||||
activeActions="{}"
|
||||
update.bind="onUpdateStructure"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="col-12 mt-3 d-flex justify-content-end gap-2">
|
||||
<button class="btn btn-primary" t-on-click="onSearch">搜索</button>
|
||||
<div class="col-auto">
|
||||
<button class="btn btn-success" t-on-click="onExportExcel">导出</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="action_staff_position_report" model="ir.actions.client">
|
||||
<field name="name">人员岗位报表</field>
|
||||
<field name="tag">att_report_client</field>
|
||||
<field name="context">
|
||||
{
|
||||
"report_config": {
|
||||
"model": "hr.job",
|
||||
"method": "get_staff_position_report",
|
||||
"columns": [
|
||||
{"headerName": "部门", "field": "部门", "flex": 1.5},
|
||||
{"headerName": "岗位", "field": "岗位", "flex": 1.5},
|
||||
{"headerName": "编制数", "field": "编制数", "flex": 0.8, "type": "number"},
|
||||
{"headerName": "在岗人数", "field": "在岗人数", "flex": 0.8, "type": "number"},
|
||||
{"headerName": "上月人数", "field": "上月人数", "flex": 0.8, "type": "number"},
|
||||
{"headerName": "变动情况", "field": "变动情况", "flex": 1},
|
||||
{"headerName": "缺岗人数", "field": "缺岗人数", "flex": 0.8, "type": "number"},
|
||||
{"headerName": "编制外人数", "field": "编制外人数", "flex": 0.8, "type": "number"},
|
||||
{"headerName": "状态", "field": "状态", "flex": 0.8},
|
||||
{"headerName": "在岗人员", "field": "在岗人员", "flex": 2},
|
||||
{"headerName": "公司", "field": "公司", "flex": 1}
|
||||
]
|
||||
}
|
||||
}
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
id="menu_staff_position_report"
|
||||
name="人员岗位报表"
|
||||
parent="yuthon_property_approval.property_approval_report_menu"
|
||||
action="action_staff_position_report"
|
||||
sequence="36"
|
||||
/>
|
||||
</data>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user