Merge pull request !161 from 李鹏宇/dev
This commit is contained in:
李鹏宇
2024-08-26 01:44:03 +00:00
committed by Gitee
23 changed files with 160 additions and 127 deletions
+1
View File
@@ -16,6 +16,7 @@
'views/room_menus.xml',
'views/room_booking_templates_frontend.xml',
'views/room_office_views.xml',
'views/webclient_templates.xml',
'data/ir_module_category_data.xml',
'security/ir_rule.xml',
'security/ir.model.access.csv',
+1
View File
@@ -2,3 +2,4 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import main
from . import main_room_yuthon
-1
View File
@@ -14,6 +14,5 @@
<field name="numbercall">-1</field>
<field eval="False" name="doall"/>
</record>
</data>
</odoo>
+3 -17
View File
@@ -81,6 +81,7 @@ class RoomBooking(models.Model):
'name': _("签到二维码"),
'res_model': 'room.booking.sign.wizard',
'views': [(False, 'form')],
'target': 'new',
'context': {
'default_qrcode_image': qrcode_image,
}
@@ -97,23 +98,8 @@ class RoomBooking(models.Model):
if attendee.get("userid", ""):
user_obj = self.sudo().env["res_users"].search([("oauth_uid", '=', attendee.get("userid", ""))])
for obj in user_obj:
sign_obj = self.sudo().env["res_users"].search([("sign_user_id", '=', obj.id), ("room_booking_id", "=", record.id)])
if sign_obj:
sign_obj.write({
"room_booking_id": record.id,
"sign_user_id": obj.id,
"sign_user_name": obj.name,
"user_type": "insiders",
"sign_type": 'yes'
})
else:
self.env["room.meeting.sign"].sudo().create({
"room_booking_id": record.id,
"sign_user_id": obj.id,
"sign_user_name": obj.name,
"user_type": "insiders",
"sign_type": 'yes'
})
sign_obj = self.sudo().env["room.meeting.sign"].search([("sign_user_id", '=', obj.id), ("room_booking_id", "=", record.id)])
sign_obj.write({"sign_type": 'yes'})
@api.constrains("start_datetime", "stop_datetime")
def _check_date_boundaries(self):
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="website_form_room.frontend_layout" name="Frontend Layout" inherit_id="web.layout" primary="True">
<template id="room.frontend_layout" name="Frontend Layout" inherit_id="web.layout" primary="True">
<xpath expr="//head/meta[last()]" position="after">
<meta name="viewport" content="width=device-width, initial-scale=1"/>
</xpath>
@@ -38,8 +38,8 @@
</xpath>
</template>
<template id="website_form_room.website_form_room" name="website form room">
<t t-call="website_form_room.frontend_layout">
<template id="room.room" name="website form room">
<t t-call="room.frontend_layout">
<div class="container py-5">
<form class="oe_website_form_room" role="form" t-attf-action="/web/room" method="post" onsubmit="this.action = '/web/room' + location.hash">
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
+2 -2
View File
@@ -5,9 +5,9 @@
<field name="model">room.booking.sign.wizard</field>
<field name="arch" type="xml">
<form create="false" edit="false" delete="false">
<group>
<div class="col-12 text-center">
<field name="qrcode_image" widget="image" readonly="1"/>
</group>
</div>
</form>
</field>
</record>
+61 -6
View File
@@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
import logging
import datetime
from odoo import models, fields, api, _, modules
from odoo.exceptions import ValidationError, UserError
import logging
_logger = logging.getLogger(__name__)
@@ -34,7 +35,7 @@ class SoongWorkflow(models.Model):
_sql_constraints = [
("uniq_name", "unique(name)", _("Workflow name must be unique.")),
("uniq_model", "unique(model_id)", _("Model must be unique.")),
# ("uniq_model", "unique(model_id)", _("Model must be unique.")),
]
name = fields.Char(string="Name", help="Give workflow a name.")
@@ -44,13 +45,67 @@ class SoongWorkflow(models.Model):
remove_default_attrs_mod = fields.Boolean(string="Remove Default Attributes & Modifiers", default=True,
help="This option will remove default attributes set on fields & buttons of current model view in order to customized all attributes depending on your needs\nAttributes like: [required, readonly, invisible].")
current_stage_highlight_color = fields.Char(default="rgb(0, 255, 255)", help="The color to highlight the current stage on flow",)
start_time = fields.Datetime(string="Start Time", copy=False)
end_time = fields.Datetime(string="End Time", copy=False)
is_enable = fields.Boolean(string="Enable", default="False", compute="compute_is_enable", store=True)
def copy(self, default=None):
workflow_id = self.search([('model_id', '=', self.model_id.id)])
workflow_version = len(workflow_id) + 1
default = dict(default or {})
default['name'] = ''
default['model_id'] = False
# [0,0...]
return super(SoongWorkflow, self).copy(default)
default.update({
'name': self.name + '-v' + str(workflow_version),
'model_id': False,
'remove_default_attrs_mod': self.remove_default_attrs_mod,
'current_stage_highlight_color': self.current_stage_highlight_color,
})
res = super(SoongWorkflow, self).copy(default)
node_dict = dict()
button_dict = dict()
# 复制节点
for node_id in self.node_ids:
new_noode_id = node_id.copy({
'workflow_id': res.id
})
node_dict[node_id.id] = new_noode_id.id
# 复制节点-按钮
for button_id in node_id.button_ids:
new_button_id = button_id.copy({
'node_id': new_noode_id.id,
'link_id': False
})
if button_id.link_id:
if button_id.link_id.id in button_dict:
button_dict[button_id.link_id.id] |= new_button_id
else:
button_dict[button_id.link_id.id] = new_button_id
# 复制节点-字段
for field_id in node_id.field_ids:
field_id.copy({
'node_id': new_noode_id.id,
})
# 复制链接
for link_id in self.link_ids:
new_link_id = link_id.copy({
'workflow_id': res.id,
'node_from': node_dict[link_id.node_from.id],
'node_to': node_dict[link_id.node_to.id]
})
if link_id.id in button_dict:
for new_button_id in button_dict[link_id.id]:
new_button_id.link_id = new_link_id.id
return res
@api.depends('start_time', 'end_time')
def compute_is_enable(self):
for rec in self:
if rec.start_time and rec.end_time:
if rec.start_time < datetime.datetime.now() and rec.end_time > datetime.datetime.now():
rec.is_enable = True
else:
rec.is_enable = False
else:
rec.is_enable = False
@api.constrains("node_ids")
def validate_nodes(self):
@@ -190,7 +190,7 @@ class SoongWorkflowMixin(models.AbstractModel):
# Variables
model = self._name
wkf_obj = self.env["soong.workflow"]
wkf_rec = wkf_obj.search([("model_id", "=", model)])
wkf_rec = wkf_obj.search([("model_id", "=", model), ('is_enable', '=', True)])
arch = etree.fromstring(res["arch"])
# Validation
@@ -26,6 +26,11 @@
<field name="model_id" required="1" options="{'no_open': True, 'no_create': True}"/>
<field name="current_stage_highlight_color" widget="color"/>
</group>
<group>
<field name="start_time"/>
<field name="end_time"/>
<field name="is_enable"/>
</group>
<div>
<div>
<label for="remove_default_attrs_mod"/>
@@ -55,6 +60,9 @@
<field name="name"/>
<field name="model_id"/>
<field name="remove_default_attrs_mod"/>
<field name="start_time"/>
<field name="end_time"/>
<field name="is_enable"/>
</tree>
</field>
</record>
-1
View File
@@ -1 +0,0 @@
from . import controllers
-11
View File
@@ -1,11 +0,0 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': '会议表单',
'version': '17.0',
'depends': ['web', 'room'],
'data': [
'views/webclient_templates.xml',
],
}
@@ -1 +0,0 @@
from . import main
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

+2 -2
View File
@@ -15,11 +15,11 @@
'security/ir.model.access.csv',
# 'data/notice_code_data.xml',
'data/project_state_type_data.xml',
'views/inherit_project_task_views.xml',
'data/notice_cron_data.xml',
# 'views/inherit_project_task_views.xml',
'views/yuthon_notice_views.xml',
'views/yuthon_notice_type_views.xml',
'views/yuthon_confirm_users_views.xml',
'report/notice_report.xml',
],
'installable': True,
'application': True,
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<data noupdate="1">
<!-- 定时任务: 每天提醒一次 -->
<record forcecreate="True" id="ir_cron_yuthon_confirm_users" model="ir.cron">
<field name="name">公告未确认通知</field>
<field name="model_id" ref="model_yuthon_confirm_users"/>
<field name="state">code</field>
<field name="code">model.sync_confirm_users_notices()</field>
<field eval="False" name="active"/>
<field name="user_id" ref="base.user_root"/>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall"/>
</record>
</data>
</odoo>
+1 -1
View File
@@ -3,5 +3,5 @@
from . import yuthon_notice
from . import yuthon_notice_type
from . import yuthon_confirm_users
from . import inherit_project_task
# from . import inherit_project_task
+19 -20
View File
@@ -1,12 +1,11 @@
# -*- coding: utf-8 -*-
from odoo import api, fields, models, tools
from odoo.exceptions import UserError, ValidationError
class YuthonConfirmUsers(models.Model):
_name = "yuthon.confirm.users"
_description = "公告确认信息"
# todo 定时任务给未确认的用户发送通知公告
# todo 打印
employee_id = fields.Many2one('hr.employee', string='员工')
notice_id = fields.Many2one('yuthon.notice', string="公告名称")
@@ -14,22 +13,22 @@ class YuthonConfirmUsers(models.Model):
notice_name = fields.Char(string="公告名称")
state = fields.Selection([('no', '未确认'), ('yes', '已确认')], string="状态")
# @api.model_create_multi
# def create(self, vals_list):
# notice_name = vals_list[0]['notice_name']
# message_body = f"您有一条新的公告确认请求:{notice_name}。请登录系统查看详情。"
# user_id_list = []
# for val in vals_list:
# if 'user_id' in val:
# user_id_list.append(val['user_id'])
# partner_ids = self.sudo().env['res.users'].search([('id', 'in', user_id_list)]).mapped('partner_id').ids
# partner_ids = self.env['res.partner'].search([('user_id', 'in', user_id_list)]).ids
# self.message_post(
# body=message_body,
# subject="公告确认提醒",
# partner_ids=[partner_id.id], # 收件人的伙伴ID
# message_type='notification',
# )
# self.sudo().with_context(lang=self.env.lang)._message_auto_subscribe_notify(partner_ids, 'yuthon_notice.message_yuthon_confirm_users_data')
# return super().create(vals_list)
def sync_confirm_users_notices(self):
menu_id = self.env['ir.ui.menu'].search([('name', '=', '我的通知公告')])
for record in self.search([('state', '=', 'no')]):
str = 'https://www.thtzjt.com/web#id={}&cids=1&menu_id={}&action={}&model=yuthon.notice&view_type=form'.format(
record.notice_id.id, menu_id.id, menu_id.action.id)
data = "您有待确认的通知公告请确认\n" + "<a href=\"{}\">{}</a>".format(str, self.name)
record.sudo().env["wecom.apps"].sync_send_message(record.employee_id.wecom_userid, data)
def reminders_notice(self):
for rem in self:
if rem.state == 'yes':
raise UserError('已确认不可催办')
confirm_noice_ids = self.env["yuthon.confirm.users"].browse(self._context.get('active_ids', self._context.get('active_id')))
for rec in confirm_noice_ids:
menu_id = self.env['ir.ui.menu'].search([('name', '=', '我的通知公告')])
str = 'https://www.thtzjt.com/web#id={}&cids=1&menu_id={}&action={}&model=yuthon.notice&view_type=form'.format(
rec.notice_id.id, menu_id.id, menu_id.action.id)
data = "您有待确认的通知公告请尽快确认\n" + "<a href=\"{}\">{}</a>".format(str, rec.notice_id.name)
rec.sudo().env["wecom.apps"].sync_send_message(rec.employee_id.wecom_userid, data)
+11 -9
View File
@@ -13,10 +13,11 @@ class YuthonNotice(models.Model):
name = fields.Char(string='通知公告标题')
code = fields.Char(string="编号", default=lambda self: self.env['ir.sequence'].next_by_code('notice_code'))
user_id = fields.Many2one('res.users', string="创建人", default=lambda self: self.env.user)
department_id = fields.Many2one(related='user_id.employee_id.department_id', string="创建人部门")
department_id = fields.Many2one(related='user_id.employee_id.department_id', string="部门")
department_ids = fields.Many2many('hr.department', string='部门范围')
employee_ids = fields.Many2many('hr.employee', string='人员范围')
users_role_ids = fields.Many2many('soong.user.role', string='角色范围')
company_page = fields.Selection([('tz', '天河投资'), ('wg', '天河物管'), ('lc', '粮储')], string="公司", compute='_compute_company_page', store=True)
notice_type_id = fields.Many2one('yuthon.notice.type', string="公告类型")
create_date = fields.Date(string="发布日期")
start_date = fields.Date(string="生效日期")
@@ -28,6 +29,9 @@ class YuthonNotice(models.Model):
is_notice_roger = fields.Selection([('yes', '已读'), ('no', '未读')], default='no', string="确认状态")
is_change_notice = fields.Boolean(string="是否发送通知", default=True)
notice_text = fields.Html(string="正文")
read_number = fields.Integer(string='阅读量')
approval_user_id = fields.Many2one('res.users', string="审核人")
approval_date = fields.Datetime(string="审核日期")
@api.onchange('is_notice_roger')
def onchange_is_notice_roger(self):
@@ -72,14 +76,12 @@ class YuthonNotice(models.Model):
data = "您有新的通知公告请及时确认\n" + "<a href=\"{}\">{}</a>".format(str, self.name)
we_id = self.env['hr.employee'].search([('id', '=', user)]).wecom_userid
self.sudo().env["wecom.apps"].sync_send_message(we_id, data)
# 待办关联
self.env['project.task'].create({
'name': '新的通知公告' + self.name + "请及时确认",
'user_ids': [(4, user)],
'notice_origin_id': self.id,
})
# # 待办关联
# self.env['project.task'].create({
# 'name': '新的通知公告' + self.name + "请及时确认",
# 'user_ids': [(4, user)],
# 'notice_origin_id': self.id,
# })
# 普通用户权限是否打开,可能需要配置权限
# 关联待办和不关联待办
-31
View File
@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="yuthon_notice_report_actions" model="ir.actions.report">
<field name="name">通知公告打印</field>
<field name="model">yuthon.notice</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">yuthon_notice.yuthon_notice_report_template</field>
<field name="report_file">yuthon_notice.yuthon_notice_report_template</field>
<field name="print_report_name">'%s' % (object.name).replace('/', '')</field>
<field name="binding_model_id" ref="model_yuthon_notice"/>
<!-- <field name="binding_model_id" eval="False"/>-->
<field name="binding_type">report</field>
</record>
<template id="yuthon_notice_report_template">
<t t-call="web.basic_layout" t-foreach="docs" t-as="doc">
<div class="page">
<h2 style="text-align:center;">
<storng>
<t t-esc="doc.name"/>
</storng>
</h2>
</div>
<table width="100%" style="table-layout:fixed;">
<tr colspan="7" rowspan="2">
<t t-esc="doc.notice_text"/>
</tr>
</table>
</t>
</template>
</odoo>
@@ -4,7 +4,11 @@
<field name="name">yuthon.confirm.users.tree</field>
<field name="model">yuthon.confirm.users</field>
<field name="arch" type="xml">
<tree create="false" edit="false" delete="false" string="公告确认信息" editable="bottom">
<tree create="false" edit="false" string="公告确认信息" editable="bottom">
<header>
<button class="oe_stat_button" name="reminders_notice" string="批量催办" type="object"
icon="fa-bars"/>
</header>
<field name="employee_id"/>
<field name="notice_id"/>
<field name="notice_code"/>
+23 -19
View File
@@ -7,13 +7,16 @@
<tree string="公告管理">
<field name="name"/>
<field name="user_id"/>
<field name="department_id"/>
<field name="notice_type_id"/>
<field name="company_page"/>
<field name="create_date"/>
<field name="start_date"/>
<field name="end_date"/>
<field name="statu"/>
<button name="on_sequence" string="置顶" invisible="sequence != 0" type="object" class="btn-primary"/>
<button name="no_sequence" string="取消置顶" invisible="sequence != 1" type="object" class="btn-primary"/>
<button name="no_sequence" string="取消置顶" invisible="sequence != 1" type="object"
class="btn-primary"/>
<button name="stop_notice" string="终止" type="object" class="btn-primary"/>
<field name="sequence" column_invisible="1"/>
</tree>
@@ -26,8 +29,10 @@
<field name="arch" type="xml">
<form string="公告管理">
<header>
<button name="look_up_notice_users" string="查看确认信息" invisible="statu != 'yes'" type="object" class="btn-primary"/>
<button name="notice_publish" string="发布" invisible="statu not in ['yes', 'done']" type="object" class="btn-primary"/>
<button name="look_up_notice_users" string="查看确认信息" invisible="statu != 'yes'" type="object"
class="btn-primary"/>
<button name="notice_publish" string="发布" invisible="statu not in ['yes', 'done']" type="object"
class="btn-primary"/>
<field name="statu" widget="statusbar"/>
</header>
<sheet>
@@ -42,6 +47,7 @@
<field name="code"/>
<field name="user_id"/>
<field name="department_id"/>
<field name="company_page"/>
<field name="department_ids" widget="many2many_tags"/>
<field name="employee_ids" widget="many2many_tags"/>
<field name="users_role_ids" widget="many2many_tags"/>
@@ -108,6 +114,7 @@
<tree string="公告管理" create="false" edit="false" delete="false">
<field name="name"/>
<field name="user_id"/>
<field name="department_id"/>
<field name="notice_type_id"/>
<field name="create_date"/>
<field name="start_date"/>
@@ -128,31 +135,28 @@
<field name="name" required="1"/>
</h1>
</div>
<group>
<group col="3">
<group>
<field name="code"/>
<field name="user_id"/>
<field name="department_id"/>
<field name="department_ids" widget="many2many_tags"/>
<field name="employee_ids" widget="many2many_tags"/>
<field name="users_role_ids" widget="many2many_tags"/>
<field name="notice_type_id"/>
<field name="is_notice_roger"/>
<field name="department_id"/>
</group>
<group>
<field name="user_id"/>
<field name="read_number"/>
</group>
<group>
<field name="approval_user_id"/>
<field name="approval_date"/>
<field name="create_date"/>
<field name="start_date"/>
<field name="end_date"/>
<field name="notice_documents_ids">
<tree>
<field name="name"/>
</tree>
</field>
</group>
</group>
<group>
<field name="notice_text" widget="tinymce"/>
<field name="sequence" invisible="1"/>
<field name="notice_documents_ids">
<tree>
<field name="name"/>
</tree>
</field>
</group>
</form>
</field>
+1 -1
View File
@@ -39,7 +39,7 @@ def rsaDecrypt(str1):
return con
str1 = rsaEncrypt("base#2030-04-18 23:59:59")
str1 = rsaEncrypt("base#2050-09-18 23:59:59")
print("加密后密文:\n%s" % str1)
# content = rsaDecrypt('16E01254F15E539CF5B734A9A6FB3649640709796F06F5167CB5BFE542210596CE920CBFDB5E22E863983682DC326C421EF896A9D8E2CAC6B9226E89F502FDD7')
# print("解密后明文:\n%s" % content)