This commit is contained in:
李鹏宇
2026-04-20 17:09:00 +08:00
18 changed files with 59 additions and 45 deletions
@@ -1437,7 +1437,10 @@ class SoongWorkflowMixin(models.AbstractModel):
id_el = etree.Element("field")
id_el.set("name", "log_ids")
id_el.set("invisible", "1")
if readonly_arr:
if self._name == "purchase.order":
# 采购订单模型:不添加 is_modify 条件 因为
field_inst.set("readonly", "state in %s" % readonly_arr)
else:
field_inst.set("readonly", "(state in %s) and (is_modify != True)" % readonly_arr)
# if required_arr:
# field_inst.set("required", "state in %s" % required_arr)
+1 -2
View File
@@ -7,6 +7,7 @@ class YuthonCatering(models.Model):
_name = 'yuthon.catering'
date = fields.Date(string='日期', required=True)
employee_number = fields.Char(string='序号', related='employee_id.user_number', store=True)
week_day = fields.Char(string='星期', compute='_compute_week_day', store=True)
dept_id = fields.Many2one(string='部门', comodel_name='hr.department', related='employee_id.department_id', store=True)
employee_id = fields.Many2one(string='员工', comodel_name='hr.employee', required=True)
@@ -447,14 +448,12 @@ class YuthonCatering(models.Model):
conf = self.env['yuthon.catering.conf'].search([], limit=1)
if not conf or not conf.employee_ids:
return
employee_ids = conf.employee_ids
target_months = [
(2025, 12),
(2026, 1),
(2026, 2),
]
all_dates = []
for y, m in target_months:
d = date_cls(y, m, 1)
+2 -1
View File
@@ -6,7 +6,7 @@
<field name="name">yuthon.catering.tree</field>
<field name="model">yuthon.catering</field>
<field name="arch" type="xml">
<tree string="餐饮" editable="top" default_order="entry_date asc">
<tree string="餐饮" editable="top" default_order="employee_number asc">
<header>
<button name="batch_remind_catering" string="批量提醒" type="object" class="btn btn-primary"/>
<button name="cron_fill_today_missing" string="补全并确认今日数据" type="object" class="btn btn-primary"/>
@@ -14,6 +14,7 @@
</header>
<field name="date"/>
<field name="week_day" readonly="1"/>
<field name="employee_number" column_invisible="1"/
<field name="breakfast"/>
<field name="lunch"/>
<field name="amount" readonly="1"/>
@@ -18,6 +18,7 @@ class HrLeave(models.Model):
_inherit = 'hr.leave'
number_of_days = fields.Float(string='天数', digits=(16, 3))
def _check_validity(self):
sorted_leaves = defaultdict(lambda: self.env['hr.leave'])
for leave in self:
@@ -13,6 +13,7 @@ class InheritHrLeave(models.Model):
_description = '请假情况'
caption = fields.Char(string="标题", compute="_compute_application_reason")
employee_number = fields.Char(string='序号', related='employee_id.user_number', store=True)
employee_id = fields.Many2one('hr.employee', string="发起人")
mobile_phone = fields.Char(related='employee_id.mobile_phone', string="手机号")
entry_date = fields.Date(related='employee_id.entry_date', string="入职时间", store=True)
@@ -10,6 +10,7 @@ class YuthonMealLine(models.Model):
_description = '误餐明细'
employee_id = fields.Many2one('hr.employee', string="员工")
employee_number = fields.Char(string='序号', related='employee_id.user_number', store=True)
meal_name = fields.Char(string='标题')
meal_id = fields.Many2one('vacation.meal.line', string="关联误餐额度记录")
entry_date = fields.Date(related='employee_id.entry_date', string="入职时间", store=True)
@@ -11,6 +11,7 @@ class YuthonOvertimeLine(models.Model):
employee_id = fields.Many2one('hr.employee', string="员工")
entry_date = fields.Date(related='employee_id.entry_date', string="入职时间", store=True)
employee_number = fields.Char(string='序号', related='employee_id.user_number', store=True)
select_month = fields.Selection([('1', '一月'), ('2', '二月'), ('3', '三月'), ('4', '四月'),
('5', '五月'), ('6', '六月'), ('7', '七月'), ('8', '八月'),
('9', '九月'), ('10', '十月'), ('11', '十一月'),
@@ -21,6 +21,7 @@ class YuthonVacationReports(models.Model):
month_id = fields.Many2one('base.month', string='月份', compute="_compute_display_date", store=True)
year_id = fields.Many2one('base.year', string='年份', compute="_compute_display_date", store=True)
employee_id = fields.Many2one('hr.employee', string='员工')
employee_number = fields.Char(string='序号', related='employee_id.user_number', store=True, readonly=True)
entry_date = fields.Date(related='employee_id.entry_date', string="入职时间", store=True)
number_card = fields.Integer(string='补卡次数', compute="_compute_number_card")
remaining_number_card = fields.Integer(string='剩余补卡次数', default=3, compute="_compute_number_card", store=True)
@@ -2510,6 +2511,7 @@ class VacationOverline(models.Model):
default=lambda self: str(datetime.now().year))
vacation_id = fields.Many2one('yuthon.vacation.reports', string='关联假期额度记录')
employee_id = fields.Many2one('hr.employee', string='员工', compute='_compute_employee_id', store=True)
employee_number = fields.Char(string='序号', related='employee_id.user_number', store=True)
entry_date = fields.Date(related='employee_id.entry_date', string="入职时间", store=True)
department_id = fields.Many2one('hr.department', related='employee_id.department_id', string="部门")
company_id = fields.Many2one('res.company', related='employee_id.company_id', string="公司")
@@ -2872,6 +2874,7 @@ class VacationMealLine(models.Model):
vacation_id = fields.Many2one('yuthon.vacation.reports', string='关联假期额度记录')
is_filing = fields.Boolean(string="归档")
employee_number = fields.Char(string='序号', related='employee_id.user_number', store=True)
employee_id = fields.Many2one('hr.employee', string='员工', compute='_compute_employee_id', store=True)
entry_date = fields.Date(related='employee_id.entry_date', string="入职时间", store=True)
department_id = fields.Many2one('hr.department', related='employee_id.department_id', string="部门", store=True)
@@ -4,10 +4,11 @@
<field name="name">hr.leave.statement.tree</field>
<field name="model">hr.leave</field>
<field name="arch" type="xml">
<tree string="请假情况" editable="bottom" limit="15" create="false" delete="false" js_class="custom_statement_confirm_button" default_order="entry_date asc">
<tree string="请假情况" editable="bottom" limit="15" create="false" delete="false" js_class="custom_statement_confirm_button" default_order="employee_number asc">
<header>
<button name="confirm_is_filing" type="object" string="归档" class="oe_highlight"/>
</header>
<field name="employee_number" column_invisible="1"/>
<field name="caption"/>
<field name="employee_id"/>
<field name="employee_company_id"/>
@@ -4,10 +4,11 @@
<field name="name">yuthon.meal.line.tree</field>
<field name="model">yuthon.meal.line</field>
<field name="arch" type="xml">
<tree string="误餐情况" create="false" default_order="entry_date asc" js_class="custom_vacation_confirm_meal_button">
<tree string="误餐情况" create="false" default_order="employee_number asc" js_class="custom_vacation_confirm_meal_button">
<header>
<button name="meal_wizard" type="object" string="归档" class="oe_highlight"/>
</header>
<field name="employee_number" column_invisible="1"/>
<field name="select_year"/>
<field name="select_month"/>
<field name="employee_id" string="申请人"/>
@@ -27,7 +27,8 @@
<field name="name">yuthon.overtime.line.tree</field>
<field name="model">yuthon.overtime.line</field>
<field name="arch" type="xml">
<tree string="加班合计数报表" editable="bottom" js_class="custom_vacation_confirm_button" create="0" default_order="entry_date asc">
<tree string="加班合计数报表" editable="bottom" js_class="custom_vacation_confirm_button" create="0" default_order="employee_number asc">
<field name="employee_number" column_invisible="1"/>
<field name="employee_id"/>
<field name="select_year"/>
<field name="select_month"/>
@@ -4,7 +4,7 @@
<field name="name">vacation.meal.line.tree</field>
<field name="model">vacation.meal.line</field>
<field name="arch" type="xml">
<tree string="误餐情况" create="false" default_order="entry_date asc">
<tree string="误餐情况" create="false" default_order="employee_number asc">
<header>
<button name="confirm" type="object" string="归档" class="oe_highlight"/>
</header>
@@ -44,7 +44,7 @@
<field name="name">yuthon.vacation.reports.tree</field>
<field name="model">yuthon.vacation.reports</field>
<field name="arch" type="xml">
<tree string="考勤确认单台账" editable="bottom" edit="0" default_order="entry_date asc"
<tree string="考勤确认单台账" editable="bottom" edit="0" default_order="employee_number asc"
js_class="custom_vacation_put_button" limit="10">
<header>
<button name="manage_confirmation" type="object" string="批量确认" class="oe_highlight"/>
@@ -53,6 +53,7 @@
<field name="vacation_state" widget="badge" decoration-info="vacation_state == 'not_sent'"
decoration-success="vacation_state == 'confirmed'"/>
<field name="display_date"/>
<field name="employee_number" column_invisible="1"/>
<field name="employee_id" options="{'no_open': True}"/>
<field name="department_id" column_invisible="1"/>
<field name="company_id" column_invisible="1"/>
@@ -280,7 +281,7 @@
<field name="vacation_id" column_invisible="1"/>
<field name="employee_id" column_invisible="1"/>
<field name="workflow_record_id"
domain="[('workflow_id.name', '=', '加班'), ('create_uid.employee_id', '=', employee_id)]"/>
domain="[('workflow_id.name', 'in', ['加班', '请假']), ('create_uid.employee_id', '=', employee_id)]"/>
<field name="update_type" readonly="0"/>
<field name="update_date" readonly="0"/>
<field name="workday"/>
@@ -568,7 +569,7 @@
<field name="vacation_id" column_invisible="1"/>
<field name="employee_id" column_invisible="1"/>
<field name="workflow_record_id"
domain="[('workflow_id.name', '=', '加班'), ('create_uid.employee_id', '=', employee_id)]"/>
domain="[('workflow_id.name', '=', ['加班', '请假']), ('create_uid.employee_id', '=', employee_id)]"/>
<field name="update_type" readonly="1"/>
<field name="update_date" readonly="1"/>
<field name="workday"/>
@@ -703,8 +704,9 @@
<field name="name">vacation.over.line.overtime.tree</field>
<field name="model">vacation.over.line</field>
<field name="arch" type="xml">
<tree string="加班明细" editable="bottom" js_class="custom_overtime_export_button" default_order="start_time asc entry_date asc">
<tree string="加班明细" editable="bottom" js_class="custom_overtime_export_button" default_order="start_time asc employee_number asc">
<field name="active" column_invisible="1"/>
<field name="employee_number" column_invisible="1"/>
<field name="overtime_name"/>
<field name="meal" column_invisible="1"/>
<field name="reason_application" column_invisible="1"/>
@@ -729,8 +731,9 @@
<field name="name">vacation.over.line.overtime.tree</field>
<field name="model">vacation.over.line</field>
<field name="arch" type="xml">
<tree string="加班明细" editable="bottom" js_class="custom_overtime_export_button" default_order="start_time asc entry_date asc">
<tree string="加班明细" editable="bottom" js_class="custom_overtime_export_button" default_order="start_time asc employee_number asc">
<field name="active" column_invisible="1"/>
<field name="employee_number" column_invisible="1"/>
<field name="overtime_name"/>
<field name="meal" column_invisible="1"/>
<field name="reason_application" column_invisible="1"/>
@@ -26,7 +26,7 @@ class YuthonHrEmployee(models.Model):
对原模型数据的隐藏,字段的开发和添加
"""
_inherit = "hr.employee"
_order = 'number asc'
_order = 'user_number asc'
# name = fields.CharWithPinyin(default_export_compatible=True)
user_role_ids_changed = fields.Boolean(string="xxx") # bug
@@ -50,7 +50,7 @@ class YuthonHrEmployee(models.Model):
user_sex = fields.Selection([('girl', '女'), ('boy', '男')], string="性别")
user_state = fields.Selection([('in', '在职'), ('leave', '离职'), ('withdraw', '退休'), ('borrow', '借调'),
('expatriate', '外派'), ('adjunct', '在职(兼职)')],
string="员工状态")
string="员工状态", default='in')
user_number_start_time = fields.Date(string="身份证开始时间")
user_role_id = fields.Many2one('soong.user.role', string="主角色")
user_role_ids = fields.Many2many('soong.user.role', string="辅助角色")
@@ -9,6 +9,7 @@ class YuthonMedicalManage(models.Model):
_description = '体检费管理'
employee_id = fields.Many2one('hr.employee', string="员工姓名")
employee_number = fields.Char( string='序号', related='employee_id.user_number', store=True, readonly=True)
start_date = fields.Date(string='开始日期')
year = fields.Char(string="年份")
current_year_remaining = fields.Float(string="本年剩余", compute="_compute_current_year_remaining")
@@ -17,12 +18,9 @@ class YuthonMedicalManage(models.Model):
last_year_quota = fields.Float(string="去年额度")
last_year_used = fields.Float(string="去年使用", compute="_compute_last_year_used")
last_year_remaining = fields.Float(string="去年剩余")
last_year_balance = fields.Float(string="去年结余")
prev_last_year_remaining = fields.Float(string="前年剩余")
prev_last_year_balance = fields.Float(string="前年结余")
this_year_usage = fields.Float(string='本年使用', compute="_compute_this_year_usage")
this_year_quota = fields.Float(string='本年额度')
identification_id = fields.Char(related='employee_id.identification_id', string="身份证")
birthday = fields.Date(related='employee_id.birthday', string="出生年月")
marital_status = fields.Selection([('married', '已婚'), ('unmarried', '未婚')],
related='employee_id.marital', string='婚姻状况')
@@ -37,13 +35,15 @@ class YuthonMedicalManage(models.Model):
@api.depends('this_year_quota', 'this_year_usage', 'last_year_remaining')
def _compute_current_year_remaining(self):
for record in self:
record.current_year_remaining = record.this_year_quota + record.last_year_remaining - record.this_year_usage
record.current_year_remaining = record.this_year_quota + record.last_year_remaining - record.this_year_usage
if record.current_year_remaining != record.remainder_the_year:
record.remainder_the_year = record.current_year_remaining
def update_remainder_the_year(self):
soong_ids = self.env["yuthon.medical.manage"].browse(
self._context.get('active_ids', self._context.get('active_id')))
for soong_id in soong_ids:
soong_id.remainder_the_year = soong_id.this_year_quota + soong_id.last_year_balance - soong_id.this_year_usage
soong_id.remainder_the_year = soong_id.this_year_quota + soong_id.last_year_remaining - soong_id.this_year_usage
if soong_id.year:
soong_id.start_date = f"{soong_id.year}-01-01"
@@ -106,7 +106,7 @@ class YuthonMedicalManage(models.Model):
if employee.user_sex == 'girl':
if employee.marital == 'single':
final_quota += rule.allowance_unmarried_women
elif employee.marital == 'married':
elif employee.marital in ['married', 'divorced']:
final_quota += rule.allowance_married_women
entry_date = fields.Date.from_string(employee.entry_date)
@@ -140,6 +140,7 @@ class YuthonMedicalManage(models.Model):
('user_state', '=', 'in'),
('company_id.name', '=', '集团本部'),
('contract_id.party_id', 'in', party_setting_records),
('contract_id.is_probation', '=', False)
])
for employee in open_employees:
medical_manage_rec = self.env['yuthon.medical.manage'].search([
@@ -161,7 +162,7 @@ class YuthonMedicalManage(models.Model):
continue
medical_manage_rec.write({'this_year_quota': this_year_quota,
})
medical_manage_rec.remainder_the_year = medical_manage_rec.this_year_quota + medical_manage_rec.last_year_balance - medical_manage_rec.this_year_usage
medical_manage_rec.remainder_the_year = medical_manage_rec.this_year_quota + medical_manage_rec.last_year_remaining - medical_manage_rec.this_year_usage
medical_manage_rec.start_date = current_date
# 回填上年数据
@@ -172,14 +173,12 @@ class YuthonMedicalManage(models.Model):
if last_year_rec:
medical_manage_rec.write({
'last_year_quota': last_year_rec.this_year_quota,
'last_year_remaining': last_year_rec.current_year_remaining,
'last_year_balance': min(last_year_rec.this_year_quota * 2, last_year_rec.current_year_remaining),
'last_year_remaining': min(last_year_rec.this_year_quota * 2, last_year_rec.current_year_remaining),
})
# 回填前年数据
prev_last_year_vals = {
'prev_last_year_balance': min(last_year_rec.last_year_quota * 2, last_year_rec.last_year_remaining),
'prev_last_year_remaining': last_year_rec.last_year_remaining,
'prev_last_year_remaining': min(last_year_rec.this_year_quota * 2, last_year_rec.current_year_remaining),
}
medical_manage_rec.write(prev_last_year_vals)
@@ -192,7 +191,7 @@ class YuthonMedicalManage(models.Model):
this_year_quota = self._calculate_medical_quota(employee, current_year)
medical_record.write({'this_year_quota': this_year_quota,
})
medical_record.remainder_the_year = medical_record.this_year_quota + medical_record.last_year_balance - medical_record.this_year_usage
medical_record.remainder_the_year = medical_record.this_year_quota + medical_record.last_year_remaining - medical_record.this_year_usage
# 回填上年数据
last_year_rec = self.env['yuthon.medical.manage'].search([
('employee_id', '=', employee.id),
@@ -201,13 +200,11 @@ class YuthonMedicalManage(models.Model):
if last_year_rec:
medical_record.write({
'last_year_quota': last_year_rec.this_year_quota,
'last_year_remaining': last_year_rec.current_year_remaining,
'last_year_balance': min(last_year_rec.this_year_quota * 2, last_year_rec.current_year_remaining),
'last_year_remaining': min(last_year_rec.this_year_quota * 2, last_year_rec.current_year_remaining),
})
# 回填前年数据
prev_last_year_vals = {
'prev_last_year_balance': min(last_year_rec.last_year_quota * 2, last_year_rec.last_year_remaining),
'prev_last_year_remaining': last_year_rec.last_year_remaining,
'prev_last_year_remaining': min(last_year_rec.last_year_quota * 2, last_year_rec.last_year_remaining),
}
medical_record.write(prev_last_year_vals)
@@ -251,13 +248,13 @@ class YuthonMedicalManage(models.Model):
last_year_quota = self._calculate_medical_quota(rec.employee_id, last_year)
this_year_quota = self._calculate_medical_quota(rec.employee_id, current_year)
prev_last_year_quota = self._calculate_medical_quota(rec.employee_id, prev_last_year)
prev_last_year_balance = min(prev_last_year_quota * 2, rec.prev_last_year_remaining)
last_year_balance = min(last_year_quota * 2, rec.last_year_remaining)
prev_last_year_remaining = min(prev_last_year_quota * 2, rec.prev_last_year_remaining)
last_year_remaining = min(last_year_quota * 2, rec.last_year_remaining)
rec.write({
'this_year_quota': this_year_quota,
'last_year_quota': last_year_quota,
'prev_last_year_balance': prev_last_year_balance,
'last_year_balance': last_year_balance,
'prev_last_year_remaining': prev_last_year_remaining,
'last_year_remaining': last_year_remaining,
})
class YuthonMedicalLine(models.Model):
@@ -221,7 +221,7 @@
<attribute name="options">"{'no_create': True, 'no_open': True}"</attribute>
</xpath>
<xpath expr="//field[@name='job_id']" position="after">
<field name="number"/>
<field name="number" invisible="1"/>
<field name="user_number"/>
<field name="contract_type_id" options="{'no_open': True}"/>
</xpath>
@@ -512,7 +512,7 @@
decoration-info="end_comparison == 'blue'"
decoration-danger="end_comparison == 'red'"
decoration-warning="end_comparison == 'yellow'"
default_order="entry_date asc">
default_order="user_number asc">
<header>
</header>
<field name="end_comparison" column_invisible="1"/>
@@ -4,29 +4,28 @@
<field name="name">yuthon.medical.manage.tree</field>
<field name="model">yuthon.medical.manage</field>
<field name="arch" type="xml">
<tree string="体检费管理" editable="bottom" default_order="entry_date desc">
<tree string="体检费管理" editable="bottom" default_order="employee_number asc">
<header>
<button name="property_reimbursement_form" string="提交体检费报销审批" type="object"
class="oe_highlight"/>
<button name="compute_medical_manage" string="重新计算" type="object"
class="oe_highlight"/>
</header>
<field name="employee_number" column_invisible="1"/>
<field name="employee_id" options="{'no_create': True}"/>
<field name="year" column_invisible="1"/>
<!-- <field name="company_id" required="1" optional="show"/>-->
<field name="current_year_remaining" options='{ "fg_color": "blue"}'/>
<field name="this_year_quota"/>
<field name="last_year_balance" column_invisible="1"/>
<field name="this_year_usage" options='{ "fg_color": "red"}'/>
<field name="last_year_remaining" options='{ "fg_color": "blue"}'/>
<field name="last_year_quota"/>
<field name="prev_last_year_balance" column_invisible="1"/>
<field name="last_year_used" options='{ "fg_color": "red"}'/>
<field name="prev_last_year_remaining" options='{ "fg_color": "blue"}'/>
<field name="birthday"/>
<field name="marital_status"/>
<field name="entry_date"/>
<field name="termination_date"/>
<field name="birthday" groups="hr_payroll.group_hr_payroll_manager"/>
<field name="marital_status" groups="hr_payroll.group_hr_payroll_manager"/>
<field name="entry_date" groups="hr_payroll.group_hr_payroll_manager"/>
<field name="termination_date" groups="hr_payroll.group_hr_payroll_manager"/>
<button name="button_details" string="查看详情" type="object" class="btn btn-blue"/>
</tree>
</field>
@@ -8,6 +8,7 @@ class YuthonMealExpenses(models.Model):
_description = '餐费'
employee_id = fields.Many2one('hr.employee', string='姓名')
employee_number = fields.Char(string='序号', related='employee_id.user_number', store=True)
card = fields.Char(string='身份证')
number_breakfasts = fields.Integer(string='早餐次数', compute='_compute_catering_counts', store=True)
number_lunches = fields.Integer(string='午餐次数', compute='_compute_catering_counts', store=True)
@@ -23,7 +23,7 @@
<field name="name">yuthon.meal.expenses.tree</field>
<field name="model">yuthon.meal.expenses</field>
<field name="arch" type="xml">
<tree string="餐费" editable="bottom" js_class="custom_meal_button">
<tree string="餐费" editable="bottom" js_class="custom_meal_button" default_order="employee_number asc">
<header>
<button name="action_generate_missing_feb" string="批量生成2026年2月缺失数据" type="object" class="btn btn-blue"/>
<button name="action_generate_missing_mar" string="批量生成2026年3月缺失数据" type="object" class="btn btn-blue"/>
@@ -31,6 +31,7 @@
<button name="action_batch_send_reminder" string="批量催缴" type="object" class="btn btn-blue"/>
<button name="action_test_monthly_reminder" string="测试月度提醒" type="object" class="btn btn-blue"/>
</header>
<field name="employee_number" column_invisible="1"/>
<field name="select_year"/>
<field name="select_time"/>
<field name="employee_id"/>