pengyuthon wechat
This commit is contained in:
@@ -0,0 +1 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
@@ -0,0 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
{
|
||||
'name': 'Faster Many2one',
|
||||
'summary': 'Faster Many2one',
|
||||
'description': """
|
||||
""",
|
||||
"version": "17.0",
|
||||
"author": "Croissant",
|
||||
"license": "OPL-1",
|
||||
'depends': ['web'],
|
||||
'images': [
|
||||
'static/description/banner.png',
|
||||
],
|
||||
'assets': {
|
||||
'web.assets_backend': [
|
||||
'cr_m2o_faster/static/src/views/fields/many2one/*',
|
||||
# 'cr_m2o_faster/static/src/views/fields/many2many/*',
|
||||
],
|
||||
},
|
||||
'installable': True,
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 47 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 45 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
@@ -0,0 +1,66 @@
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<div class="container">
|
||||
<div class="oe_styling_v8">
|
||||
<div>
|
||||
|
||||
<section class="oe_container lead title_box" style="text-align:center">
|
||||
<div>
|
||||
<div>
|
||||
<h2 class="oe_slogan title" style="margin-bottom:10px; padding-top:10px">
|
||||
<b>Many2one Show More</b>
|
||||
</h2>
|
||||
<hr style="width:80%">
|
||||
<p class="oe_slogan" style="padding:5px 10px">Many2one字段一键直达更多。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div style="min-height:20px"></div>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="oe_container lead title_box" style="text-align:center">
|
||||
<div style="margin-bottom:40px">
|
||||
<div>
|
||||
<h2 class="oe_slogan title" style="margin-bottom:10px">
|
||||
<b> Description</b>
|
||||
</h2>
|
||||
<hr style="width:80%; height:1px">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div style="margin-bottom:40px">
|
||||
<h3 class="oe_slogan" style="color:#091383; font-weight:initial ; margin:auto">It provides a convenient way to quickly click on show more .</h3>
|
||||
<br>
|
||||
<p>它提供了一种便捷的方式,快速点击更多。</p>
|
||||
<img class="img-responsive" style="display:block; width:95%; margin:auto" src="./1.png">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<section class="oe_container lead title_box" style="text-align:center">
|
||||
<div>
|
||||
<div>
|
||||
<h2 class="oe_slogan title" style="margin-bottom:10px">
|
||||
<b> Support</b>
|
||||
</h2>
|
||||
<hr style="width:80%; height:1px">
|
||||
<b class="oe_slogan" style="margin-bottom:0px; margin-top:15px"> If there are any errors or issues, you will receive 60 days of free support. </b>
|
||||
<div class="oe_slogan" style="margin:0"> 如果出现任何错误或问题,您将获得60天的免费支持。 </div>
|
||||
<div>
|
||||
<b class="oe_slogan" style="margin:0px; margin-right:5px"> If you have any questions or need support, please contact me</b>
|
||||
<div class="oe_slogan" style="margin:0px; margin-right:5px"> 如有任何问题或需要支持,请联系我</div>
|
||||
<a href="mailto:croissant_cr@163.com?subject=Fields Sorting in locale" target="_top"> croissant_cr@163.com</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr style="width:80%">
|
||||
<div style="min-height:20px"></div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/** @odoo-module **/
|
||||
import {patch} from "@web/core/utils/patch";
|
||||
import {Many2manyField} from "@web/views/fields/many2one/many2one_field";
|
||||
import {useSelectCreate} from "@web/views/fields/relational_utils";
|
||||
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
import { sprintf } from "@web/core/utils/strings";
|
||||
|
||||
patch(Many2manyField.prototype, {
|
||||
setup(...args) {
|
||||
super.setup(...args)
|
||||
let self = this;
|
||||
this.selectCreate = useSelectCreate({
|
||||
resModel:this.relation,
|
||||
activeActions: this.state.activeActions,
|
||||
onSelected: (resId) => {
|
||||
const resIds = Array.isArray(resId) ? resId : [resId];
|
||||
const values = resIds.map((id) => ({id}));
|
||||
return self.update(values);
|
||||
},
|
||||
onCreateEdit: ({context}) => this.openMany2X({context}),
|
||||
onUnselect: this.update,
|
||||
});
|
||||
},
|
||||
onMoreBtnClick() {
|
||||
const domain = this.getDomain();
|
||||
let dynamicFilters = [];
|
||||
const title = sprintf(_t("Search: %s"), this.props.string);
|
||||
this.selectCreate({
|
||||
domain,
|
||||
context: this.context,
|
||||
filters: dynamicFilters,
|
||||
title,
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-inherit="web.Many2ManyField" t-inherit-mode="extension">
|
||||
<xpath expr="//Many2XAutocomplete" position="after">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-secondary fa fa-list-alt o_external_button"
|
||||
tabindex="-1"
|
||||
draggable="false"
|
||||
aria-label="Show More"
|
||||
data-tooltip="Show More"
|
||||
t-on-click="onMoreBtnClick"
|
||||
/>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
@@ -0,0 +1,36 @@
|
||||
/** @odoo-module **/
|
||||
import {patch} from "@web/core/utils/patch";
|
||||
import {Many2OneField} from "@web/views/fields/many2one/many2one_field";
|
||||
import {useSelectCreate} from "@web/views/fields/relational_utils";
|
||||
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
import { sprintf } from "@web/core/utils/strings";
|
||||
|
||||
patch(Many2OneField.prototype, {
|
||||
setup(...args) {
|
||||
super.setup(...args)
|
||||
let self = this;
|
||||
this.selectCreate = useSelectCreate({
|
||||
resModel:this.relation,
|
||||
activeActions: this.state.activeActions,
|
||||
onSelected: (resId) => {
|
||||
const resIds = Array.isArray(resId) ? resId : [resId];
|
||||
const values = resIds.map((id) => ({id}));
|
||||
return self.update(values);
|
||||
},
|
||||
onCreateEdit: ({context}) => this.openMany2X({context}),
|
||||
onUnselect: this.update,
|
||||
});
|
||||
},
|
||||
onMoreBtnClick() {
|
||||
const domain = this.getDomain();
|
||||
let dynamicFilters = [];
|
||||
const title = sprintf(_t("Search: %s"), this.props.string);
|
||||
this.selectCreate({
|
||||
domain,
|
||||
context: this.context,
|
||||
filters: dynamicFilters,
|
||||
title,
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-inherit="web.Many2OneField" t-inherit-mode="extension">
|
||||
<xpath expr="//Many2XAutocomplete" position="after">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-secondary fa fa-list-alt o_external_button"
|
||||
tabindex="-1"
|
||||
draggable="false"
|
||||
aria-label="Show More"
|
||||
data-tooltip="Show More"
|
||||
t-on-click="onMoreBtnClick"
|
||||
/>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
@@ -28,7 +28,6 @@
|
||||
"views/soong_workflow_entrust_views.xml",
|
||||
"views/soong_workflow_inspector_views.xml",
|
||||
"views/soong_workflow_log_views.xml",
|
||||
'wizard/approval_notice_wizard_views.xml',
|
||||
"wizard/soong_workflow_comment_wizard_view.xml",
|
||||
"templates/soong_workflow_templates.xml",
|
||||
"views/menuitem.xml",
|
||||
|
||||
@@ -48,7 +48,7 @@ class YuthonUserRole(models.Model):
|
||||
'thtjbb': '天河投资本部',
|
||||
}
|
||||
|
||||
@api.depends('name','yuthon_company')
|
||||
@api.depends('name', 'yuthon_company')
|
||||
def _compute_display_name(self):
|
||||
company_mapping = self._get_company_mapping()
|
||||
for record in self:
|
||||
|
||||
@@ -20,7 +20,6 @@ access_soong_approval_users,soong_approval_users,model_soong_approval_users,soon
|
||||
access_soong_note,soong_note,model_soong_note,soong_workflow.group_soong_workflow_user,1,1,1,1
|
||||
access_soong_approval_group,soong_approval_group,model_soong_approval_group,soong_workflow.group_soong_workflow_user,1,1,1,1
|
||||
|
||||
access_soong_approval_notice_wizard,soong_approval_notice_wizard,model_soong_approval_notice_wizard,base.group_user,1,1,1,1
|
||||
|
||||
access_soong_workflow_log_user,soong_workflow_log_user,model_soong_workflow_log,soong_workflow.group_soong_workflow_user,1,1,1,1
|
||||
access_soong_workflow_comment_wizard_user,soong_workflow_comment_wizard_user,model_soong_workflow_comment_wizard,soong_workflow.group_soong_workflow_user,1,1,1,1
|
||||
|
||||
|
@@ -1,8 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
|
||||
|
||||
from . import approval_notice_wizard
|
||||
from . import soong_workflow_comment_wizard
|
||||
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from odoo import api, fields, models, tools, _
|
||||
from datetime import datetime, date, time, timedelta
|
||||
from odoo.tools.safe_eval import safe_eval
|
||||
from odoo.exceptions import ValidationError, UserError
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
class SoongApprovalNoticeWizard(models.TransientModel):
|
||||
_name = 'soong.approval.notice.wizard'
|
||||
_description = """ 审批意见弹窗 """
|
||||
|
||||
# approval_res_id = fields.Char(string="审批明细行")
|
||||
# approval_res_model = fields.Char(string="审批明细行")
|
||||
approval_notice_state = fields.Selection([
|
||||
('0', '不分类'),
|
||||
('1', '审批通过'),
|
||||
('2', '审批拒绝'),
|
||||
], string='意见类型', default='0')
|
||||
approval_user_notice = fields.Many2one('soong.note', string='审批意见')
|
||||
# approval_user_sign = fields.Binary(string="审批签署", copy=False)
|
||||
|
||||
def confirm(self):
|
||||
self.ensure_one()
|
||||
active_model = self.env.context.get("active_model")
|
||||
active_id = self.env.context.get("active_id")
|
||||
self.env["soong.approval.users"].create({
|
||||
'res_model_id': self.env['ir.model']._get(active_model).id,
|
||||
'res_id': active_id,
|
||||
'approval_user_notice': self.approval_user_notice.name,
|
||||
'approval_user_id': self.env.user.id,
|
||||
'approval_user_datetime': fields.datetime.now(),
|
||||
# 'approval_user_sign': self.approval_user_sign,
|
||||
'approval_notice_state': self.approval_notice_state,
|
||||
})
|
||||
wkf_btn_obj = self.env["soong.workflow.node.button"]
|
||||
btn_rec = wkf_btn_obj.search([("btn_key", "=", self.env.context.get("btn_key", False))])
|
||||
if btn_rec:
|
||||
# todo 更改业务数据的状态,成品不建议这样玩
|
||||
try:
|
||||
obj = self.env[active_model].browse(active_id)
|
||||
if obj.exists():
|
||||
if self.approval_notice_state == '1':
|
||||
obj.write({'statu': 'done'})
|
||||
elif self.approval_notice_state == '2':
|
||||
obj.write({'statu': 'stop'})
|
||||
except Exception as e:
|
||||
# todo 可以记录一下日志,但用处不大
|
||||
pass
|
||||
btn_rec.link_id.trigger_link()
|
||||
@@ -1,51 +0,0 @@
|
||||
<odoo>
|
||||
<record id="soong_approval_notice_wizard_form" model="ir.ui.view">
|
||||
<field name="name">审批意见弹窗</field>
|
||||
<field name="model">soong.approval.notice.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<field name="approval_notice_state" invisible="1"/>
|
||||
<group>
|
||||
<field name="approval_user_notice"/>
|
||||
</group>
|
||||
<!-- <group>-->
|
||||
<!-- <field name="approval_user_sign" widget="signature" options="{'size': ['',200]}"/>-->
|
||||
<!-- </group>-->
|
||||
<footer>
|
||||
<button name="confirm" string="确认" type="object" class="oe_highlight"/>
|
||||
<button string="返回" class="btn-secondary" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="soong_approval_notice_wizard_action" model="ir.actions.act_window">
|
||||
<field name="name">审批意见弹窗</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">soong.approval.notice.wizard</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
<field name="context">
|
||||
{"default_approval_notice_state": '0'}
|
||||
</field>
|
||||
</record>
|
||||
<record id="soong_approval_approve_notice_wizard_action" model="ir.actions.act_window">
|
||||
<field name="name">审批通过弹窗</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">soong.approval.notice.wizard</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
<field name="context">
|
||||
{"default_approval_notice_state": '1'}
|
||||
</field>
|
||||
</record>
|
||||
<record id="soong_approval_refuse_notice_wizard_action" model="ir.actions.act_window">
|
||||
<field name="name">审批拒绝弹窗</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">soong.approval.notice.wizard</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
<field name="context">
|
||||
{"default_approval_notice_state": '2'}
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -5,6 +5,11 @@ from odoo import fields, models, api
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
|
||||
|
||||
class SoongApprovalNoticeWizard(models.TransientModel):
|
||||
_name = "soong.approval.notice.wizard"
|
||||
_description = "Soong Workflow Comment Wizard"
|
||||
|
||||
|
||||
class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
_name = "soong.workflow.comment.wizard"
|
||||
_description = "Soong Workflow Comment Wizard"
|
||||
@@ -23,42 +28,18 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
trans_link_id = fields.Many2one('trans.link', string='转交节点')
|
||||
return_link_id = fields.Many2one('trans.link', string='退回节点')
|
||||
|
||||
send_type = fields.Selection([('send', '分发'), ('super', '督办')], default='send', string="动作类型")
|
||||
department_id = fields.Many2one('hr.department', string="承办部门")
|
||||
start_date = fields.Date(string="开始日期", default=fields.Date.today())
|
||||
end_date = fields.Date(string="结束日期")
|
||||
|
||||
department_ids = fields.Many2many('hr.department', string='部门范围')
|
||||
employee_ids = fields.Many2many('hr.employee', string='人员范围')
|
||||
users_role_ids = fields.Many2many('soong.user.role', string='角色范围')
|
||||
approval_users_ids = fields.Many2many('res.users', string="传阅/督办人员", compute="compute_approval_users_ids", store=True)
|
||||
employee_ids = fields.Many2many('hr.employee', 'employee_ids_rel',
|
||||
'custom_id', 'employee_id',
|
||||
string="传阅人员", store=True)
|
||||
circulated_employee_ids = fields.Many2many('hr.employee', 'circulated_employee_rel',
|
||||
'custom_id', 'employee_id',
|
||||
string="传阅人员", store=True)
|
||||
supervising_employee_ids = fields.Many2many('hr.employee', 'supervising_employee_rel',
|
||||
'custom_id', 'employee_id',
|
||||
string="督办人员", store=True)
|
||||
|
||||
is_automatic = fields.Boolean('是否自动识别')
|
||||
|
||||
@api.depends('department_ids', 'employee_ids', 'users_role_ids')
|
||||
def compute_approval_users_ids(self):
|
||||
department_users_list = []
|
||||
users_role_list = []
|
||||
for users in self:
|
||||
if users.department_ids:
|
||||
for depart in users.department_ids:
|
||||
department_users_data = users.env['hr.employee'].search([('department_id', '=', depart.id.origin)])
|
||||
department_users_list = [de.user_id.id for de in department_users_data]
|
||||
if depart.child_ids:
|
||||
for child in depart.child_ids:
|
||||
department_child_users_data = users.env['hr.employee'].search(
|
||||
[('department_id', '=', child.id.origin)])
|
||||
department_users_list += [de.user_id.id for de in department_child_users_data]
|
||||
employee_users_list = users.employee_ids.user_id.ids
|
||||
if users.users_role_ids:
|
||||
for user_id in users.users_role_ids:
|
||||
user_role_data = users.env['hr.employee'].search(
|
||||
['|', ('user_role_id', '=', user_id.id.origin), ('user_role_ids', '=', user_id.id.origin)])
|
||||
users_role_list = [ro.user_id.id for ro in user_role_data]
|
||||
publish_user_list = department_users_list + employee_users_list + users_role_list
|
||||
false_none_list = [x for x in publish_user_list if x != False]
|
||||
users.approval_users_ids = [(6, 0, list(set(false_none_list)))]
|
||||
|
||||
@api.onchange('record_id')
|
||||
def _onchange_record_id(self):
|
||||
record_id = self.env[self.res_model].search([('id', '=', self.res_id)])
|
||||
@@ -115,4 +96,4 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
if self.node_btn_name == '加签':
|
||||
record_id.approval_sign_ids = self.approval_users_ids
|
||||
|
||||
return self.node_btn_id.with_context(cx).run()
|
||||
return self.node_btn_id.with_context(cx).run()
|
||||
@@ -8,7 +8,7 @@
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="意见">
|
||||
<group>
|
||||
<group invisible="node_btn_name == '分发'">
|
||||
<field name="node_btn_id" invisible="1"/>
|
||||
<field name="node_btn_name" invisible="1"/>
|
||||
<field name="node_link_len" invisible="1"/>
|
||||
@@ -19,15 +19,13 @@
|
||||
<!-- 转交人员 -->
|
||||
<field name="trans_link_id" invisible="not node_link_len" string="转交节点"/>
|
||||
<field name="comment_note_id"/>
|
||||
<!-- 分发 -->
|
||||
<field name="send_type" invisible="node_btn_name != '分发'" widget="radio"/>
|
||||
<field name="start_date" invisible="send_type != 'super'"/>
|
||||
<field name="end_date" invisible="send_type != 'super'"/>
|
||||
<field name="department_ids" invisible="node_btn_name not in ['加签', '分发']" widget="many2many_tags"/>
|
||||
<field name="employee_ids" widget="many2many_tags" invisible="node_btn_name in ['加签确认']" readonly="1"/>
|
||||
<field name="users_role_ids" invisible="node_btn_name not in ['加签', '分发']" widget="many2many_tags"/>
|
||||
<field name="approval_users_ids" invisible="node_btn_name != '分发'" widget="many2many_tags"/>
|
||||
<field name="approval_users_ids" string='加签人员' invisible="node_btn_name != '加签'" widget="many2many_tags"/>
|
||||
<field name="employee_ids" widget="many2many_tags" string="人员范围"/>
|
||||
</group>
|
||||
<group string="流程选择" invisible="node_btn_name != '分发'">
|
||||
<field name="comment_note_id"/>
|
||||
<field name="employee_ids" widget="many2many_tags" string="董事长"/>
|
||||
<field name="circulated_employee_ids" widget="many2many_tags"/>
|
||||
<field name="supervising_employee_ids" widget="many2many_tags"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="add_comment" string="确认" type="object" class="oe_highlight"/>
|
||||
|
||||
@@ -46,7 +46,6 @@ class HolidaysRequestBatch(models.Model):
|
||||
|
||||
name = fields.Char(string='标题')
|
||||
employee_id = fields.Many2one(string='员工', comodel_name='hr.employee', required=True, default=_get_default_emp, index=True)
|
||||
# leave_ids = fields.One2many(string='详情', comodel_name='hr.leave', inverse_name='batch_id')
|
||||
state = fields.Selection(string='状态', selection=[
|
||||
('draft', '撤回'),
|
||||
('confirm', '转交'),
|
||||
@@ -60,8 +59,6 @@ class HolidaysRequestBatch(models.Model):
|
||||
text = fields.Html(string='申请事由')
|
||||
leave_line_ids = fields.One2many('hr.leave.line', 'leave_batch_id', string="关联请假详情明细行")
|
||||
is_issues = fields.Boolean(string='是否上会')
|
||||
leave_by_hour = fields.Boolean(string='按小时请假', default=True)
|
||||
leave_unit = fields.Selection(string='时长单位', selection=[('day', '天'), ('hour', '小时')])
|
||||
|
||||
@api.constrains('leave_line_ids')
|
||||
def _check_leave_line_ids(self):
|
||||
@@ -71,11 +68,6 @@ class HolidaysRequestBatch(models.Model):
|
||||
if rec.leave_line_ids.filtered(lambda line: line.residual < 0):
|
||||
raise ValidationError('假期剩余天数不能小于0')
|
||||
|
||||
@api.onchange('leave_by_hour')
|
||||
def _onchange_leave_by_hour(self):
|
||||
# self.leave_unit = 'hour' if self.leave_by_hour else 'day'
|
||||
self.leave_unit = 'day'
|
||||
self.leave_line_ids = None
|
||||
|
||||
# 提交
|
||||
def action_submit(self):
|
||||
@@ -117,7 +109,7 @@ class HolidaysRequestBatch(models.Model):
|
||||
name_parts.append(line.leave_type_id.name)
|
||||
if line.available_days:
|
||||
name_parts.append(str(line.available_days))
|
||||
self.name =''.join(name_parts) or 'New'
|
||||
self.name = ''.join(name_parts) or 'New'
|
||||
|
||||
|
||||
class HrLeaveLine(models.Model):
|
||||
@@ -141,7 +133,6 @@ class HrLeaveLine(models.Model):
|
||||
end_time = fields.Date(string="结束日期", required=True)
|
||||
end_hour_from = fields.Selection(string="结束时间", selection=HOUR_SELECTION)
|
||||
leave_duration = fields.Float(string="时长", compute='_compute_leave_duration')
|
||||
leave_unit = fields.Selection(string="单位", related='leave_batch_id.leave_unit')
|
||||
residual = fields.Float(string="剩余时长", compute='_compute_remaining_days')
|
||||
custom_document_ids = fields.Many2many(
|
||||
string='文件',
|
||||
@@ -159,9 +150,6 @@ class HrLeaveLine(models.Model):
|
||||
for rec in self:
|
||||
if rec.start_time > rec.end_time:
|
||||
raise ValidationError('开始时间不能大于结束时间')
|
||||
# if rec.leave_batch_id.leave_by_hour:
|
||||
# if rec.start_time != rec.end_time:
|
||||
# raise ValidationError('按小时请假禁止跨天')
|
||||
|
||||
@api.depends('leave_type_id')
|
||||
def _compute_available_days(self):
|
||||
@@ -179,33 +167,33 @@ class HrLeaveLine(models.Model):
|
||||
for record in self:
|
||||
if record.start_time and record.end_time:
|
||||
# 按小时
|
||||
if record.leave_batch_id.leave_by_hour:
|
||||
if record.start_hour_from and record.end_hour_from:
|
||||
hour_selection = dict(HOUR_SELECTION)
|
||||
start_time_obj = datetime.strptime(hour_selection[record.start_hour_from], "%H:%M").time()
|
||||
end_time_obj = datetime.strptime(hour_selection[record.end_hour_from], "%H:%M").time()
|
||||
start_date = datetime.combine(record.start_time, start_time_obj)
|
||||
end_time = datetime.combine(record.end_time, end_time_obj)
|
||||
# 根据时间段计算请假时长
|
||||
# 天数计算公式,每天最大时长为8,如果请假时间超过8,则按8计算,小于8,则按请假时间计算
|
||||
# 如果有跨天
|
||||
# 天数 = 第一天的天数 + 间隔时常 - 2天 + 最后一天的天数
|
||||
first_days, interval_days, last_days = 0, 0, 0
|
||||
# 跨天
|
||||
if start_date.date() != end_time.date():
|
||||
# 第一天的天数, 如果开始时间大于中午十二点,则按0.5计算,如果小于中午十二点,则按1天计算
|
||||
first_days = (start_date.time() > time(12, 0)) and 0.5 or 1
|
||||
interval_days = (end_time.date() - start_date.date()).days - 2
|
||||
last_days = (end_time.time() > time(12, 0)) and 0.5 or 1
|
||||
# 没有跨天
|
||||
else:
|
||||
# 天数 = 时常 / 8
|
||||
first_days = (end_time - start_date).total_seconds() / 3600 / 8
|
||||
leave_duration = first_days + interval_days + last_days
|
||||
else:
|
||||
start_date = datetime.combine(record.start_time, datetime.min.time())
|
||||
end_time = datetime.combine(record.end_time, datetime.min.time())
|
||||
leave_duration = record._get_leave_duration(start_date, end_time)
|
||||
# if record.leave_batch_id.leave_by_hour:
|
||||
# if record.start_hour_from and record.end_hour_from:
|
||||
# hour_selection = dict(HOUR_SELECTION)
|
||||
# start_time_obj = datetime.strptime(hour_selection[record.start_hour_from], "%H:%M").time()
|
||||
# end_time_obj = datetime.strptime(hour_selection[record.end_hour_from], "%H:%M").time()
|
||||
# start_date = datetime.combine(record.start_time, start_time_obj)
|
||||
# end_time = datetime.combine(record.end_time, end_time_obj)
|
||||
# # 根据时间段计算请假时长
|
||||
# # 天数计算公式,每天最大时长为8,如果请假时间超过8,则按8计算,小于8,则按请假时间计算
|
||||
# # 如果有跨天
|
||||
# # 天数 = 第一天的天数 + 间隔时常 - 2天 + 最后一天的天数
|
||||
# first_days, interval_days, last_days = 0, 0, 0
|
||||
# # 跨天
|
||||
# if start_date.date() != end_time.date():
|
||||
# # 第一天的天数, 如果开始时间大于中午十二点,则按0.5计算,如果小于中午十二点,则按1天计算
|
||||
# first_days = (start_date.time() > time(12, 0)) and 0.5 or 1
|
||||
# interval_days = (end_time.date() - start_date.date()).days - 2
|
||||
# last_days = (end_time.time() > time(12, 0)) and 0.5 or 1
|
||||
# # 没有跨天
|
||||
# else:
|
||||
# # 天数 = 时常 / 8
|
||||
# first_days = (end_time - start_date).total_seconds() / 3600 / 8
|
||||
# leave_duration = first_days + interval_days + last_days
|
||||
# else:
|
||||
start_date = datetime.combine(record.start_time, datetime.min.time())
|
||||
end_time = datetime.combine(record.end_time, datetime.min.time())
|
||||
leave_duration = record._get_leave_duration(start_date, end_time)
|
||||
record.leave_duration = leave_duration
|
||||
|
||||
@api.depends('available_days', 'leave_duration')
|
||||
@@ -217,13 +205,6 @@ class HrLeaveLine(models.Model):
|
||||
else:
|
||||
record.residual = 0
|
||||
|
||||
@api.onchange('start_time', 'start_hour_from', 'end_time', 'end_hour_from')
|
||||
def _onchange_leave_date(self):
|
||||
if self.start_time > self.end_time:
|
||||
raise ValidationError('开始时间不能大于结束时间')
|
||||
# if self.leave_batch_id.leave_by_hour and self.start_time and self.end_time and self.start_time != self.end_time:
|
||||
# raise ValidationError('按小时请假禁止跨天')
|
||||
|
||||
# 计算开始时间与结束时间之间的时长
|
||||
def _get_leave_duration(self, start_time: datetime, end_time: datetime):
|
||||
"""
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<!-- Tree View -->
|
||||
<record id="view_hr_leave_batch_tree" model="ir.ui.view">
|
||||
<field name="name">hr.leave.batch.tree</field>
|
||||
<field name="model">hr.leave.batch</field>
|
||||
@@ -11,10 +10,6 @@
|
||||
<field name="name"/>
|
||||
<field name="state" column_invisible="1"/>
|
||||
<field name="leave_id"/>
|
||||
<!-- <field name="days"/>-->
|
||||
<!-- <field name="hours"/>-->
|
||||
<!-- <field name="holiday_status_id" string="Leave Type" column_invisible="1"/>-->
|
||||
<!-- <field name="leave_ids"/> -->
|
||||
<button name="action_validate" type="object" class="oe_highlight" string="Validate" invisible="1"/>
|
||||
<button name="action_refuse" type="object" class="oe_highlight" string="Refuse" invisible="1"/>
|
||||
<button name="action_draft" type="object" class="oe_highlight" string="Retract" invisible="1"/>
|
||||
@@ -22,7 +17,6 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Form View -->
|
||||
<record id="view_hr_leave_batch_form" model="ir.ui.view">
|
||||
<field name="name">hr.leave.batch.form</field>
|
||||
<field name="model">hr.leave.batch</field>
|
||||
@@ -31,15 +25,12 @@
|
||||
<header>
|
||||
<field name="state" widget="statusbar" invisible="1"/>
|
||||
<button name="action_submit" type="object" class="oe_highlight" string="Submit" invisible="1"/>
|
||||
<button name="action_validate" type="object" class="oe_highlight" string="Validate" invisible="1"/>
|
||||
<button name="action_validate" type="object" class="oe_highlight" string="Validate"
|
||||
invisible="1"/>
|
||||
<button name="action_refuse" type="object" class="oe_highlight" string="Refuse" invisible="1"/>
|
||||
<button name="action_draft" type="object" class="oe_highlight" string="Retract" invisible="1"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<!-- <group>-->
|
||||
<!-- <field name="employee_id" readonly="1" forcesave="1"/>-->
|
||||
<!-- <field name="name"/>-->
|
||||
<!-- </group>-->
|
||||
<div class="oe_title">
|
||||
<label for="name"/>
|
||||
<h1>
|
||||
@@ -54,12 +45,8 @@
|
||||
<group>
|
||||
<field name="employee_id" invisible="1" force_save="1"/>
|
||||
<field name="department_id"/>
|
||||
<field name="leave_by_hour"/>
|
||||
<field name="leave_unit"/>
|
||||
</group>
|
||||
<group>
|
||||
<!-- <field name="days"/> -->
|
||||
<!-- <field name="hours"/> -->
|
||||
<field name="is_issues" invisible="1"/>
|
||||
</group>
|
||||
</group>
|
||||
@@ -72,8 +59,6 @@
|
||||
<field name="leave_type_id"
|
||||
force_save="1"
|
||||
domain="[
|
||||
('request_unit', '=', leave_unit),
|
||||
'|',
|
||||
('requires_allocation', '=', 'no'),
|
||||
'&',
|
||||
('has_valid_allocation', '=', True),
|
||||
@@ -88,14 +73,13 @@
|
||||
/>
|
||||
<field name="available_days"/>
|
||||
<field name="start_time"/>
|
||||
<field name="start_hour_from" column_invisible="not parent.leave_by_hour" required="parent.leave_by_hour"/>
|
||||
<field name="end_time"/>
|
||||
<field name="end_hour_from" column_invisible="not parent.leave_by_hour" required="parent.leave_by_hour"/>
|
||||
<field name="leave_duration" sum="Total"/>
|
||||
<field name="leave_unit"/>
|
||||
<field name="residual"/>
|
||||
<field name="leave_documents_ids" widget="preview_many2many" options="{'preview_type': 'button', 'preview_string': '查看详情'}"/>
|
||||
<field name="custom_document_ids" widget="preview_many2many" options="{'show_select_btn': false}"/>
|
||||
<field name="leave_documents_ids" widget="preview_many2many"
|
||||
options="{'preview_type': 'button', 'preview_string': '查看详情'}"/>
|
||||
<field name="custom_document_ids" widget="preview_many2many"
|
||||
options="{'show_select_btn': false}"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
@@ -105,7 +89,6 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Search View -->
|
||||
<record id="hr_leave_batch_search_view" model="ir.ui.view">
|
||||
<field name="model">hr.leave.batch</field>
|
||||
<field name="arch" type="xml">
|
||||
@@ -125,7 +108,6 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Action My Time Off -->
|
||||
<record id="hr_leave_batch_action_my" model="ir.actions.act_window">
|
||||
<field name="name">我的休假</field>
|
||||
<field name="res_model">hr.leave.batch</field>
|
||||
@@ -139,10 +121,8 @@
|
||||
id="hr_holidays.hr_leave_menu_my"
|
||||
parent="hr_holidays.menu_hr_holidays_my_leaves"
|
||||
action="hr_leave_batch_action_my"
|
||||
sequence="2"
|
||||
/>
|
||||
sequence="2"/>
|
||||
|
||||
<!-- Action My Time Off -->
|
||||
<record id="hr_leave_batch_action_all" model="ir.actions.act_window">
|
||||
<field name="name">所有休息时间</field>
|
||||
<field name="res_model">hr.leave.batch</field>
|
||||
@@ -156,8 +136,7 @@
|
||||
id="hr_holidays.menu_open_department_leave_approve"
|
||||
parent="hr_holidays.menu_hr_holidays_management"
|
||||
action="hr_leave_batch_action_all"
|
||||
sequence="1"
|
||||
/>
|
||||
sequence="1"/>
|
||||
|
||||
|
||||
</data>
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<!-- 此处在前端改了,把假期余额的form视图修改把div class="o_row" 和 di class="o_td_label"删除 添加<field name="start_time"/>
|
||||
和<field name="end_time">-->
|
||||
</odoo>
|
||||
@@ -11,8 +11,8 @@ class YuthonDutyArrangement(models.Model):
|
||||
|
||||
employee_id = fields.Many2one('hr.employee', string='员工',
|
||||
domain=lambda self: [('department_id.name', '=', '仓储组')])
|
||||
start_time = fields.Datetime(string="开始时间")
|
||||
end_time = fields.Datetime(string="结束时间")
|
||||
start_time = fields.Date(string="开始日期")
|
||||
end_time = fields.Date(string="结束日期")
|
||||
remind = fields.Selection([('fifteen', '提醒-15分钟'), ('thirty', '提醒-30分钟'), ('one_hour', '提醒-1小时'),
|
||||
('two_hour', '提醒-2小时')], string='提醒')
|
||||
remarks = fields.Text(string='备注')
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import {Component, markup, useState} from "@odoo/owl";
|
||||
// odoo\addons\web\static\src\views\view_dialogs\select_create_dialog.js
|
||||
export class SelectCreateDialog extends Component {
|
||||
setup() {
|
||||
this.viewService = useService("view");
|
||||
this.dialogService = useService("dialog");
|
||||
this.state = useState({ resIds: [] });
|
||||
// ℹ️ `_t` can only be inlined directly inside JS template literals
|
||||
// after Babel has been updated to version 2.12.
|
||||
const translatedText = _t("No records found!");
|
||||
this.busy = false; // flag used to ensure we only call once the onSelected/onUnselect props
|
||||
this.baseViewProps = {
|
||||
display: { searchPanel: true }, // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
editable: false, // readonly
|
||||
noBreadcrumbs: true,
|
||||
noContentHelp: markup(`<p>${escape(translatedText)}</p>`),
|
||||
showButtons: false,
|
||||
selectRecord: (resId) => this.select([resId]),
|
||||
onSelectionChanged: (resIds) => {
|
||||
this.state.resIds = resIds;
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
<!--odoo\addons\web\static\src\views\form\form_status_indicator\form_status_indicator.xml-->
|
||||
<t t-name="web.FormStatusIndicator">
|
||||
<div class="o_form_status_indicator d-md-flex align-items-center align-self-md-end me-auto" t-att-class="{ o_form_status_indicator_new_record: props.model.root.isNew }">
|
||||
<div class="o_form_status_indicator_buttons d-flex" t-att-class="{ invisible: !(props.model.root.isNew or displayButtons) }">
|
||||
<button
|
||||
type="button"
|
||||
class="o_form_button_save btn btn-light px-1 py-0 lh-sm"
|
||||
data-hotkey="s"
|
||||
t-on-click.stop="save"
|
||||
data-tooltip="Save manually"
|
||||
style="background-color: blue !important;color: white !important;"
|
||||
aria-label="Save manually"
|
||||
t-ref="save">
|
||||
<i class="fa fa-cloud-upload fa-fw"/>
|
||||
保存
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="o_form_button_cancel btn btn-light px-1 py-0 lh-sm"
|
||||
data-hotkey="j"
|
||||
t-on-click.stop="discard"
|
||||
data-tooltip="Discard changes"
|
||||
style="background-color: red !important;color: white !important;"
|
||||
aria-label="Discard changes">
|
||||
<i class="fa fa-undo fa-fw"/>
|
||||
取消
|
||||
</button>
|
||||
</div>
|
||||
<span
|
||||
t-if="!props.model.root.isNew and indicatorMode === 'invalid'"
|
||||
class="text-danger small ms-2"
|
||||
data-tooltip="Unable to save. Correct the issue or discard changes">
|
||||
<i class="fa fa-warning" />
|
||||
</span>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
Reference in New Issue
Block a user