@@ -58,7 +58,7 @@ class BusController(Controller):
|
||||
if employee_id:
|
||||
request.env(user=SUPERUSER_ID)["hr.attendance.detail"].create({
|
||||
'employee_id': employee_id.id, # 员工
|
||||
'checkin_time': fields.Datetime.now(), # 打卡时间
|
||||
'checkin_time': fields.Datetime.now(),
|
||||
'source': 'iot', # 打卡来源
|
||||
'attendance_iot_id': attendance_iot_id.id, # 打卡设备
|
||||
})
|
||||
|
||||
@@ -45,12 +45,12 @@ class SoongWorkflowLog(models.Model):
|
||||
@api.depends("workflow_id", "node_id", "node_btn_id")
|
||||
def _compute_name(self):
|
||||
for rec in self:
|
||||
# rec.name = "%(workflow_id_name)s - %(node_id_name)s - %(node_btn_name)s" % {
|
||||
# "workflow_id_name": rec.workflow_id.name,
|
||||
# "node_id_name": rec.node_id.name,
|
||||
# "node_btn_name": rec.node_btn_id.name,
|
||||
# }
|
||||
rec.name = "%(node_id_name)s" % {"node_id_name": rec.node_id.name}
|
||||
if rec.name == '归档':
|
||||
pass
|
||||
if rec.node_id:
|
||||
rec.name = "%(node_id_name)s" % {"node_id_name": rec.node_id.name}
|
||||
else:
|
||||
rec.name = ""
|
||||
|
||||
@api.depends("workflow_id")
|
||||
def _compute_sequence(self):
|
||||
@@ -91,7 +91,10 @@ class SoongWorkflowLog2(models.Model):
|
||||
@api.depends("workflow_id", "node_id", "node_btn_id")
|
||||
def _compute_name(self):
|
||||
for rec in self:
|
||||
rec.name = "%(node_id_name)s" % {"node_id_name": rec.node_id.name}
|
||||
if rec.node_id and rec.node_btn_id:
|
||||
rec.name = "%(node_id_name)s" % {"node_id_name": rec.node_id.name}
|
||||
else:
|
||||
rec.name = None
|
||||
|
||||
@api.depends("workflow_id")
|
||||
def _compute_sequence(self):
|
||||
|
||||
@@ -96,17 +96,24 @@ class SoongWorkflowMixin(models.AbstractModel):
|
||||
if matched_logs and all(log.approval_state == '0' for log in matched_logs):
|
||||
record.is_back = True
|
||||
if record._name == 'yuthon.official.incoming.normal':
|
||||
has_handling_log = any(
|
||||
log.name == '承办' and log.approval_state == '1'
|
||||
for log in record.log_ids
|
||||
)
|
||||
has_handling_log2 = any(
|
||||
log.approval_state == '1'
|
||||
current_user_in_logs2 = any(
|
||||
log.done_by.id == self.env.uid
|
||||
for log in record.log_ids2
|
||||
)
|
||||
if has_handling_log or has_handling_log2:
|
||||
record.is_back = False
|
||||
else:
|
||||
organizer_user_in_logs = any(
|
||||
log.done_by.id == self.env.user.id
|
||||
for log in record.log_ids.filtered(lambda l: l.name == '承办')
|
||||
)
|
||||
all_handling_logs_approval_0 = all(
|
||||
log.approval_state == '0'
|
||||
for log in record.log_ids.filtered(lambda l: l.name == '承办')
|
||||
)
|
||||
all_logs2_approval_0 = all(
|
||||
log.approval_state == '0'
|
||||
for log in record.log_ids2
|
||||
)
|
||||
|
||||
if all_logs2_approval_0 and all_handling_logs_approval_0 and not current_user_in_logs2 and not organizer_user_in_logs:
|
||||
record.is_back = True
|
||||
|
||||
def _compute_is_active(self):
|
||||
@@ -115,7 +122,7 @@ class SoongWorkflowMixin(models.AbstractModel):
|
||||
query_user_id = self.user_id.id
|
||||
elif hasattr(self, 'users_id') and self.users_id:
|
||||
query_user_id = self.users_id.id
|
||||
if query_user_id == current_user_id and self.work_end:
|
||||
if query_user_id == current_user_id and self.work_end and self.log_ids[-1].approval_state in ['0', '1']:
|
||||
self.is_active = True
|
||||
else:
|
||||
self.is_active = False
|
||||
@@ -128,9 +135,9 @@ class SoongWorkflowMixin(models.AbstractModel):
|
||||
('res_id', '=', record.id), ('approval_state', 'in', ['0', '1'])]
|
||||
lg2 = record.log_ids2.search(domain)
|
||||
lg1 = record.log_ids.search(domain)
|
||||
if lg2:
|
||||
if lg2 or lg1:
|
||||
record.is_confirm = False
|
||||
if lg1:
|
||||
if not lg1 and not lg2:
|
||||
record.is_end = False
|
||||
|
||||
@api.depends("node_id", "log_ids")
|
||||
@@ -215,7 +222,7 @@ class SoongWorkflowMixin(models.AbstractModel):
|
||||
|
||||
def _create_update_logs(self, btn_rec):
|
||||
log_obj = self.env["soong.workflow.log"]
|
||||
if btn_rec.name not in ['转交', '分发', '加签', '加签确认', '退回', '收回', '结束']:
|
||||
if btn_rec.name not in ['转交', '分发', '加签', '加签确认', '退回', '收回', '结束', '归档', '确认']:
|
||||
record_obj = log_obj.search(
|
||||
[("model", "=", self._name),
|
||||
("res_id", "=", self.id),
|
||||
@@ -508,7 +515,6 @@ class SoongWorkflowMixin(models.AbstractModel):
|
||||
'default_comment_note_id': comment_note_id,
|
||||
"default_code": self.code,
|
||||
"default_res_model": self._name,
|
||||
"default_log_ids": logs.ids,
|
||||
"default_node_btn_id": btn_rec.id,
|
||||
"default_is_supervising": is_supervising,
|
||||
"default_trans_link_id": self.env['trans.link'].search(trans_domain, limit=1).id if btn_rec.name == '转交' else False,
|
||||
|
||||
@@ -126,49 +126,41 @@ class SoongWorkflowNode(models.Model):
|
||||
@api.onchange("is_end")
|
||||
def onchange_is_end(self):
|
||||
for record in self:
|
||||
current_buttons = record.button_ids
|
||||
if record.is_end:
|
||||
record.use_custom_colors = True
|
||||
record.bg_color = END_BG_COLOR_1
|
||||
record.res_bg_color = END_BG_COLOR_1
|
||||
sequence = max([r.sequence for r in record.button_ids] if record.button_ids else [1])
|
||||
record.button_ids = [
|
||||
(0, 0, {
|
||||
"name": _("结束"),
|
||||
# "workflow_id": record.workflow_id.ids[0] if record.workflow_id.ids else None,
|
||||
"node_id": record.id,
|
||||
"sequence": sequence + 1,
|
||||
"action_type": "end",
|
||||
"btn_hide": False, # 对所有人显示
|
||||
"has_comment": False, # 对所有人显示
|
||||
"review_type": "end",
|
||||
}),
|
||||
]
|
||||
end_btns = current_buttons.filtered(lambda r: r.name == _("结束"))
|
||||
archive_btns = current_buttons.filtered(lambda r: r.name == _("归档"))
|
||||
remove_commands = [(3, btn.id) for btn in end_btns + archive_btns]
|
||||
sequence = max([r.sequence for r in current_buttons] if current_buttons else [1])
|
||||
add_end = (0, 0, {
|
||||
"name": _("结束"),
|
||||
"node_id": record.id,
|
||||
"sequence": sequence + 1,
|
||||
"action_type": "end",
|
||||
"btn_hide": False,
|
||||
"has_comment": False,
|
||||
"review_type": "end",
|
||||
})
|
||||
add_archive = (0, 0, {
|
||||
"name": _("归档"),
|
||||
"node_id": record.id,
|
||||
"sequence": sequence + 2,
|
||||
"action_type": "code",
|
||||
"btn_hide": False,
|
||||
"has_comment": False,
|
||||
})
|
||||
record.button_ids = remove_commands + [add_end, add_archive]
|
||||
|
||||
else:
|
||||
record.use_custom_colors = True
|
||||
record.bg_color = DEFAULT_BG_COLOR
|
||||
record.res_bg_color = DEFAULT_BG_COLOR
|
||||
remove_ids = record.button_ids.filtered(lambda r: r.name in ["结束"])
|
||||
record.button_ids = [(3, remove_id.id) for remove_id in remove_ids]
|
||||
|
||||
@api.onchange("is_archive")
|
||||
def onchange_is_archive(self):
|
||||
for record in self:
|
||||
if record.is_archive:
|
||||
sequence = max([r.sequence for r in record.button_ids] if record.button_ids else [1])
|
||||
record.button_ids = [
|
||||
(0, 0, {
|
||||
"name": _('归档'),
|
||||
"node_id": record.id,
|
||||
"sequence": sequence + 1,
|
||||
"action_type": "code",
|
||||
"btn_hide": False,
|
||||
"has_comment": False,
|
||||
}),
|
||||
]
|
||||
else:
|
||||
remove_ids = record.button_ids.filtered(lambda r: r.name in ["归档"])
|
||||
record.button_ids = [(3, remove_id.id) for remove_id in remove_ids]
|
||||
|
||||
end_btns = current_buttons.filtered(lambda r: r.name == _("结束"))
|
||||
archive_btns = current_buttons.filtered(lambda r: r.name == _("归档"))
|
||||
record.button_ids = [(3, btn.id) for btn in end_btns + archive_btns]
|
||||
|
||||
@api.onchange("is_confirm")
|
||||
def onchange_is_confirm(self):
|
||||
|
||||
@@ -67,7 +67,7 @@ class SoongWorkflowRecord(models.Model):
|
||||
done_by = fields.Many2one(comodel_name="res.users", string="发起人")
|
||||
active = fields.Boolean(string="归档", default=True)
|
||||
is_manager = fields.Boolean(string="是否管理员", compute='_compute_is_manager')
|
||||
soong_state = fields.Selection([('to_do', '待办'), ('done', '已办'), ('active', '已归档')], string="流程状态", default="to_do")
|
||||
soong_state = fields.Selection([('to_do', '待办'), ('done', '已办'),('to_active', '待归档'), ('active', '已归档')], string="流程状态", default="to_do")
|
||||
member_of_department = fields.Boolean("是否是本部门数据", compute='_compute_part_of_department',
|
||||
search='_search_part_of_department')
|
||||
|
||||
@@ -336,7 +336,7 @@ class SoongWorkflowRecord(models.Model):
|
||||
def get_view(self, view_id=None, view_type='form', **options):
|
||||
all_records = self.search([
|
||||
('users_ids', 'in', self.env.user.id),
|
||||
('soong_state', '!=', 'active')
|
||||
('soong_state', '!=', 'active'),
|
||||
])
|
||||
for record in all_records:
|
||||
record_id = self.env[record.res_model].browse(record.res_id)
|
||||
@@ -345,11 +345,22 @@ class SoongWorkflowRecord(models.Model):
|
||||
continue
|
||||
for log in record_id.log_ids:
|
||||
if log.done_by.name == self.env.user.name:
|
||||
if log.approval_state == '0'or log.approval_state == '1':
|
||||
if log.name == '归档' and (log.approval_state == '0' or log.approval_state == '1'):
|
||||
record.write({'soong_state': 'to_active'})
|
||||
elif log.name == '归档' and log.approval_state == '2':
|
||||
record.write({'soong_state': 'active'})
|
||||
elif log.approval_state == '0' or log.approval_state == '1':
|
||||
record.write({'soong_state': 'to_do'})
|
||||
else:
|
||||
record.write({'soong_state': 'done'})
|
||||
|
||||
for log2 in record_id.log_ids2:
|
||||
if log2.done_by.name == self.env.user.name:
|
||||
if log2.approval_state == '2':
|
||||
record.write({'soong_state': 'done'})
|
||||
elif log2.approval_state in ['0', '1']:
|
||||
record.write({'soong_state': 'to_do'})
|
||||
|
||||
return super(SoongWorkflowRecord, self).get_view(view_id, view_type, **options)
|
||||
|
||||
# def get_department_employees(self, department_id):
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
options="{'no_create': True}"/>
|
||||
<field name="is_apostille"/>
|
||||
<field name="is_end"/>
|
||||
<field name="is_archive"/>
|
||||
<field name="is_confirm"/>
|
||||
</group>
|
||||
</group>
|
||||
@@ -154,7 +153,7 @@
|
||||
<field name="model">soong.workflow.node.button</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<field name="workflow_id" invisible="1"/>
|
||||
<field name="workflow_id" invisible="0"/>
|
||||
<field name="invisible_expression_model" invisible="1"/>
|
||||
<sheet>
|
||||
<group>
|
||||
|
||||
@@ -317,7 +317,7 @@
|
||||
<field name="res_model">soong.workflow.record</field>
|
||||
<field name="view_mode">tree,kanban,search</field>
|
||||
<field name="context">{'header_search_default_approve_state': 1, 'header_search_default_to_do':1, 'check_employee': 1}</field>
|
||||
<field name="domain">[('users_ids', 'in', uid), ('reclaim_state', '=', False), ('soong_state', 'in', ['to_do', 'active'])]</field>
|
||||
<field name="domain">[('users_ids', 'in', uid), ('reclaim_state', '=', False), ('soong_state', 'in', ['to_do', 'to_active'])]</field>
|
||||
<field name="search_view_id" ref="soong_workflow_record_search1"/>
|
||||
<field name="view_id" ref="soong_workflow_record_my_tree"/>
|
||||
</record>
|
||||
@@ -327,7 +327,7 @@
|
||||
<field name="res_model">soong.workflow.record</field>
|
||||
<field name="view_mode">tree,kanban,search</field>
|
||||
<field name="context">{'header_search_default_approve_state': 1, 'header_search_default_to_do':1, 'check_employee': 1}</field>
|
||||
<field name="domain">[('users_ids', 'in', uid), ('reclaim_state', '=', False), ('soong_state', '=', 'done')]</field>
|
||||
<field name="domain">[('users_ids', 'in', uid), ('reclaim_state', '=', False), ('soong_state', 'in', ['done', 'active'])]</field>
|
||||
<field name="search_view_id" ref="soong_workflow_record_search1"/>
|
||||
<field name="view_id" ref="soong_workflow_record_my_tree"/>
|
||||
</record>
|
||||
|
||||
@@ -456,10 +456,18 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
fields.Datetime.now() + timedelta(
|
||||
hours=8)),
|
||||
url=url, btntxt="查看详情")
|
||||
msg_id = result_data[-1]['msgid']
|
||||
target_logs = next_node_log_records.filtered(lambda l: l.done_by.id == employee.user_id.id)
|
||||
if target_logs:
|
||||
target_logs.msg_id = msg_id
|
||||
msg_id = None
|
||||
try:
|
||||
if result_data and isinstance(result_data, list) and len(result_data) > 0:
|
||||
last_item = result_data[-1]
|
||||
if isinstance(last_item, dict) and 'msgid' in last_item:
|
||||
msg_id = last_item['msgid']
|
||||
except (IndexError, KeyError, TypeError):
|
||||
msg_id = None
|
||||
if msg_id:
|
||||
target_logs = next_node_log_records.filtered(lambda l: l.done_by.id == employee.user_id.id)
|
||||
if target_logs:
|
||||
target_logs.msg_id = msg_id
|
||||
|
||||
else: # 串审模式 (沿用原有逻辑)
|
||||
# 查找下一个节点
|
||||
@@ -606,12 +614,16 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
# if not record_id.log_ids2.search([('approval_state', '=', '0')]) or record_id.log_ids2:
|
||||
last_log = record_id.log_ids[-1] if record_id.log_ids else None
|
||||
if last_log:
|
||||
applicant = None
|
||||
for field_name in ['user_id', 'users_id']:
|
||||
if hasattr(record_id, field_name):
|
||||
applicant = getattr(record_id, field_name)
|
||||
if applicant:
|
||||
break
|
||||
same_name_logs = record_id.log_ids.filtered(
|
||||
lambda log: log.name == last_log.name and log.node_btn_name == '4' and log.id != last_log.id
|
||||
)
|
||||
all_approved = all(log.approval_state == '3' for log in same_name_logs)
|
||||
all_approved = all_approved and (last_log.approval_state == '3')
|
||||
|
||||
all_approved = all(log.approval_state == '3' for log in same_name_logs) or not same_name_logs
|
||||
log2_ids_all_qualified = True
|
||||
if record_id.log_ids2:
|
||||
log2_ids_all_qualified = all(log2.approval_state == '2' for log2 in record_id.log_ids2)
|
||||
@@ -622,19 +634,25 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
if workflow_record:
|
||||
workflow_record.write({
|
||||
'approve_state': 'end',
|
||||
'employee_ids': False,
|
||||
'employee_ids': [(6, 0, [applicant.employee_ids.id])],
|
||||
'soong_state': 'to_active',
|
||||
'node_id': False,
|
||||
})
|
||||
log_id = record_id.log_ids.filtered(lambda l: l.comment in ['归档', '待归档'])
|
||||
if not log_id:
|
||||
self.env["soong.workflow.log"].create({
|
||||
'name': '归档',
|
||||
"code": self.code,
|
||||
"model": self.res_model,
|
||||
"res_id": self.res_id,
|
||||
"workflow_id": self.node_btn_id.workflow_id.id,
|
||||
"lase_click_date": fields.Datetime.now(),
|
||||
"done_by": applicant.id,
|
||||
"approval_state": "0",
|
||||
"node_btn_id": self.node_btn_id.id,
|
||||
})
|
||||
record_id.work_end = True
|
||||
else:
|
||||
self.env['soong.workflow.record'].search([
|
||||
('code', '=', record_id.code)
|
||||
]).write({
|
||||
'approve_state': 'end',
|
||||
'employee_ids': False,
|
||||
'node_id': False,
|
||||
})
|
||||
record_id.work_end = True
|
||||
|
||||
# 给申请人发消息
|
||||
biz_record = self.env[self.res_model].browse(self.res_id)
|
||||
if hasattr(biz_record, 'user_id') and biz_record.user_id:
|
||||
@@ -696,8 +714,12 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
"done_by": self.employee_ids.user_id.id,
|
||||
"node_btn_name": "0",
|
||||
})
|
||||
result_data = self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id='18562027762', title=record_id._description, description=description, url=url, btntxt="查看详情")
|
||||
msg_id = result_data[-1]['msgid']
|
||||
result_data = self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id=emp.wecom_userid, title=record_id._description, description=description, url=url, btntxt="查看详情")
|
||||
msg_id = None
|
||||
if result_data and isinstance(result_data, list) and len(result_data) > 0:
|
||||
last_item = result_data[-1]
|
||||
if isinstance(last_item, dict) and 'msgid' in last_item:
|
||||
msg_id = last_item['msgid'] or ""
|
||||
log_id.msg_id = msg_id
|
||||
for emp in self.dep_manager_employee_ids:
|
||||
workflow_record_id.users_ids = [(4, employee.user_id.id) for employee in self.dep_manager_employee_ids if employee.user_id]
|
||||
@@ -712,7 +734,11 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
"node_btn_name": "4",
|
||||
})
|
||||
result_data = self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id=emp.wecom_userid, title=record_id._description + "承办", description=description, url=url, btntxt="查看详情")
|
||||
msg_id = result_data[-1]['msgid']
|
||||
msg_id = None
|
||||
if result_data and isinstance(result_data, list) and len(result_data) > 0:
|
||||
last_item = result_data[-1]
|
||||
if isinstance(last_item, dict) and 'msgid' in last_item:
|
||||
msg_id = last_item['msgid'] or ""
|
||||
log_id.msg_id = msg_id
|
||||
for employee in self.circulated_employee_ids:
|
||||
workflow_record_id.users_ids = [(4, employee.user_id.id) for employee in self.circulated_employee_ids if employee.user_id]
|
||||
@@ -736,8 +762,12 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
"node_btn_id": self.node_btn_id.id,
|
||||
"approval_state": "0",
|
||||
})
|
||||
result_data = self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id='18562027762', title=record_id._description + "传阅/抄送",description=description, url=url, btntxt="查看详情")
|
||||
msg_id = result_data[-1]['msgid']
|
||||
result_data = self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id=emp.wecom_userid, title=record_id._description + "传阅/抄送",description=description, url=url, btntxt="查看详情")
|
||||
msg_id = None
|
||||
if result_data and isinstance(result_data, list) and len(result_data) > 0:
|
||||
last_item = result_data[-1]
|
||||
if isinstance(last_item, dict) and 'msgid' in last_item:
|
||||
msg_id = last_item['msgid'] or ""
|
||||
log2_id.msg_id = msg_id
|
||||
workflow_record_id.employee_ids = self.dep_manager_employee_ids + self.employee_ids + self.circulated_employee_ids
|
||||
record_id.log_ids[-1].write({"comment": self.comment, "approval_state": "2", "lase_click_date": fields.Datetime.now()})
|
||||
@@ -766,8 +796,14 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
self.node_btn_id.with_context(cx).run()
|
||||
|
||||
if self.node_btn_name == '归档':
|
||||
record = self.env[self.res_model].search([('id', '=', self.res_id)])
|
||||
record.log_ids[-1].write({'approval_state': '2'})
|
||||
if self.document_ids:
|
||||
record.log_ids[-1].write({'document_ids': [(6, 0, self.document_ids.ids)]})
|
||||
workflow_record_id = self.env['soong.workflow.record'].search([('code', '=', record_id.code)])
|
||||
workflow_record_id.write({'soong_state': 'active'})
|
||||
workflow_record_id.write({'soong_state': 'active',
|
||||
'employee_ids':False
|
||||
})
|
||||
|
||||
|
||||
if self.node_btn_name != "收回":
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
</group>
|
||||
<div invisible="node_btn_name != '归档'">
|
||||
<h2>你确认要归档吗?</h2>
|
||||
<group>
|
||||
<field name="document_ids" widget="many2many_tags"/>
|
||||
</group>
|
||||
</div>
|
||||
<group invisible="node_btn_name != '结束'">
|
||||
<div>
|
||||
@@ -69,7 +72,7 @@
|
||||
<group col="2" invisible="node_btn_name in ['分发', '结束', '收回', '确认', '归档']">
|
||||
<group>
|
||||
<!-- 转交人员 -->
|
||||
<field name="trans_link_id" string="转交节点" invisible="node_btn_name == '退回'" domain="[('id', 'not in', invalid_link_ids)]" options="{'no_open': True}" widget="radio"/>
|
||||
<field name="trans_link_id" string="转交节点" invisible="node_btn_name == '退回'" domain="[('id', 'not in', invalid_link_ids)]" options="{'no_open': True}" widget="radio" force_save="1"/>
|
||||
<field name="employee_trans_domain_ids" invisible="1"/>
|
||||
<!-- 退回意见退回类型 -->
|
||||
<field name="return_link_id" invisible="node_btn_name != '退回'" string="退回节点" widget="radio"/>
|
||||
|
||||
@@ -53,9 +53,12 @@
|
||||
<field name="increase"/>
|
||||
<field name="reason_application"/>
|
||||
<field name="is_issues" invisible="is_issues == False"/>
|
||||
<field name="documents_ids" widget="preview_many2many"/>
|
||||
<!-- <field name="documents_ids" widget="preview_many2many"/>-->
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<field name="documents_ids" widget="preview_many2many"/>
|
||||
</group>
|
||||
<group>
|
||||
<group>
|
||||
<field name="users_id" invisible="1"/>
|
||||
|
||||
@@ -414,6 +414,10 @@ class HrAttendanceDetail(models.Model):
|
||||
start_datetime = datetime.combine(date, datetime.min.time()).replace(
|
||||
hour=start_hour, minute=start_minute, second=0, microsecond=0
|
||||
) - timedelta(hours=8)
|
||||
if template.planning_name == '厨卫(集团本部)':
|
||||
start_datetime = datetime.combine(date, datetime.min.time()).replace(
|
||||
hour=start_hour, minute=start_minute, second=0, microsecond=0
|
||||
) - timedelta(hours=6)
|
||||
if template.day2 == '次日':
|
||||
end_datetime = datetime.combine(date, datetime.min.time()).replace(
|
||||
hour=end_hour, minute=end_minute, second=0, microsecond=0
|
||||
|
||||
@@ -55,10 +55,13 @@
|
||||
<field name="attendance_id" domain="[('employee_id', '=', employee_id), '|', '|', '|', '|', ('is_abnormal', '=', True), ('is_early_card', '=', True), ('is_late_card', '=', True), ('absenteeism_card', '=', True), ('is_no_card', '=', True)]" invisible="is_attendance"/>
|
||||
<field name="attendance" invisible="not is_attendance"/>
|
||||
<field name="replacement_time"/>
|
||||
<field name="documents_ids" widget="preview_many2many"/>
|
||||
<!-- <field name="documents_ids" widget="preview_many2many"/>-->
|
||||
</group>
|
||||
<group/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="documents_ids" widget="preview_many2many"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
|
||||
@@ -98,6 +98,9 @@
|
||||
</group>
|
||||
<group/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="documents_ids" widget="preview_many2many"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
|
||||
@@ -62,10 +62,13 @@
|
||||
<field name="work_end" invisible="1"/>
|
||||
<field name="reason_application"/>
|
||||
<field name="issues_result" invisible="is_issues == False"/>
|
||||
<field name="documents_ids" widget="preview_many2many"/>
|
||||
<!-- <field name="documents_ids" widget="preview_many2many"/>-->
|
||||
</group>
|
||||
<group/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="documents_ids" widget="preview_many2many"/>
|
||||
</group>
|
||||
<group col="2" string="加班信息">
|
||||
<field name="type_overtime"/>
|
||||
<group>
|
||||
|
||||
@@ -50,9 +50,12 @@
|
||||
<field name="work_end" invisible="1"/>
|
||||
<field name="reason_application"/>
|
||||
<field name="issues_result" invisible="is_issues == False"/>
|
||||
<field name="documents_ids" widget="preview_many2many"/>
|
||||
<!-- <field name="documents_ids" widget="preview_many2many"/>-->
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<field name="documents_ids" widget="preview_many2many"/>
|
||||
</group>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="users_id" widget="ztree_select"/>
|
||||
|
||||
@@ -54,12 +54,15 @@
|
||||
<field name="alternate_shifts" invisible="1"/>
|
||||
<field name="work_end" invisible="1"/>
|
||||
<field name="is_issues" invisible="is_issues == False"/>
|
||||
<field name="documents_ids" widget="preview_many2many"/>
|
||||
<!-- <field name="documents_ids" widget="preview_many2many"/>-->
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="users_id" invisible="1"/>
|
||||
<field name="department_id" invisible="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<field name="documents_ids" widget="preview_many2many"/>
|
||||
</group>
|
||||
<group string="换班1" invisible="work_end">
|
||||
<label for="resource_id"/>
|
||||
<div>
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
<field name="reason_application"/>
|
||||
<field name="work_end" invisible="1"/>
|
||||
<field name="issues_result" invisible="is_issues == False"/>
|
||||
<field name="documents_ids" widget="preview_many2many"/>
|
||||
<!-- <field name="documents_ids" widget="preview_many2many"/>-->
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="resource_id" domain="[('company_id', '=', company_id)]"/>
|
||||
<field name="department_id" invisible="1"/>
|
||||
@@ -62,6 +62,9 @@
|
||||
<field name="users_id" invisible="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<field name="documents_ids" widget="preview_many2many"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
|
||||
@@ -53,9 +53,12 @@
|
||||
<field name="is_department" invisible="1"/>
|
||||
<field name="work_end" invisible="1"/>
|
||||
<field name="reason_application"/>
|
||||
<field name="documents_ids" widget="preview_many2many"/>
|
||||
<!-- <field name="documents_ids" widget="preview_many2many"/>-->
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<field name="documents_ids" widget="preview_many2many"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="部门变更明细" invisible="is_department">
|
||||
<field name="approval_ids">
|
||||
|
||||
@@ -40,14 +40,17 @@
|
||||
<group string="审批事项">
|
||||
<group>
|
||||
<field name="is_back" invisible="1"/>
|
||||
<field name="name" readonly="0"/>
|
||||
<field name="name" readonly="0"/>F
|
||||
<field name="users_id"/>
|
||||
<field name="work_end" invisible="1"/>
|
||||
<field name="reason_application"/>
|
||||
<field name="is_execution" invisible="1"/>
|
||||
<field name="documents_ids" widget="preview_many2many"/>
|
||||
<!-- <field name="documents_ids" widget="preview_many2many"/>-->
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<field name="documents_ids" widget="preview_many2many"/>
|
||||
</group>
|
||||
<group string="离职信息" col="3">
|
||||
<group>
|
||||
<field name="employee_id"/>
|
||||
|
||||
@@ -49,9 +49,12 @@
|
||||
<field name="users_id"/>
|
||||
<field name="work_end" invisible="1"/>
|
||||
<field name="reason_application"/>
|
||||
<field name="documents_ids" widget="preview_many2many"/>
|
||||
<!-- <field name="documents_ids" widget="preview_many2many"/>-->
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<field name="documents_ids" widget="preview_many2many"/>
|
||||
</group>
|
||||
<group string="续签员工" col="2">
|
||||
<group>
|
||||
<field name="employee_id"/>
|
||||
|
||||
@@ -16,7 +16,7 @@ class IssueLibrary(models.Model):
|
||||
topic_content = fields.Text(string='事项背景')
|
||||
will_based = fields.Text(string='上会依据')
|
||||
deliberation_content = fields.Text(string='请示事项', default='建议同意')
|
||||
handling_situation = fields.Text(string='办理情况')
|
||||
handling_situation = fields.Text(string='办理情况', help="(存在问题)")
|
||||
is_invisible_workflow = fields.Boolean(string="流程隐藏的判断")
|
||||
code = fields.Char(string='编号', required=True, copy=False,
|
||||
default=lambda self: self.env['ir.sequence'].next_by_code('issue_library_code'))
|
||||
|
||||
@@ -11,7 +11,6 @@ class IssueMeetingMinutes(models.Model):
|
||||
|
||||
name = fields.Char(string='名称')
|
||||
number_of_meetings = fields.Integer(string='会议次数')
|
||||
|
||||
meeting_id = fields.Many2one('room.booking', string='会议名称', required=True)
|
||||
meeting_type_id = fields.Many2one('room.meeting.type', string="会议类型")
|
||||
meeting_date = fields.Datetime(string="会议时间")
|
||||
|
||||
@@ -105,13 +105,20 @@
|
||||
<field name="name_title" readonly="1"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<field name="name" required="1" force_save="1" invisible="is_invisible_workflow" readonly="issue_state not in ['draft', 'cancel']"/>
|
||||
<field name="topic_content" invisible="is_invisible_workflow" readonly="issue_state not in ['draft', 'cancel']"/>
|
||||
<field name="handling_situation" string="办理情况" placeholder="(存在问题)" readonly="issue_state not in ['draft', 'cancel']"/>
|
||||
<field name="deliberation_content" readonly="issue_state not in ['draft', 'cancel']"/>
|
||||
<field name="will_based" readonly="issue_state not in ['draft', 'cancel']"/>
|
||||
</group>
|
||||
<group>
|
||||
<group>
|
||||
<field name="name" required="1" force_save="1" invisible="is_invisible_workflow" readonly="issue_state not in ['draft', 'cancel']"/>
|
||||
<field name="topic_content" invisible="is_invisible_workflow" readonly="issue_state not in ['draft', 'cancel']"/>
|
||||
<field name="handling_situation" string="办理情况(存在问题)" readonly="issue_state not in ['draft', 'cancel']"/>
|
||||
<field name="deliberation_content" readonly="issue_state not in ['draft', 'cancel']"/>
|
||||
<field name="will_based" readonly="issue_state not in ['draft', 'cancel']"/>
|
||||
<!-- <field name="name" required="1" force_save="1" invisible="is_invisible_workflow" readonly="issue_state not in ['draft', 'cancel']"/>-->
|
||||
<!-- <field name="topic_content" invisible="is_invisible_workflow" readonly="issue_state not in ['draft', 'cancel']"/>-->
|
||||
<!-- <field name="handling_situation" string="办理情况(存在问题)" readonly="issue_state not in ['draft', 'cancel']"/>-->
|
||||
<!-- <field name="deliberation_content" readonly="issue_state not in ['draft', 'cancel']"/>-->
|
||||
<!-- <field name="will_based" readonly="issue_state not in ['draft', 'cancel']"/>-->
|
||||
<field name="is_legal_trial" readonly="issue_state not in ['draft', 'cancel']"/>
|
||||
<field name="department_personnel_ids" widget="many2many_tags" invisible="1"/>
|
||||
<field name="workflow_id" invisible="is_legal_trial == 'no'" domain="[('res_model', '=', 'contract.review.approval'), ('create_uid', 'in', department_personnel_ids)]" readonly="issue_state not in ['draft', 'cancel']"/>
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
<field name="host"/>
|
||||
<field name="room_users_ids" widget="many2many_tags"/>
|
||||
<field name="meeting_date"/>
|
||||
<field name="meeting_type_id"/>
|
||||
<field name="number_of_meetings"/>
|
||||
<field name="meeting_resolution"/>
|
||||
</group>
|
||||
<group>
|
||||
|
||||
@@ -81,6 +81,7 @@ class YuthonOfficial(models.Model):
|
||||
sub_id = self.env['yuthon.sub.enterprises'].create({
|
||||
'name': self.name,
|
||||
'users_id': self.users_id.id,
|
||||
'state': '申请人',
|
||||
'code': self.env['ir.sequence'].next_by_code('sub_enterprises_code'),
|
||||
'official_partner_id': official_partner_id.id,
|
||||
'issuance_process_id': self.id,
|
||||
|
||||
@@ -84,6 +84,9 @@
|
||||
<group>
|
||||
<field name="document_ids" string="附件" widget="preview_many2many"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="document_ids" string="附件" widget="preview_many2many"/>
|
||||
</group>
|
||||
<notebook string="采购明细" >
|
||||
<page string="固定资产明细" invisible="purchase_type != 'fixed'">
|
||||
<field name="fixed_line_ids">
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import models
|
||||
from . import wizard
|
||||
from . import wizard
|
||||
from . import controllers
|
||||
@@ -0,0 +1 @@
|
||||
from . import salary_phone
|
||||
@@ -0,0 +1,52 @@
|
||||
import base64
|
||||
import json
|
||||
from odoo import http, fields
|
||||
from odoo.http import request
|
||||
from urllib.parse import quote
|
||||
|
||||
|
||||
class YuthonWillTask(http.Controller):
|
||||
|
||||
@http.route('/party/list', methods=['POST'], type='http', auth='public', csrf=False)
|
||||
def party_list(self, **kwargs):
|
||||
party_ids = request.env['yuthon.salary.party'].sudo().search([('employee_id.id', '=', kwargs.get('employee_id'))])
|
||||
data_list = []
|
||||
for party in party_ids:
|
||||
result = {
|
||||
'id': party.id,
|
||||
'select_year': party.select_year,
|
||||
'select_time': party.select_time,
|
||||
'fee': party.fee,
|
||||
'payment': party.payment,
|
||||
'total_payment': party.total_payment,
|
||||
'toll_state': party.toll_state,
|
||||
}
|
||||
data_list.append(result)
|
||||
return json.dumps({'data': data_list, 'code': 200, 'message': 'success'})
|
||||
|
||||
@http.route('/party/list/confirm', methods=['POST'], type='http', auth='public', csrf=False)
|
||||
def meal_list_confirm(self, **kwargs):
|
||||
meal_id = request.env['yuthon.salary.party'].sudo().search([('id', '=', kwargs.get('id'))])
|
||||
meal_id.write({'toll_state': 'True'})
|
||||
|
||||
@http.route('/meal/list', methods=['POST'], type='http', auth='public', csrf=False)
|
||||
def meal_list(self, **kwargs):
|
||||
meal_ids = request.env['yuthon.meal.expenses'].sudo().search([('employee_id.id', '=', kwargs.get('employee_id'))])
|
||||
data_list = []
|
||||
for meal in meal_ids:
|
||||
result = {
|
||||
'id': meal.id,
|
||||
'select_year': meal.select_year,
|
||||
'select_time': meal.select_time,
|
||||
'number_breakfasts': meal.number_breakfasts,
|
||||
'number_lunches': meal.number_lunches,
|
||||
'total_payment': meal.total_payment,
|
||||
'toll_state': meal.toll_state,
|
||||
}
|
||||
data_list.append(result)
|
||||
return json.dumps({'data': data_list, 'code': 200, 'message': 'success'})
|
||||
|
||||
@http.route('/meal/list/confirm', methods=['POST'], type='http', auth='public', csrf=False)
|
||||
def meal_list_confirm(self, **kwargs):
|
||||
meal_id = request.env['yuthon.meal.expenses'].sudo().search([('id', '=', kwargs.get('id'))])
|
||||
meal_id.write({'toll_state': 'True'})
|
||||
@@ -4,7 +4,7 @@ from datetime import datetime
|
||||
|
||||
class YuthonSalaryParty(models.Model):
|
||||
_name = 'yuthon.salary.party'
|
||||
_description = '党建'
|
||||
_description = '党费'
|
||||
|
||||
employee_id = fields.Many2one('hr.employee', string='姓名')
|
||||
card = fields.Char(string='身份证')
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<field name="name">yuthon.salary.party.tree</field>
|
||||
<field name="model">yuthon.salary.party</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="党建" editable="bottom" js_class="custom_party_button">
|
||||
<tree string="党费" editable="bottom" js_class="custom_party_button">
|
||||
<field name="select_time"/>
|
||||
<field name="select_year"/>
|
||||
<field name="employee_id"/>
|
||||
@@ -22,10 +22,10 @@
|
||||
<field name="name">yuthon.my.salary.party.tree</field>
|
||||
<field name="model">yuthon.salary.party</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="党建" editable="bottom">
|
||||
<tree string="党费" editable="bottom">
|
||||
<field name="select_time"/>
|
||||
<field name="select_year"/>
|
||||
<field name="employee_id" column_invisible="1"/>
|
||||
<field name="employee_id"/>
|
||||
<field name="fee"/>
|
||||
<field name="payment"/>
|
||||
<field name="total_payment"/>
|
||||
@@ -36,14 +36,14 @@
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_yuthon_salary_party_action" model="ir.actions.act_window">
|
||||
<field name="name">党建</field>
|
||||
<field name="name">党费</field>
|
||||
<field name="res_model">yuthon.salary.party</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_ids" eval="[(5, 0, 0),
|
||||
(0, 0, {'view_mode': 'tree', 'view_id': ref('yuthon_salary.view_yuthon_salary_party_tree')})]"/>
|
||||
</record>
|
||||
<record id="view_my_yuthon_salary_party_action" model="ir.actions.act_window">
|
||||
<field name="name">党建</field>
|
||||
<field name="name">党费</field>
|
||||
<field name="res_model">yuthon.salary.party</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="domain">[('employee_id.user_id', '=', uid)]</field>
|
||||
|
||||
@@ -52,9 +52,12 @@
|
||||
<field name="name"/>
|
||||
<field name="information_categories_ids" widget="many2many_tags" options="{'no_create': True}"/>
|
||||
<field name="text"/>
|
||||
<field name="documents_ids" widget="preview_many2many"/>
|
||||
<!-- <field name="documents_ids" widget="preview_many2many"/>-->
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<field name="documents_ids" widget="preview_many2many"/>
|
||||
</group>
|
||||
<group string="发布设置">
|
||||
<group>
|
||||
<field name="publish_ids" widget="many2many_tags" options="{'no_create': True}"/>
|
||||
|
||||
Reference in New Issue
Block a user