pengyuthon
@@ -0,0 +1 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
@@ -0,0 +1,37 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
{
|
||||
'name': "funenc_json_widget",
|
||||
|
||||
'summary': """
|
||||
json widget for odoo
|
||||
""",
|
||||
|
||||
'description': """
|
||||
json widget for odoo
|
||||
json
|
||||
template widget
|
||||
template
|
||||
color widget
|
||||
color
|
||||
""",
|
||||
|
||||
'author': "Funenc",
|
||||
'website': "http://odoo.funenc.com",
|
||||
"images": [
|
||||
"static/description/description.gif"
|
||||
],
|
||||
|
||||
'category': 'App/json',
|
||||
'version': '17.0.0.1',
|
||||
'price': 5,
|
||||
'license': 'OPL-1',
|
||||
|
||||
'depends': ['base', 'web'],
|
||||
'data': [],
|
||||
|
||||
'assets': {
|
||||
'web.assets_backend': [
|
||||
'funenc_json_widget/static/src/json_widget.js',
|
||||
]
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 274 KiB |
|
After Width: | Height: | Size: 550 KiB |
|
After Width: | Height: | Size: 160 KiB |
|
After Width: | Height: | Size: 686 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 63 KiB |
@@ -0,0 +1,67 @@
|
||||
<div class="container">
|
||||
|
||||
<div class="oe_styling_v8">
|
||||
<div class="shadow row my-5 p-3 pb-2 overflow-hidden">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<p style="width: 100%; font-size: 18px; text-indent:1em;" class="px-sm-4 p-2">
|
||||
This is a json widget for odoo!!! it used to format json data to html.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 class="w-100 text-center mb-3">(Current Release V15.0.0.1 -- 2022.08.09)</h2>
|
||||
|
||||
<div class="shadow row my-5 p-3 pb-2 overflow-hidden">
|
||||
<img src="./description.gif" style="width:100%; " />
|
||||
</div>
|
||||
|
||||
<div class="shadow row my-5 p-3 pb-2 overflow-hidden" style="background-color:#fbfcfd; border-radius: 5px; border: 1px solid #d2caca66;">
|
||||
<div class="container">
|
||||
<h3 style="opacity:1; padding:10px 0px; color:#201111; letter-spacing:0.2em;">
|
||||
<b>Our Other Apps</b>
|
||||
</h3>
|
||||
<hr class="mb-4 mt-0">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div style="text-align:center; border:1px solid #aaa">
|
||||
<div class="sh_img" style="padding:10px">
|
||||
<a href="https://apps.odoo.com/apps/themes/15.0/awesome_theme_pro/">
|
||||
<img src="https://apps.odoocdn.com/apps/assets/15.0/awesome_theme_pro/pwa.gif?d01ce2b" style="width:100%">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div style="text-align:center; border:1px solid #aaa">
|
||||
<div class="sh_img" style="padding:10px">
|
||||
<a href="https://apps.odoo.com/apps/modules/14.0/anita_modeler/">
|
||||
<img src="https://apps.odoocdn.com/apps/assets/15.0/anita_modeler/description.gif?2245b0c" style="width:100%">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div style="text-align:center; border:1px solid #aaa">
|
||||
<div class="sh_img" style="padding:10px">
|
||||
<a href="https://apps.odoo.com/apps/modules/15.0/anita_list/">
|
||||
<img src="https://apps.odoocdn.com/apps/assets/15.0/anita_list/description.gif?fdda9e6" style="width:100%">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div style="text-align:center; border:1px solid #aaa">
|
||||
<div class="sh_img" style="padding:10px">
|
||||
<a href="https://apps.odoo.com/apps/modules/15.0/anita_socketio/">
|
||||
<img src="https://apps.odoocdn.com/apps/assets/15.0/anita_socketio/description.gif?ba46791" style="width:100%">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,57 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { registry } from "@web/core/registry";
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
import { standardFieldProps } from "@web/views/fields/standard_field_props";
|
||||
import { Component, xml } from "@odoo/owl";
|
||||
|
||||
export class JsonTemplateWidget extends Component {
|
||||
|
||||
static template = xml`
|
||||
<div>
|
||||
<t t-call="{{get_template_id()}}" />
|
||||
</div>`
|
||||
|
||||
static props = {
|
||||
...standardFieldProps,
|
||||
};
|
||||
|
||||
setup() {
|
||||
console.log(this)
|
||||
}
|
||||
|
||||
get isReadonly() {
|
||||
return true;
|
||||
}
|
||||
|
||||
get_template_id() {
|
||||
if (!this.template_id) {
|
||||
try {
|
||||
debugger
|
||||
let name = this.props.name;
|
||||
let data = this.props.record.data;
|
||||
let value = data[name] || "{}"
|
||||
this.value = JSON.parse(value);
|
||||
if (!this.value || !this.value.template) {
|
||||
this.template_id = xml`<t t-esc="value" />`;
|
||||
} else {
|
||||
this.template_id = this.value.template;
|
||||
}
|
||||
} catch (e) {
|
||||
this.template_id = xml`${e.message}`;
|
||||
}
|
||||
}
|
||||
return this.template_id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const JsonTemplateField = {
|
||||
component: JsonTemplateWidget,
|
||||
displayName: _t("Json Template"),
|
||||
supportedTypes: ["char", "text"],
|
||||
isEmpty: () => false
|
||||
};
|
||||
|
||||
registry.category("fields").add("json_template", JsonTemplateField);
|
||||
@@ -11,33 +11,34 @@
|
||||
'author': 'zxltwins<email:444713077@qq.com>',
|
||||
'website': "www.odoo.com",
|
||||
'version': '17.0',
|
||||
"depends": ["base", 'sale'],
|
||||
"depends": ["base",'sale'],
|
||||
"external_dependencies": {"python": ["mammoth"]},
|
||||
"data": [
|
||||
'security/ir.model.access.csv',
|
||||
'views/preview.xml'],
|
||||
'assets': {
|
||||
'web._assets_primary_variables': [
|
||||
'web._assets_primary_variables': [
|
||||
|
||||
],
|
||||
'web.assets_backend': [
|
||||
'preview_easy/static/src/js/qweb.js',
|
||||
'preview_easy/static/src/xml/qweb.xml'
|
||||
],
|
||||
'web.assets_frontend': [
|
||||
],
|
||||
'web.assets_backend': [
|
||||
'preview_easy/static/src/js/qweb.js',
|
||||
'preview_easy/static/src/xml/qweb.xml'
|
||||
],
|
||||
'web.assets_frontend': [
|
||||
|
||||
],
|
||||
'web.assets_tests': [
|
||||
|
||||
],
|
||||
],
|
||||
'web.assets_tests': [
|
||||
|
||||
'web.report_assets_common': [
|
||||
],
|
||||
|
||||
],
|
||||
'web.report_assets_pdf': [
|
||||
'web.report_assets_common': [
|
||||
|
||||
],
|
||||
},
|
||||
],
|
||||
'web.report_assets_pdf': [
|
||||
|
||||
],
|
||||
},
|
||||
|
||||
'images': [
|
||||
'static/description/main_screenshot.png',
|
||||
|
||||
@@ -10,16 +10,14 @@ import mammoth
|
||||
|
||||
|
||||
class preview(http.Controller):
|
||||
|
||||
@http.route('/web/content/preview/<int:id>', type='http', method=['Get'], auth="user")
|
||||
@http.route('/web/content/preview/<int:id>', type='http', method=['Get'], auth="public")
|
||||
def content_preview(self, id=None):
|
||||
ir_attach = request.env['ir.attachment'].sudo()
|
||||
attach = ir_attach.browse(id)
|
||||
image = ['image/jpeg', 'image/png', 'image/bmp', 'image/gif', 'image/jpg', 'image/svg']
|
||||
html = ['text/html']
|
||||
video = ['video/mp4', 'video/webm', 'video/wmv', 'video/asf', 'video/divx', 'video/rm', 'video/mkv',
|
||||
'video/flv', 'video/3gp',
|
||||
'video/wma', 'video/wav', 'video/ape', 'video/mpeg', 'video/mpg']
|
||||
'video/flv', 'video/3gp', 'video/wma', 'video/wav', 'video/ape', 'video/mpeg', 'video/mpg']
|
||||
pdf = ['application/pdf']
|
||||
txt = ['text/plain']
|
||||
excel = ['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.ms-excel']
|
||||
@@ -36,23 +34,25 @@ class preview(http.Controller):
|
||||
html = result.value
|
||||
return template.render(html=html)
|
||||
elif attach.mimetype in excel:
|
||||
# base_url = env['ir.config_parameter'].sudo().get_param('web.base.url')
|
||||
# base_url = request.env['ir.config_parameter'].sudo().get_param('web.base.url')
|
||||
# env.cr.dbname
|
||||
# html = "https://view.officeapps.live.com/op/view.aspx?src=" + "https://pengyuthon.com" + "/web/content/" + id
|
||||
html = "https://view.officeapps.live.com/op/view.aspx?src=" + "http://youthpower.ltd/blogger_lib_admin/test.xlsx"
|
||||
# /web/content/ir.attachment/2/datas?download = true 这个是下载
|
||||
url_login = "https://pengyuthon.com/web/content/ir.attachment/" + str(id) + '/datas'
|
||||
url = "https://pengyuthon.com/web/content/preview/" + str(id) + "/"
|
||||
html = "https://view.officeapps.live.com/op/view.aspx?src=" + url
|
||||
# html = "https://view.officeapps.live.com/op/view.aspx?src=" + "http://youthpower.ltd/blogger_lib_admin/test.xlsx"
|
||||
return werkzeug.wrappers.Response(f"""
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
|
||||
<title></title>
|
||||
</head>
|
||||
<body onLoad="parent.location='{html}'">
|
||||
</body>
|
||||
</html>
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
|
||||
<title></title>
|
||||
</head>
|
||||
<body onLoad="parent.location='{html}'">
|
||||
</body>
|
||||
</html>
|
||||
""", status=200, headers=[('Content-Type', 'text/html'), ('charset', 'utf-8')])
|
||||
|
||||
else:
|
||||
return werkzeug.wrappers.Response('This format is not currently supported', status=200, headers=[('Content-Type', 'text/html'),('charset','utf-8')])
|
||||
|
||||
|
||||
@@ -6,19 +6,40 @@ import {standardFieldProps} from "@web/views/fields/standard_field_props";
|
||||
import { FileInput } from "@web/core/file_input/file_input";
|
||||
import { useX2ManyCrud } from "@web/views/fields/relational_utils";
|
||||
import { Component } from "@odoo/owl";
|
||||
import { TagsList } from "@web/core/tags_list/tags_list";
|
||||
import { Dialog } from "@web/core/dialog/dialog";
|
||||
export class Many2ManyBinaryField extends Component {
|
||||
import {
|
||||
Many2XAutocomplete,
|
||||
useActiveActions,
|
||||
} from "@web/views/fields/relational_utils";
|
||||
import { Many2ManyTagsField, many2ManyTagsField } from "@web/views/fields/many2many_tags/many2many_tags_field";
|
||||
|
||||
export class Many2ManyBinaryField extends Many2ManyTagsField {
|
||||
static template = "web.Many2ManyBinaryField";
|
||||
static components = {
|
||||
FileInput,
|
||||
TagsList,
|
||||
Many2XAutocomplete,
|
||||
};
|
||||
static props = {
|
||||
...standardFieldProps,
|
||||
acceptedFileExtensions: { type: String, optional: true },
|
||||
className: { type: String, optional: true },
|
||||
canCreate: { type: Boolean, optional: true },
|
||||
canQuickCreate: { type: Boolean, optional: true },
|
||||
canCreateEdit: { type: Boolean, optional: true },
|
||||
colorField: { type: String, optional: true },
|
||||
createDomain: { type: [Array, Boolean], optional: true },
|
||||
domain: { type: [Array, Function], optional: true },
|
||||
context: { type: Object, optional: true },
|
||||
placeholder: { type: String, optional: true },
|
||||
nameCreateField: { type: String, optional: true },
|
||||
string: { type: String, optional: true },
|
||||
noSearchMore: { type: Boolean, optional: true },
|
||||
};
|
||||
|
||||
setup() {
|
||||
super.setup()
|
||||
this.orm = useService("orm");
|
||||
this.notification = useService("notification");
|
||||
this.operations = useX2ManyCrud(() => this.props.record.data[this.props.name], true);
|
||||
|
||||
@@ -2,10 +2,28 @@
|
||||
<t t-inherit="web.Many2ManyBinaryField" t-inherit-mode="extension" owl="1">
|
||||
<xpath expr="//div[hasclass('o_attachments')]" position="replace">
|
||||
<t t-foreach="files" t-as="file" t-key="file_index">
|
||||
<t t-call="Many2ManyBinaryField.attachment_preview1"/>
|
||||
</t>
|
||||
|
||||
|
||||
<t t-call="Many2ManyBinaryField.attachment_preview1"/>
|
||||
</t>
|
||||
</xpath>
|
||||
<xpath expr="//div[hasclass('oe_add')]" position="after">
|
||||
<!-- <button class="btn btn-secondary o_attach" t-on-click="onExternalBtnClick" data-tooltip="Attach">-->
|
||||
<!-- 选择文件-->
|
||||
<!-- </button>-->
|
||||
<Many2XAutocomplete
|
||||
id="props.id"
|
||||
placeholder="tags.length ? '' : props.placeholder"
|
||||
resModel="relation"
|
||||
autoSelect="true"
|
||||
fieldString="string"
|
||||
activeActions="activeActions"
|
||||
update="update"
|
||||
quickCreate="activeActions.create ? quickCreate : null"
|
||||
context="props.context"
|
||||
getDomain.bind="getDomain"
|
||||
isToMany="true"
|
||||
nameCreateField="props.nameCreateField"
|
||||
noSearchMore="props.noSearchMore"
|
||||
/>
|
||||
</xpath>
|
||||
</t>
|
||||
<t t-name="Many2ManyBinaryField.attachment_preview1" owl="1">
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='partner_id']" position="after">
|
||||
<field name="attachment_ids" widget="preview_many2many"/>
|
||||
<field name="attachment_ids" widget="many2many_tags"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -18,8 +18,8 @@ class RoomBooking(models.Model):
|
||||
name = fields.Char(string="名称", required=True, tracking=1)
|
||||
room_id = fields.Many2one("room.room", string="Room", required=True, ondelete="cascade",
|
||||
group_expand="_read_group_room_id", tracking=4)
|
||||
start_datetime = fields.Date(string="Start Datetime", required=True, tracking=2)
|
||||
stop_datetime = fields.Date(string="End Datetime", required=True, tracking=3)
|
||||
start_datetime = fields.Datetime(string="Start Datetime", required=True, tracking=2)
|
||||
stop_datetime = fields.Datetime(string="End Datetime", required=True, tracking=3)
|
||||
organizer_id = fields.Many2one("res.users", string="Organizer",
|
||||
default=lambda self: self.env.user.id if not self.env.user._is_public() else False,
|
||||
tracking=5)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
'category': 'Human Resources/Attendances',
|
||||
'version': '0.1',
|
||||
'license': 'LGPL-3',
|
||||
'depends': ['mail', 'base', 'documents', 'room','soong_workflow'],
|
||||
'depends': ['mail', 'base', 'documents', 'room', 'soong_workflow', 'funenc_json_widget'],
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
'data/issue_library_code_data.xml',
|
||||
@@ -24,7 +24,7 @@
|
||||
],
|
||||
'assets': {
|
||||
'web.assets_backend': [
|
||||
'yuthon_issue/static/xml/meeting.xml'
|
||||
'yuthon_issue/static/xml/issue_approval.xml'
|
||||
],
|
||||
},
|
||||
'installable': True,
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
import qrcode
|
||||
import base64
|
||||
from io import BytesIO
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import ValidationError, UserError
|
||||
import os
|
||||
from datetime import timedelta
|
||||
|
||||
|
||||
class InheritRoomBooking(models.Model):
|
||||
class RoomBooking(models.Model):
|
||||
_inherit = 'room.booking'
|
||||
|
||||
room_booking_library_ids = fields.One2many('issue.library', 'room_booking_id')
|
||||
@@ -16,7 +10,7 @@ class InheritRoomBooking(models.Model):
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
records = super(InheritRoomBooking, self).create(vals_list)
|
||||
records = super(RoomBooking, self).create(vals_list)
|
||||
for vals in vals_list:
|
||||
if vals['room_booking_library_ids']:
|
||||
for library_id in vals['room_booking_library_ids']:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from odoo import api, fields, models, tools
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
|
||||
from datetime import date, datetime, time
|
||||
|
||||
class IssueApproval(models.Model):
|
||||
_name = "issue.approval"
|
||||
@@ -9,7 +9,7 @@ class IssueApproval(models.Model):
|
||||
_inherit = ['soong.workflow.mixin']
|
||||
_rec_name = 'name'
|
||||
|
||||
name = fields.Char(string='标题',required=True)
|
||||
name = fields.Char(string='标题', required=True)
|
||||
code = fields.Char(string='编号', required=True, copy=False, default=lambda self: self.env['ir.sequence'].next_by_code('issue_approval_code'))
|
||||
yuthon_company = fields.Selection([('thtz', '天河投资集团'), ('thwg', '天河物管'),
|
||||
('thlc', '天河粮储'), ('tctj', '天投城建'),
|
||||
@@ -18,9 +18,6 @@ class IssueApproval(models.Model):
|
||||
department_id = fields.Many2one('hr.department', string="部门")
|
||||
create_time = fields.Date(string='创建日期', default=lambda self: fields.Date.today())
|
||||
user_id = fields.Many2one('res.users', string="经办人", default=lambda self: self.env.user)
|
||||
|
||||
agenda_items = fields.Char(string="议题事项", compute='_compute_agenda_items')
|
||||
decision_checklist = fields.Char(string="决策清单", compute='_compute_decision_checklist')
|
||||
meeting_details = fields.Char(string="会议详情")
|
||||
job_id = fields.Many2one('hr.job', string="岗位")
|
||||
is_attend = fields.Boolean(string="是否上会", default=True)
|
||||
@@ -28,17 +25,58 @@ class IssueApproval(models.Model):
|
||||
notice_documents_ids = fields.Many2many('ir.attachment', string='议题附件')
|
||||
approval_decision_id = fields.Many2one('issue.approval.decision', string="关联决策清单")
|
||||
|
||||
issue_library_ids = fields.One2many('issue.library', 'issue_approval_id', string="关联议题")
|
||||
approval_decision_ids = fields.One2many('issue.approval.decision', 'issue_approval_id', string="决策清单")
|
||||
room_approval_ids = fields.One2many('issue.approval.room.line', 'room_approval_id', string="会议详情明细行")
|
||||
issue_library_ids = fields.One2many('issue.library', 'issue_approval_id', string="关联议题", store=True)
|
||||
approval_decision_ids = fields.One2many('issue.approval.decision', 'issue_approval_id', string="决策清单", store=True)
|
||||
room_approval_ids = fields.One2many('issue.approval.room.line', 'room_approval_id', string="会议详情明细行", store=True)
|
||||
|
||||
issue_data = fields.Char(string="议题事项js")
|
||||
decision_data = fields.Char(string="决策清单js")
|
||||
meeting_data = fields.Char(string="会议详情js")
|
||||
|
||||
issue_display = fields.Char(string="议题事项", default='{"template": "yuthon_issue.html_issue_demo"}')
|
||||
decision_display = fields.Char(string="决策清单", default='{"template": "yuthon_issue.html_decision_demo"}')
|
||||
meeting_display = fields.Char(string="会议详情", default='{"template": "yuthon_issue.table_meet_demo"}')
|
||||
|
||||
is_parent_unit = fields.Boolean(string="上级单位", compute="_compute_is_parent_unit")
|
||||
|
||||
@api.depends('issue_library_ids')
|
||||
def _compute_agenda_items(self):
|
||||
for record in self:
|
||||
names = [item.name for item in record.issue_library_ids if item.name]
|
||||
record.agenda_items = '、'.join(names)
|
||||
def _compute_is_parent_unit(self):
|
||||
for line in self:
|
||||
line.is_parent_unit = bool(line.issue_library_ids.filtered('is_note'))
|
||||
|
||||
@api.onchange('issue_library_ids')
|
||||
def _onchange_issue_data(self):
|
||||
self.issue_data = ''
|
||||
names = []
|
||||
if self.issue_library_ids:
|
||||
for record in self.issue_library_ids:
|
||||
names += [item.name for item in record]
|
||||
self.issue_data += ';'.join(names)
|
||||
|
||||
@api.onchange('approval_decision_ids')
|
||||
def _onchange_decision_data(self):
|
||||
self.decision_data = ''
|
||||
names = []
|
||||
if self.approval_decision_ids:
|
||||
for record in self.approval_decision_ids:
|
||||
names += [item.specifics for item in record]
|
||||
self.decision_data += ';'.join(names)
|
||||
|
||||
|
||||
@api.onchange('room_approval_ids')
|
||||
def _onchange_meeting_data(self):
|
||||
meet_str = ''
|
||||
if self.room_approval_ids:
|
||||
for record in self.room_approval_ids:
|
||||
record_list = []
|
||||
record_list.append(record.meeting_type_id.name)
|
||||
record_list.append(record.date_start.strftime('%Y%m%d'))
|
||||
record_list.append(record.room_booking_id.name)
|
||||
record_list.append(dict(record._fields['decision_results'].selection).get(record.decision_results) if record.decision_results else ' ')
|
||||
meet_str = meet_str + '、'.join(record_list) + ';'
|
||||
self.meeting_data = meet_str
|
||||
else:
|
||||
self.meeting_data = ''
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
@@ -48,12 +86,6 @@ class IssueApproval(models.Model):
|
||||
issue_id.write({'issue_approval_id': issue_id.id})
|
||||
return super().create(vals_list)
|
||||
|
||||
@api.depends('approval_decision_ids')
|
||||
def _compute_decision_checklist(self):
|
||||
for record in self:
|
||||
names = [item.specifics for item in record.approval_decision_ids]
|
||||
record.decision_checklist = ','.join(names)
|
||||
|
||||
def pub_meeting_minutes(self):
|
||||
pass
|
||||
|
||||
@@ -82,7 +114,7 @@ class IssueApprovalRoomLine(models.Model):
|
||||
date_end = fields.Date(string="结束时间")
|
||||
decision_results = fields.Selection([('agree', '通过'), ('disagree', '未通过')], string="决策结果")
|
||||
|
||||
# 为room_users_ids 传值
|
||||
# 为room_users_ids 传值
|
||||
department_ids = fields.Many2many('hr.department', string='部门范围')
|
||||
employee_ids = fields.Many2many('hr.employee', string='人员范围')
|
||||
users_role_ids = fields.Many2many('soong.user.role', string='角色范围')
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
from odoo import api, fields, models, tools
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
|
||||
class IssueApprovalDecision(models.Model):
|
||||
@@ -35,26 +34,4 @@ class IssueApprovalDecision(models.Model):
|
||||
seq.sequence = ''
|
||||
|
||||
|
||||
# @api.onchange('sequence', 'decision_id')
|
||||
# def _onchange_department_code(self):
|
||||
# for code in self:
|
||||
# if code.sequence and code.decision_id:
|
||||
# code.sequence = code.decision_id.sequence + ('.' + code.sequence if code.sequence else '')
|
||||
# else:
|
||||
# code.sequence = code.sequence
|
||||
# code._update_child_sequences()
|
||||
#
|
||||
# def _update_child_sequences(self):
|
||||
# def recursive_update(parent, parent_sequence):
|
||||
# # 遍历每个子记录
|
||||
# for child in parent.child_ids:
|
||||
# # 使用父级的 sequence 更新子级的 sequence
|
||||
# new_sequence = parent_sequence + ('.' + child.sequence.split('.')[-1] if child.sequence else '')
|
||||
# self.env['issue.approval.decision'].search([('id', '=', child.id.origin)]).write({'sequence': new_sequence})
|
||||
# # 递归处理孙级
|
||||
# recursive_update(child, new_sequence)
|
||||
# # 从当前记录开始递归更新所有子孙级别
|
||||
# recursive_update(self, self.sequence)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
from odoo import api, fields, models, tools
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
|
||||
class IssueApprovalDecisionType(models.Model):
|
||||
@@ -26,12 +25,8 @@ class IssueApprovalDecisionType(models.Model):
|
||||
|
||||
def _update_child_sequences(self):
|
||||
def recursive_update(parent, parent_sequence):
|
||||
# 遍历每个子记录
|
||||
for child in parent.child_ids:
|
||||
# 使用父级的 sequence 更新子级的 sequence
|
||||
new_sequence = parent_sequence + ('.' + child.sequence.split('.')[-1] if child.sequence else '')
|
||||
self.env['issue.approval.decision.type'].search([('id', '=', child.id.origin)]).write({'sequence': new_sequence})
|
||||
# 递归处理孙级
|
||||
recursive_update(child, new_sequence)
|
||||
# 从当前记录开始递归更新所有子孙级别
|
||||
recursive_update(self, self.sequence)
|
||||
recursive_update(self, self.sequence)
|
||||
|
||||
@@ -26,21 +26,7 @@ class IssueLibrary(models.Model):
|
||||
issue_library_line_ids = fields.One2many('issue.library.line', 'issue_library_id', string="决策明细")
|
||||
issue_library_approval_line_ids = fields.One2many('issue.library.approval.line', 'issue_approval_id', string='流程记录')
|
||||
room_booking_id = fields.Many2one('room.booking', string="会议室")
|
||||
|
||||
# 审批中
|
||||
# ☑
|
||||
# 已上会
|
||||
|
||||
# tree_ids
|
||||
# json_content = fields.Text(string="json content", default={"name": "crax", "template": "yuthon_issue.meeting"}) # 配置
|
||||
# json_display = fields.Char(string="json display", default={"name": "crax", "template": "yuthon_issue.meeting"}) # 效果
|
||||
#
|
||||
# @api.onchange('json_content')
|
||||
# def _onchange_json_content(self):
|
||||
# if self.json_content:
|
||||
# self.json_display = self.json_content
|
||||
# else:
|
||||
# self.json_display = False
|
||||
|
||||
def issue_pull(self):
|
||||
for record in self:
|
||||
@@ -63,9 +49,9 @@ class IssueLibrary(models.Model):
|
||||
self.write({"state": "cancel"})
|
||||
|
||||
def all_issue_pull(self):
|
||||
# for record in self:
|
||||
# if record.state in ['approval', 'cancel']:
|
||||
# raise UserError("当前状态不允许提交")
|
||||
for record in self:
|
||||
if record.state in ['approval', 'cancel']:
|
||||
raise UserError("当前状态不允许提交")
|
||||
issue_active_ids = self.env["issue.library"].browse(self._context.get('active_ids', self._context.get('active_id')))
|
||||
form_id = self.env.ref("yuthon_issue.issue_library_approval_form").id
|
||||
self.write({"state": "approval"})
|
||||
@@ -84,8 +70,6 @@ class IssueLibrary(models.Model):
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@api.depends('issue_library_line_ids')
|
||||
def _compute_issue_library_line_ids(self):
|
||||
for line in self:
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates id="template" xml:space="preserve">
|
||||
<t t-name="yuthon_issue.html_issue_demo" owl="1">
|
||||
<t t-set="data" t-value="props.record.data"/>
|
||||
<div>
|
||||
<p>
|
||||
<t t-foreach="data.issue_data.split(';')" t-as="line" t-key="line">
|
||||
<t t-esc="line"/>
|
||||
<br/>
|
||||
</t>
|
||||
</p>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="yuthon_issue.html_decision_demo" owl="1">
|
||||
<t t-set="data" t-value="props.record.data"/>
|
||||
<div>
|
||||
<p>
|
||||
<t t-foreach="data.decision_data.split(';')" t-as="line" t-key="line">
|
||||
<t t-esc="line"/>
|
||||
<br/>
|
||||
</t>
|
||||
</p>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="yuthon_issue.table_meet_demo" owl="1">
|
||||
<t t-set="data" t-value="props.record.data"/>
|
||||
<table style="table-layout:fixed;border: 1px solid black;">
|
||||
<thead>
|
||||
<tr colspan="8" style="border: 1px solid black;">
|
||||
<td colspan="2" style="border: 1px solid black;"><span style="color: black;"><strong>会议类型</strong></span></td>
|
||||
<td colspan="2" style="border: 1px solid black;"><span style="color: black;"><strong>会议时间</strong></span></td>
|
||||
<td colspan="2" style="border: 1px solid black;"><span style="color: black;"><strong>会议名称</strong></span></td>
|
||||
<!-- <td colspan="2" style="border: 1px solid black;"><span style="color: black;"><strong>参会人员</strong></span></td>-->
|
||||
<td colspan="2" style="border: 1px solid black;"><span style="color: black;"><strong>决策结果</strong></span></td>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<t t-esc="data.meeting_data"/>
|
||||
<!-- <t t-foreach="data.meeting_data.split(';')" t-as="line" t-key="line">-->
|
||||
<!-- <thead>-->
|
||||
<!-- <tr colspan="8" style="border: 1px solid black;">-->
|
||||
|
||||
<!-- <t t-foreach="line.split('、')" t-as="l" t-key="l">-->
|
||||
<td colspan="8" style="border: 1px solid black;"><span style="color: red;">☑</span></td>
|
||||
<!-- <td colspan="1" style="border: 1px solid black;"><span style="color: red;">☑</span></td>-->
|
||||
<!-- <td colspan="1" style="border: 1px solid black;"><span style="color: black;"><t t-esc="l"/></span></td>-->
|
||||
<!-- <td colspan="2" style="border: 1px solid black;"><span style="color: black;"><t t-esc="l"/></span></td>-->
|
||||
<!-- <td colspan="2" style="border: 1px solid black;"><span style="color: black;"><t t-esc="l"/></span></td>-->
|
||||
<!-- <!– <td colspan="2" style="border: 1px solid black;"><span style="color: black;"><strong>参会人员</strong></span></td>–>-->
|
||||
<!-- <td colspan="2" style="border: 1px solid black;"><span style="color: black;"><t t-esc="l"/></span></td>-->
|
||||
<!-- </t>-->
|
||||
|
||||
<!-- </tr>-->
|
||||
<!-- </thead>-->
|
||||
<!-- </t>-->
|
||||
<t t-if="data.is_parent_unit">
|
||||
<thead>
|
||||
<tr colspan="8" style="border: 1px solid black;">
|
||||
<td colspan="1" style="border: 1px solid black;"><span style="color: red;">☑</span></td>
|
||||
<td colspan="1" style="border: 1px solid black;"><span style="color: black;">上级单位</span></td>
|
||||
<td colspan="2" style="border: 1px solid black;"/>
|
||||
<td colspan="2" style="border: 1px solid black;"/>
|
||||
<td colspan="2" style="border: 1px solid black;"/>
|
||||
<!-- <td colspan="2" style="border: 1px solid black;"/>-->
|
||||
</tr>
|
||||
</thead>
|
||||
</t>
|
||||
</table>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
@@ -1,34 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates id="template" xml:space="preserve">
|
||||
<t t-name="yuthon_issue.meeting" owl="1">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">#</th>
|
||||
<th scope="col">First</th>
|
||||
<th scope="col">Last</th>
|
||||
<th scope="col">Handle</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">1</th>
|
||||
<td>Mark</td>
|
||||
<td>Otto</td>
|
||||
<td>@mdo</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">2</th>
|
||||
<td>Jacob</td>
|
||||
<td>Thornton</td>
|
||||
<td>@fat</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">3</th>
|
||||
<td colspan="2">Larry the Bird</td>
|
||||
<td>@twitter</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</t>
|
||||
</templates>
|
||||
@@ -4,13 +4,15 @@
|
||||
<field name="name">issue.approval.tree</field>
|
||||
<field name="model">issue.approval</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="议题审批">
|
||||
<tree string="议题审批" delete="0" create="0">
|
||||
<field name="issue_data" column_invisible="1"/>
|
||||
<field name="decision_data" column_invisible="1"/>
|
||||
<field name="name"/>
|
||||
<field name="yuthon_company"/>
|
||||
<field name="department_id"/>
|
||||
<field name="agenda_items"/>
|
||||
<field name="decision_checklist"/>
|
||||
<field name="meeting_details"/>
|
||||
<field name="issue_display" widget="json_template"/>
|
||||
<field name="decision_display" widget="json_template"/>
|
||||
<field name="meeting_display" widget="json_template"/>
|
||||
<button name="all_meeting_issue" string="安排会议" type="object" class="oe_highlight"/>
|
||||
<button name="pub_meeting_minutes" string="会议纪要" type="object" class="oe_highlight"/>
|
||||
</tree>
|
||||
@@ -37,13 +39,23 @@
|
||||
<group string="审批事项">
|
||||
<field name="name" required="1"/>
|
||||
<field name="issue_text" widget="tinymce"/>
|
||||
<field name="notice_documents_ids" widget="many2many_tags"/>
|
||||
<field name="notice_documents_ids" widget="preview_many2many" string=" "/>
|
||||
<!-- <field name="notice_documents_ids" widget="many2many_tags"/>-->
|
||||
<field name="notice_documents_ids" widget="preview_many2many"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="issue_display" widget="json_template" invisible="1"/>
|
||||
<field name="decision_display" widget="json_template" invisible="1"/>
|
||||
<field name="meeting_display" widget="json_template" invisible="1"/>
|
||||
|
||||
<field name="issue_data" invisible="1" force_save="1"/>
|
||||
<field name="decision_data" invisible="1" force_save="1"/>
|
||||
<field name="meeting_data" invisible="1" force_save="1"/>
|
||||
<field name="is_parent_unit" invisible="1"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="关联议题">
|
||||
<field name="issue_library_ids">
|
||||
<tree editable="bottom">
|
||||
<tree editable="bottom" create="false">
|
||||
<field name="issue_approval_id" column_invisible="1"/>
|
||||
<field name="name"/>
|
||||
<field name="is_party"/>
|
||||
@@ -54,7 +66,7 @@
|
||||
</field>
|
||||
</page>
|
||||
<page string="决策清单">
|
||||
<field name="approval_decision_ids">
|
||||
<field name="approval_decision_ids" create="false">
|
||||
<tree editable="bottom">
|
||||
<field name="issue_approval_id" column_invisible="1"/>
|
||||
<field name="specifics"/>
|
||||
|
||||
@@ -83,24 +83,6 @@
|
||||
action="issue_library_approval_action"
|
||||
sequence="9"/>
|
||||
|
||||
<!-- <menuitem id="issue_approval_menu"-->
|
||||
<!-- parent="issue_approval_menu"-->
|
||||
<!-- name="议题审批"-->
|
||||
<!-- action="issue_approval_action"-->
|
||||
<!-- sequence="10"/>-->
|
||||
|
||||
<!-- <menuitem id="issue_approval_class_menu"-->
|
||||
<!-- parent="issue_approval_menu"-->
|
||||
<!-- name="领导班子议题审批"-->
|
||||
<!-- action="issue_approval_class_action"-->
|
||||
<!-- sequence="20"/>-->
|
||||
|
||||
<!-- <menuitem id="issue_approval_boss_menu"-->
|
||||
<!-- parent="issue_approval_menu"-->
|
||||
<!-- name="董事会议题审批"-->
|
||||
<!-- action="issue_approval_boss_action"-->
|
||||
<!-- sequence="30"/>-->
|
||||
|
||||
<menuitem id="issue_approval_decision_menu"
|
||||
parent="tianhe_issue_library_menu_root"
|
||||
name="决策清单"
|
||||
|
||||