实习生增员申请表

This commit is contained in:
李鹏宇
2026-09-07 15:09:56 +08:00
parent e18ad27430
commit ba78bb040b
12 changed files with 381 additions and 8 deletions
+54 -2
View File
@@ -106,7 +106,7 @@ class RestaurantController(Controller):
def get_catering(self, **kwargs):
user_id = int(kwargs.get('user_id'))
menu_date = kwargs.get('menu_date', date.today())
menu_id = int(kwargs.get('menu_id'))
menu_id = kwargs.get('menu_id')
if not user_id or not menu_date or not menu_id:
return json.dumps({'data': '', 'code': 500, 'message': '请求失败'})
@@ -124,11 +124,63 @@ class RestaurantController(Controller):
'menu_id': catering.menu_day_id.id,
'breakfast': catering.breakfast,
'lunch': catering.lunch,
'state': catering.state
'state': catering.state,
'is_expatriate': False,
}
return json.dumps({'data': catering_data, 'code': 200, 'message': ''})
# 没有用餐记录时,判断当前员工是否处于外派期间;
# 若处于外派期间,默认早餐和午餐均为不就餐(False)。
is_expatriate = self._check_expatriation(employee, menu_date)
if is_expatriate:
catering_data = {
'id': 0,
'user_id': employee.user_id.id,
'menu_id': int(menu_id),
'breakfast': False,
'lunch': False,
'state': 'unconfirmed',
'is_expatriate': True,
}
return json.dumps({'data': catering_data, 'code': 200, 'message': ''})
return json.dumps({'data': '', 'code': 200, 'message': '没有查询到数据'})
def _check_expatriation(self, employee, menu_date):
"""判断员工在指定日期是否处于外派期间。
规则:
1. 存在审批结束且未作废、未失效、未结束的外派审批记录,员工在 expatriates_ids 中;
2. 外派开始日期 <= 当前日期;
3. 已填写返回日期时,当前日期 <= 返回日期;
4. 未填写返回日期时,从外派开始日期起即视为外派中。
"""
if not employee:
return False
WorkflowRecord = request.env['soong.workflow.record'].sudo()
# 先找出审批结束且未作废的外派审批单 ID
workflow_records = WorkflowRecord.search([
('res_model', '=', 'expatriation.approval'),
('approve_state', '=', 'end'),
('reclaim_state', '=', False),
])
expatriation_ids = workflow_records.mapped('res_id')
if not expatriation_ids:
return False
Expatriation = request.env['expatriation.approval'].sudo()
domain = [
('id', 'in', expatriation_ids),
('expatriates_ids', 'in', [employee.id]),
('start_date', '!=', False),
('start_date', '<=', menu_date),
('is_effect', '=', False),
('work_end', '=', False),
'|',
('return_date', '=', False),
('return_date', '>=', menu_date),
]
return bool(Expatriation.search(domain, limit=1))
@route('/phone/restaurant/get_catering_statistics', methods=['POST'], type='http', auth="none", csrf=False, cors='*')
@exception_handle
def get_catering_statistics(self, **kwargs):
@@ -82,7 +82,7 @@
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//field[@name='department_id']" position="after">
<!-- <field name="allowed_user_ids" invisible="1"/>-->
<field name="allowed_user_ids" invisible="1"/>
<field name="number"/>
<field name="establishment_quotas"/>
<field name="no_of_employee" string="在编人数"/>
@@ -50,6 +50,7 @@
'views/yuthon_appointment_approval_views.xml',
'views/yuthon_transfer_approval_views.xml',
'views/yuthon_social_files_approval_view.xml',
'views/yuthon_intern_increment_views.xml',
'views/website_employee_views.xml',
'views/menuitem.xml',
@@ -63,6 +64,8 @@
'report/renewal_approval_template.xml',
'report/service_approval_report.xml',
'report/service_approval_report_templates.xml',
'report/yuthon_intern_increment_report.xml',
'report/yuthon_intern_increment_report_templates.xml',
'wizard/yuthon_website_employee_wizard.xml',
'wizard/interview_approval_wizard.xml',
@@ -168,4 +168,11 @@
<field name="padding">3</field>
<field name="company_id" eval="False"/>
</record>
<record id="yuthon_intern_increment_code" model="ir.sequence">
<field name="name">实习生增员申请表-编号</field>
<field name="code">yuthon_intern_increment_code</field>
<field name="prefix">SX%(y)s%(month)s%(day)s</field>
<field name="padding">3</field>
<field name="company_id" eval="False"/>
</record>
</odoo>
@@ -29,3 +29,4 @@ from . import contract_review_approval
from . import yuthon_employee_add
from . import yuthon_pre_examination
from . import yuthon_employee_setting
from . import yuthon_intern_increment
@@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
# 实习生增员申请表模型
from odoo import models, fields, api
class YuthonInternIncrement(models.Model):
_name = 'yuthon.intern.increment'
_description = '实习生增员申请表'
_inherit = ['soong.workflow.mixin', 'mail.thread.main.attachment', 'mail.activity.mixin']
code = fields.Char(string='编号',
default=lambda self: self.env['ir.sequence'].next_by_code('yuthon_intern_increment_code'))
name = fields.Char(string='标题')
users_id = fields.Many2one('res.users', string='申请人', default=lambda self: self.env.user.id)
department_id = fields.Many2one(related='users_id.employee_id.department_id', string='申请部门')
company_id = fields.Many2one(related='users_id.employee_id.company_id', string='公司')
application_date = fields.Date(string='申请日期', default=fields.Date.today)
intern_position = fields.Char(string='实习岗位')
current_staff_count = fields.Integer(string='部门现有人数')
increment_count = fields.Integer(string='拟增员人数')
planned_report_date = fields.Date(string='计划报到日期')
increment_reason = fields.Text(string='增员理由')
job_content = fields.Text(string='工作内容(主要职责)')
qualifications = fields.Text(string='任职资格(学历、专业、资质及相关要求)')
dept_manager_opinion = fields.Text(string='申请部门经理意见')
hr_opinion = fields.Text(string='综合办公室意见')
management_opinion = fields.Text(string='经营班子审批意见')
documents_ids = fields.Many2many('ir.attachment', string='附件')
work_end = fields.Boolean(string='结束')
active = fields.Boolean('Active', default=True, tracking=True)
urgency_level = fields.Selection([('normal', '普件'), ('urgent', '急件'), ('emergency', '特急件')],
string='紧急度', default='normal')
def _get_default_name_title(self):
return self._description if self._description else self._name
name_title = fields.Char(default=_get_default_name_title)
self_users_ids = fields.Many2many('res.users', string='当前经办人',
default=lambda self: [(6, 0, [self.env.user.id])])
def action_print_intern_increment(self):
"""打印实习生增员申请表"""
self.ensure_one()
report_ref = self.env.ref('yuthon_hr_employee_approval.action_intern_increment_report')
return report_ref.report_action(self.id)
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 实习生增员申请表打印报表动作定义 -->
<odoo>
<data>
<!-- 复用汇审意见表的纸张格式 -->
<record id="action_intern_increment_report" model="ir.actions.report">
<field name="name">实习生增员申请表</field>
<field name="paperformat_id" ref="yuthon_hr_employee_approval.paperformat_hr_employee_approval_small"/>
<field name="model">yuthon.intern.increment</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">yuthon_hr_employee_approval.intern_increment_report_document</field>
<field name="report_file">yuthon_hr_employee_approval.intern_increment_report_document</field>
<!-- 绑定到模型,自动出现在打印下拉菜单 -->
<field name="binding_model_id" ref="model_yuthon_intern_increment"/>
<field name="binding_type">report</field>
<!-- PDF文件名:实习生增员申请表_标题_申请人_归档日期 -->
<field name="print_report_name">'实习生增员申请表_%s_%s_%s' % (object.name or '', object.users_id.name or '', ((object.log_ids.filtered(lambda l: l.name == '归档')[-1].lase_click_date or object.log_ids.filtered(lambda l: l.name == '归档')[-1].date_create).strftime('%Y-%m-%d') if object.log_ids.filtered(lambda l: l.name == '归档') else ''))</field>
</record>
</data>
</odoo>
@@ -0,0 +1,140 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 实习生增员申请表打印模板 -->
<odoo>
<data>
<template id="intern_increment_report_document">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="doc">
<t t-call="web.external_layout">
<style type="text/css">
/* 表格纵向版式:自适应,最大800px 居中 */
table { border-collapse: collapse; width: 100%; max-width: 800px; margin: 0 auto; table-layout: fixed; }
td { border: 1px solid #000; padding: 6px; text-align: center; vertical-align: middle; }
.title {
text-align: center;
font-weight: bold;
font-size: 18px;
padding: 8px 0;
}
.header-cell { font-weight: bold; background-color: #d4e6f1;}
.label-cell { font-weight: bold; background-color: #d4e6f1; text-align: center; }
.content-cell { text-align: left; vertical-align: top; }
.tall-cell { height: 100px; }
.signature-row { text-align: right; vertical-align: bottom; padding-top: 60px; }
/* 隐藏意见和审批人之间的竖边框 */
.no-right-border { border-right: none !important; }
.no-left-border { border-left: none !important; }
</style>
<!-- 实习生增员申请表标题 -->
<div class="title" style="text-align:center; font-weight:bold; font-size:18px; padding:12px 0; margin-bottom:10px;">
实习生增员申请表
</div>
<!-- 申请部门/流水号行 -->
<div style="margin-bottom:8px; text-align:left;">
申请部门:<span t-esc="doc.department_id.name or ''"/>
<span style="margin-left:40px;">流水号:<span t-esc="doc.code or ''"/></span>
</div>
<table>
<colgroup>
<col style="width:10%"/>
<col style="width:23%"/>
<col style="width:10%"/>
<col style="width:23%"/>
<col style="width:10%"/>
<col style="width:24%"/>
</colgroup>
<!-- 申请部门 / 申请日期 / 实习岗位 -->
<tr>
<td class="label-cell"><strong>申请部门</strong></td>
<td><span t-esc="doc.department_id.name or ''"/></td>
<td class="label-cell"><strong>申请日期</strong></td>
<td><span t-esc="doc.application_date and doc.application_date.strftime('%Y-%m-%d') or ''"/></td>
<td class="label-cell"><strong>实习岗位</strong></td>
<td><span t-esc="doc.intern_position or ''"/></td>
</tr>
<!-- 部门现有人数 / 拟增员人数 / 计划报到日期 -->
<tr>
<td class="label-cell"><strong>部门现有人数</strong></td>
<td><span t-esc="doc.current_staff_count or 0"/></td>
<td class="label-cell"><strong>拟增员人数</strong></td>
<td><span t-esc="doc.increment_count or 0"/></td>
<td class="label-cell"><strong>计划报到日期</strong></td>
<td><span t-esc="doc.planned_report_date and doc.planned_report_date.strftime('%Y-%m-%d') or ''"/></td>
</tr>
<!-- 增员理由 -->
<tr>
<td class="label-cell tall-cell"><strong>增员理由</strong></td>
<td class="content-cell tall-cell" colspan="5"><span t-esc="doc.increment_reason or ''"/></td>
</tr>
<!-- 工作内容(主要职责) -->
<tr>
<td class="label-cell tall-cell"><strong>工作内容<br/>(主要职责)</strong></td>
<td class="content-cell tall-cell" colspan="5"><span t-esc="doc.job_content or ''"/></td>
</tr>
<!-- 任职资格 -->
<tr>
<td class="label-cell tall-cell"><strong>任职资格<br/>(学历、专业、资质<br/>及相关要求)</strong></td>
<td class="content-cell tall-cell" colspan="5"><span t-esc="doc.qualifications or ''"/></td>
</tr>
<!-- 申请部门经理意见 -->
<tr>
<td class="label-cell tall-cell"><strong>申请部门经理意见</strong></td>
<td class="content-cell tall-cell" colspan="5">
<div><span t-esc="doc.dept_manager_opinion or ''"/></div>
<div class="signature-row">签名:________________&#160;&#160;&#160;&#160;日期:________________</div>
</td>
</tr>
<!-- 综合办公室意见 -->
<tr>
<td class="label-cell tall-cell"><strong>综合办公室意见</strong></td>
<td class="content-cell tall-cell" colspan="5">
<div><span t-esc="doc.hr_opinion or ''"/></div>
<div class="signature-row">签名:________________&#160;&#160;&#160;&#160;日期:________________</div>
</td>
</tr>
<!-- 经营班子审批意见 -->
<tr>
<td class="label-cell tall-cell"><strong>经营班子审批意见</strong></td>
<td class="content-cell tall-cell" colspan="5">
<div><span t-esc="doc.management_opinion or ''"/></div>
<div class="signature-row">签名:________________&#160;&#160;&#160;&#160;日期:________________</div>
</td>
</tr>
<!-- 附件清单 -->
<tr>
<td class="label-cell"><strong>附件清单</strong></td>
<td class="content-cell" colspan="5" style="text-align:left;">
<t t-foreach="doc.documents_ids" t-as="att">
<div><t t-esc="att.name"/></div>
</t>
</td>
</tr>
<!-- 审批详情标题行 -->
<tr>
<td colspan="6" style="background-color: #d4e6f1; text-align: center;"><strong>审批详情</strong></td>
</tr>
<!-- 审批日志遍历(与汇审意见表完全一致) -->
<t t-set="logs_ordered" t-value="doc.get_logs_for_print()"/>
<t t-foreach="logs_ordered" t-as="log">
<tr>
<td colspan="1"><span t-esc="log.name"/></td>
<!-- 隐藏意见列右侧边框 -->
<td class="no-right-border" colspan="4"><span t-esc="log.comment"/></td>
<!-- 隐藏审批人列左侧边框 -->
<td class="no-left-border" colspan="1">
<t t-if="log.done_by">
<span t-esc="log.done_by.name"/> <span t-esc="log.lase_click_date and log.lase_click_date.strftime('%Y-%m-%d')"/>
</t>
</td>
</tr>
</t>
</table>
</t>
</t>
</t>
</template>
</data>
</odoo>
@@ -56,6 +56,7 @@ access_contract_review_approval,contract_review_approval,model_contract_review_a
access_awards_line, awards_line,model_awards_line,base.group_user,1,1,1,1
access_yuthon_employee_add,yuthon_employee_add,model_yuthon_employee_add,base.group_user,1,1,1,1
access_yuthon_pre_examination,yuthon_pre_examination,model_yuthon_pre_examination,base.group_user,1,1,1,1
access_yuthon_intern_increment,yuthon_intern_increment,model_yuthon_intern_increment,base.group_user,1,1,1,1
access_yuthon_service_type,yuthon_service_type,model_yuthon_service_type,base.group_user,1,1,1,1
access_yuthon_contract_type,yuthon_contract_type,model_yuthon_contract_type,base.group_user,1,1,1,1
access_leaving_salary_line,leaving_salary_line,model_leaving_salary_line,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
56 access_awards_line awards_line model_awards_line base.group_user 1 1 1 1
57 access_yuthon_employee_add yuthon_employee_add model_yuthon_employee_add base.group_user 1 1 1 1
58 access_yuthon_pre_examination yuthon_pre_examination model_yuthon_pre_examination base.group_user 1 1 1 1
59 access_yuthon_intern_increment yuthon_intern_increment model_yuthon_intern_increment base.group_user 1 1 1 1
60 access_yuthon_service_type yuthon_service_type model_yuthon_service_type base.group_user 1 1 1 1
61 access_yuthon_contract_type yuthon_contract_type model_yuthon_contract_type base.group_user 1 1 1 1
62 access_leaving_salary_line leaving_salary_line model_leaving_salary_line base.group_user 1 1 1 1
@@ -8,10 +8,10 @@
parent="hr_recruitment.menu_hr_recruitment_root"
sequence="7"/>
<menuitem id="hr_menu_recruitment_approval"
name="招聘需求申请表"
parent="hr_process_work_job"
action="yuthon_recruitment_approval_action"
sequence="1"/>
name="招聘需求申请表"
parent="hr_process_work_job"
action="yuthon_recruitment_approval_action"
sequence="1"/>
<menuitem id="hr_menu_message_login"
name="个人信息登记表"
parent="hr_process_work_job"
@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="view_yuthon_intern_increment_tree" model="ir.ui.view">
<field name="name">yuthon.intern.increment.tree</field>
<field name="model">yuthon.intern.increment</field>
<field name="arch" type="xml">
<tree>
<field name="code"/>
<field name="name"/>
<field name="users_id" options="{'no_create': True}"/>
<field name="department_id"/>
<field name="application_date"/>
<field name="intern_position"/>
<field name="increment_count"/>
<field name="planned_report_date"/>
</tree>
</field>
</record>
<record id="view_yuthon_intern_increment_form" model="ir.ui.view">
<field name="name">yuthon.intern.increment.form</field>
<field name="model">yuthon.intern.increment</field>
<field name="arch" type="xml">
<form create="0">
<header>
<!-- 打印按钮:流程结束后显示 -->
<button name="action_print_intern_increment"
type="object"
string="打印"
class="btn-primary" invisible="not work_end"/>
</header>
<sheet>
<group col="4">
<group>
<field name="code" string="流水号" readonly="1"/>
</group>
<group>
<field name="urgency_level" readonly="1"/>
</group>
<group/>
<group/>
</group>
<div class="col-12 text-center">
<h1>
<field name="name_title" readonly="1"/>
</h1>
</div>
<group string="申请信息">
<group>
<field name="name" required="1"/>
<field name="users_id" options="{'no_create': True}"/>
<field name="department_id" options='{"no_create": True}'/>
<field name="application_date"/>
<field name="intern_position"/>
</group>
<group>
<field name="current_staff_count"/>
<field name="increment_count"/>
<field name="planned_report_date"/>
<field name="work_end" invisible="1"/>
<field name="company_id" invisible="1"/>
</group>
</group>
<group string="增员信息">
<group>
<field name="increment_reason"/>
</group>
<group>
<field name="job_content"/>
</group>
<group>
<field name="qualifications"/>
</group>
</group>
<group string="审批意见">
<group>
<field name="dept_manager_opinion"/>
</group>
<group>
<field name="hr_opinion"/>
</group>
<group>
<field name="management_opinion"/>
</group>
</group>
<group>
<field name="documents_ids" widget="preview_many2many"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="yuthon_intern_increment_action" model="ir.actions.act_window">
<field name="name">实习生增员申请表</field>
<field name="res_model">yuthon.intern.increment</field>
<field name="view_mode">tree,form</field>
</record>
</odoo>
+5
View File
@@ -65,6 +65,11 @@
parent="hr_menu_recruitment_process"
action="yuthon_hr_employee_approval.yuthon_recruitment_approval_action"
sequence="1"/>
<menuitem id="hr_menu_intern_increment_root_board"
name="实习生增员申请表"
parent="hr_menu_recruitment_process"
action="yuthon_hr_employee_approval.yuthon_intern_increment_action"
sequence="3"/>
<menuitem id="hr_menu_interview_approval_root_board"
name="面试信息表"
parent="hr_menu_recruitment_process"