Accept Merge Request #1143: (feature/优化制造功能 -> develop)
Merge Request: 增加工单模块 Created By: @马广威 Accepted By: @马广威 URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1143?initial=true
This commit is contained in:
5
jikimo_system_order/__init__.py
Normal file
5
jikimo_system_order/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import controllers
|
||||||
|
from . import models
|
||||||
|
from . import wizard
|
||||||
38
jikimo_system_order/__manifest__.py
Normal file
38
jikimo_system_order/__manifest__.py
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
{
|
||||||
|
'name': "jikimo_system_order",
|
||||||
|
|
||||||
|
'summary': """
|
||||||
|
系统工单""",
|
||||||
|
|
||||||
|
'description': """
|
||||||
|
用于处理针对系统的工作任务;
|
||||||
|
员工可以通过系统工单发起申请,由维护人员处理以后,填写处理结果。
|
||||||
|
""",
|
||||||
|
|
||||||
|
'author': "机企猫",
|
||||||
|
'website': "http://www.jikimo.com",
|
||||||
|
|
||||||
|
# Categories can be used to filter modules in modules listing
|
||||||
|
# Check https://github.com/odoo/odoo/blob/master/odoo/addons/base/module/module_data.xml
|
||||||
|
# for the full list
|
||||||
|
'category': 'Uncategorized',
|
||||||
|
'version': '0.1',
|
||||||
|
|
||||||
|
# any module necessary for this one to work correctly
|
||||||
|
'depends': ['base','mail'],
|
||||||
|
|
||||||
|
# always loaded
|
||||||
|
'data': [
|
||||||
|
'security/account_security.xml',
|
||||||
|
'security/ir.model.access.csv',
|
||||||
|
'wizard/order_wizard.xml',
|
||||||
|
'views/notice_user_config.xml',
|
||||||
|
'views/yizuo_system_order_view.xml',
|
||||||
|
'views/work_order_number.xml',
|
||||||
|
],
|
||||||
|
# only loaded in demonstration mode
|
||||||
|
'demo': [
|
||||||
|
'demo/demo.xml',
|
||||||
|
],
|
||||||
|
}
|
||||||
3
jikimo_system_order/controllers/__init__.py
Normal file
3
jikimo_system_order/controllers/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import controllers
|
||||||
20
jikimo_system_order/controllers/controllers.py
Normal file
20
jikimo_system_order/controllers/controllers.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from odoo import http
|
||||||
|
|
||||||
|
# class TopSystemOrder(http.Controller):
|
||||||
|
# @http.route('/jikimo_system_order/jikimo_system_order/', auth='public')
|
||||||
|
# def index(self, **kw):
|
||||||
|
# return "Hello, world"
|
||||||
|
|
||||||
|
# @http.route('/jikimo_system_order/jikimo_system_order/objects/', auth='public')
|
||||||
|
# def list(self, **kw):
|
||||||
|
# return http.request.render('jikimo_system_order.listing', {
|
||||||
|
# 'root': '/jikimo_system_order/jikimo_system_order',
|
||||||
|
# 'objects': http.request.env['jikimo_system_order.jikimo_system_order'].search([]),
|
||||||
|
# })
|
||||||
|
|
||||||
|
# @http.route('/jikimo_system_order/jikimo_system_order/objects/<model("jikimo_system_order.jikimo_system_order"):obj>/', auth='public')
|
||||||
|
# def object(self, obj, **kw):
|
||||||
|
# return http.request.render('jikimo_system_order.object', {
|
||||||
|
# 'object': obj
|
||||||
|
# })
|
||||||
30
jikimo_system_order/demo/demo.xml
Normal file
30
jikimo_system_order/demo/demo.xml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<!-- -->
|
||||||
|
<!-- <record id="object0" model="jikimo_system_order.jikimo_system_order"> -->
|
||||||
|
<!-- <field name="name">Object 0</field> -->
|
||||||
|
<!-- <field name="value">0</field> -->
|
||||||
|
<!-- </record> -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- <record id="object1" model="jikimo_system_order.jikimo_system_order"> -->
|
||||||
|
<!-- <field name="name">Object 1</field> -->
|
||||||
|
<!-- <field name="value">10</field> -->
|
||||||
|
<!-- </record> -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- <record id="object2" model="jikimo_system_order.jikimo_system_order"> -->
|
||||||
|
<!-- <field name="name">Object 2</field> -->
|
||||||
|
<!-- <field name="value">20</field> -->
|
||||||
|
<!-- </record> -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- <record id="object3" model="jikimo_system_order.jikimo_system_order"> -->
|
||||||
|
<!-- <field name="name">Object 3</field> -->
|
||||||
|
<!-- <field name="value">30</field> -->
|
||||||
|
<!-- </record> -->
|
||||||
|
<!-- -->
|
||||||
|
<!-- <record id="object4" model="jikimo_system_order.jikimo_system_order"> -->
|
||||||
|
<!-- <field name="name">Object 4</field> -->
|
||||||
|
<!-- <field name="value">40</field> -->
|
||||||
|
<!-- </record> -->
|
||||||
|
<!-- -->
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
6
jikimo_system_order/models/__init__.py
Normal file
6
jikimo_system_order/models/__init__.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import constant
|
||||||
|
from . import order_classify
|
||||||
|
from . import system_work_order
|
||||||
|
from . import work_order_template
|
||||||
7
jikimo_system_order/models/constant.py
Normal file
7
jikimo_system_order/models/constant.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# 工单状态
|
||||||
|
STATE_SELECTION = [('draft', u'草稿'), ('unconfirmed', u'待确认'), ('pending', u'待处理'),
|
||||||
|
('processed', u'已处理待评分'), ('completed', u'已完成'), ('closed', u'已关闭')]
|
||||||
|
|
||||||
|
GRADE = [('1', '1非常不满意'), ('2', '2不满意'), ('3', '3一般'), ('4', '4满意'), ('5', '5非常满意')]
|
||||||
25
jikimo_system_order/models/order_classify.py
Normal file
25
jikimo_system_order/models/order_classify.py
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from odoo import models, fields, api
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
|
||||||
|
|
||||||
|
class OrderClassify(models.Model):
|
||||||
|
_name = 'order.classify'
|
||||||
|
_order = 'sequence, name'
|
||||||
|
|
||||||
|
|
||||||
|
@api.constrains('name')
|
||||||
|
def check_base_name(self):
|
||||||
|
"""类型名称唯一"""
|
||||||
|
name_obj = self.env['order.classify'].search([('name', '=', self.name)])
|
||||||
|
if len(name_obj) >= 2:
|
||||||
|
raise ValidationError(u'该类型已存在')
|
||||||
|
|
||||||
|
# 名称
|
||||||
|
name = fields.Char(string=u'名称', size=20)
|
||||||
|
# 排序
|
||||||
|
sequence = fields.Integer(default=10)
|
||||||
|
# 是否有效
|
||||||
|
state = fields.Boolean(default=True, string='是否有效')
|
||||||
|
|
||||||
183
jikimo_system_order/models/system_work_order.py
Normal file
183
jikimo_system_order/models/system_work_order.py
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from odoo import models, fields, api
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
from odoo import exceptions
|
||||||
|
from .constant import STATE_SELECTION, GRADE
|
||||||
|
import datetime
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
class SystemWorkOrder(models.Model):
|
||||||
|
_name = 'system.work.order'
|
||||||
|
_inherit = ['mail.thread', 'mail.activity.mixin']
|
||||||
|
_order = 'date desc'
|
||||||
|
_description = u'系统工单'
|
||||||
|
_rec_name = 'order_number'
|
||||||
|
|
||||||
|
def get_is_technicist(self):
|
||||||
|
self._cr.execute(
|
||||||
|
"select u.id from res_users u left join res_groups_users_rel r on r.uid = u.id where r.gid in (select g.id from res_groups g where g.name = '技术员权限') and u.id ='%s'",
|
||||||
|
(self.env.user.id,))
|
||||||
|
hr = self._cr.dictfetchall()
|
||||||
|
if len(hr) > 0:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# def get_user_department_id(self):
|
||||||
|
# """根据用户id系统员工id"""
|
||||||
|
# employee = self.env['hr.employee'].sudo().search([('user_id', '=', self.env.uid)], limit=1)
|
||||||
|
# if employee:
|
||||||
|
# if len(employee) > 0:
|
||||||
|
# if not employee.department_id:
|
||||||
|
# raise exceptions.Warning(u'您当前使用的用户没有所属部门')
|
||||||
|
# return employee.department_id
|
||||||
|
# else:
|
||||||
|
# return False
|
||||||
|
# else:
|
||||||
|
# raise exceptions.Warning(u'您当前使用的用户没有关联员工')
|
||||||
|
|
||||||
|
@api.onchange('order_template_id')
|
||||||
|
def get_title(self):
|
||||||
|
"""选择模板自动填充"""
|
||||||
|
if self.order_template_id:
|
||||||
|
self.title = self.order_template_id.title_template
|
||||||
|
self.text = self.order_template_id.text_template
|
||||||
|
|
||||||
|
# 工单编号
|
||||||
|
order_number = fields.Char(string=u'工单编号', default='/')
|
||||||
|
# 紧急程度
|
||||||
|
urgency_degree = fields.Selection([('0', u'0星'), ('1', u'一星'), ('2', u'二星'), ('3', u'三星'), ('4', u'四星'),
|
||||||
|
('5', u'五星')], string=u'紧急程度', help='五星为最紧急!', default='5')
|
||||||
|
# 工单分类(可以配置,并调整优先级)
|
||||||
|
order_type = fields.Many2one('order.classify', string=u'工单分类', domain=[('state', '=', True)])
|
||||||
|
# 发起人所属公司(res.company)
|
||||||
|
initiator_company_id = fields.Many2one('res.company', string=u'发起人所属公司', default=lambda self: self.env.user.company_id)
|
||||||
|
# 发起人部门(hr.department)
|
||||||
|
# initiator_department_id = fields.Many2one('hr.department', string=u'发起人部门', default=get_user_department_id)
|
||||||
|
# 发起人(hr.employee)
|
||||||
|
initiator_id = fields.Many2one('res.users', string=u'发起人', default=lambda self: self.env.user)
|
||||||
|
# 发起时间
|
||||||
|
date = fields.Datetime(string=u'发起时间', default=lambda self: fields.datetime.now())
|
||||||
|
# 确认人
|
||||||
|
confirm_id = fields.Many2one('res.users', string=u'确认人')
|
||||||
|
# 确认日期
|
||||||
|
confirmation_date = fields.Datetime(string=u'确认时间')
|
||||||
|
# 模板
|
||||||
|
order_template_id = fields.Many2one('work.order.template', string=u'模板', domain=[('state', '=', True)])
|
||||||
|
# 标题
|
||||||
|
title = fields.Char(string=u'标题')
|
||||||
|
# 正文
|
||||||
|
text = fields.Html(string=u'正文')
|
||||||
|
# 状态[草稿\待确认\待处理\已处理\已关闭]
|
||||||
|
state = fields.Selection(STATE_SELECTION, default='draft', string=u'状态')
|
||||||
|
# 关闭原因
|
||||||
|
close_cause = fields.Text(string=u'关闭问题原因')
|
||||||
|
# 关闭时间
|
||||||
|
close_time = fields.Datetime(string=u'关闭问题时间')
|
||||||
|
# 关闭人
|
||||||
|
close_user_id = fields.Many2one('res.users', string=u'关闭人')
|
||||||
|
# 解决人
|
||||||
|
solve_people_id = fields.Many2one('res.users', string=u'解决人')
|
||||||
|
# 用户实际问题
|
||||||
|
users_problem = fields.Text(string=u'用户实际问题')
|
||||||
|
# 最终解决方案
|
||||||
|
solution = fields.Text(string=u'最终解决方案')
|
||||||
|
# 判断是否为技术人员
|
||||||
|
is_technicist = fields.Boolean(string=u'是否为技术人员', default=get_is_technicist)
|
||||||
|
# 打分
|
||||||
|
grade = fields.Selection(GRADE, string=u'评分')
|
||||||
|
# 评价按钮的显示
|
||||||
|
is_display = fields.Boolean('控制显示评价按钮', compute='compute_is_display')
|
||||||
|
|
||||||
|
def compute_is_display(self):
|
||||||
|
for item in self:
|
||||||
|
if item.state == 'processed' and self.env.user.id == item.initiator_id.id:
|
||||||
|
item.is_display = True
|
||||||
|
else:
|
||||||
|
item.is_display = False
|
||||||
|
|
||||||
|
@api.onchange('order_type')
|
||||||
|
def _onchange_order_type(self):
|
||||||
|
self.order_template_id = None
|
||||||
|
self.title = None
|
||||||
|
self.text = None
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def create(self, vals):
|
||||||
|
# 创建编号
|
||||||
|
if vals.get('order_number', '/') == '/':
|
||||||
|
vals['order_number'] = self.env['ir.sequence'].get('system.work.order') or '/'
|
||||||
|
return super(SystemWorkOrder, self).create(vals)
|
||||||
|
|
||||||
|
def do_draft(self, order=None):
|
||||||
|
"""状态草稿"""
|
||||||
|
bill = self
|
||||||
|
if order:
|
||||||
|
bill = order
|
||||||
|
if bill.state == 'unconfirmed':
|
||||||
|
state_remark = u'待确认 --> 草稿'
|
||||||
|
# bill.message_post(u'操作人:%s,操作时间:%s,状态变更过程:%s' % (self.env.user.name,
|
||||||
|
# (datetime.datetime.now() + datetime.timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S'), state_remark))
|
||||||
|
bill.state = 'draft'
|
||||||
|
|
||||||
|
def do_unconfirmed(self):
|
||||||
|
"""状态待确认"""
|
||||||
|
if self.state == 'draft':
|
||||||
|
state_remark = u'草稿 --> 待确认'
|
||||||
|
# self.message_post(u'操作人:%s,操作时间:%s,状态变更过程:%s' % (
|
||||||
|
# self.env.user.name,
|
||||||
|
# (datetime.datetime.now() + datetime.timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S'), state_remark))
|
||||||
|
self.state = 'unconfirmed'
|
||||||
|
# 获取通知人
|
||||||
|
objs = self.env['system.order.notice'].search([])
|
||||||
|
user_ids = objs.notice_user_ids.filtered(lambda item: item.we_employee_id not in ['', False])
|
||||||
|
we_employee_ids = user_ids.mapped('we_employee_id')
|
||||||
|
lost_agent_id = self.env['ir.config_parameter'].sudo().get_param('lost_agent_id')
|
||||||
|
wechat = self.env['we.config'].sudo().get_wechat(agent_id=lost_agent_id)
|
||||||
|
# agent_id, user_ids, content
|
||||||
|
content = """您有一张工单<font color=\"warning\">待处理</font>:**工单标题:{2}**
|
||||||
|
>创建人:{1}
|
||||||
|
>提交时间:{3}
|
||||||
|
>紧急程度:{0}星
|
||||||
|
请查看工单消息,并及时处理!
|
||||||
|
""".format(self.urgency_degree,
|
||||||
|
self.initiator_id.name, self.title, (self.date + datetime.timedelta(hours=8)).strftime('%Y-%m-%d %H:%M'))
|
||||||
|
for we_employee_id in we_employee_ids:
|
||||||
|
try:
|
||||||
|
wechat.message.send_markdown(agent_id=lost_agent_id, user_ids=we_employee_id, content=content)
|
||||||
|
except Exception as e:
|
||||||
|
logging.error('工单处理发送消息异常%s' % str(e))
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def do_pending(self):
|
||||||
|
"""状态待处理"""
|
||||||
|
if self.state == 'unconfirmed':
|
||||||
|
state_remark = u'待确认 --> 待处理'
|
||||||
|
# self.message_post(u'操作人:%s,操作时间:%s,状态变更过程:%s' % (
|
||||||
|
# self.env.user.name,
|
||||||
|
# (datetime.datetime.now() + datetime.timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S'), state_remark))
|
||||||
|
self.state = 'pending'
|
||||||
|
self.confirm_id = self.env.user
|
||||||
|
self.confirmation_date = fields.datetime.now()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def urned_off(self):
|
||||||
|
"""状态关闭"""
|
||||||
|
if self.close_cause:
|
||||||
|
self.state = 'closed'
|
||||||
|
self.close_time = fields.datetime.now()
|
||||||
|
else:
|
||||||
|
raise ValidationError(u'请注明关闭原因')
|
||||||
|
return True
|
||||||
|
|
||||||
|
def unlink(self):
|
||||||
|
for item in self:
|
||||||
|
if item.state != "draft":
|
||||||
|
raise ValidationError(u'只能删除状态为【草稿】的工单。')
|
||||||
|
elif item.env.uid != item.initiator_id.id:
|
||||||
|
raise ValidationError(u'非本人不能删除')
|
||||||
|
else:
|
||||||
|
super(SystemWorkOrder, item).unlink()
|
||||||
38
jikimo_system_order/models/work_order_template.py
Normal file
38
jikimo_system_order/models/work_order_template.py
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from odoo import models, fields, api
|
||||||
|
|
||||||
|
|
||||||
|
class WorkOrderTemplate(models.Model):
|
||||||
|
_name = 'work.order.template'
|
||||||
|
_order = 'num'
|
||||||
|
|
||||||
|
# 编号
|
||||||
|
num = fields.Char(string=u'编号', default='/')
|
||||||
|
# 名称
|
||||||
|
name = fields.Char(string=u'模板名称', required="1")
|
||||||
|
# 分类
|
||||||
|
work_order_type = fields.Many2one('order.classify', string=u'系统工单分类', domain=[('state', '=', True)])
|
||||||
|
# 模板标题
|
||||||
|
title_template = fields.Char(string=u'模板标题')
|
||||||
|
# 模板正文
|
||||||
|
text_template = fields.Html(string=u'模板正文')
|
||||||
|
# 模板说明
|
||||||
|
template_explain = fields.Text(string=u'模板说明')
|
||||||
|
# 是否有效
|
||||||
|
state = fields.Boolean(default=True, string=u'是否有效')
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def create(self, vals):
|
||||||
|
# 创建编号
|
||||||
|
if vals.get('num', '/') == '/':
|
||||||
|
vals['num'] = self.env['ir.sequence'].get('work.order.template') or '/'
|
||||||
|
return super(WorkOrderTemplate, self).create(vals)
|
||||||
|
|
||||||
|
|
||||||
|
class SystemOrderNotice(models.Model):
|
||||||
|
_name = 'system.order.notice'
|
||||||
|
_description = '工单处理人设置'
|
||||||
|
|
||||||
|
notice_user_ids = fields.Many2many('res.users', string='工单处理人')
|
||||||
|
|
||||||
24
jikimo_system_order/security/account_security.xml
Normal file
24
jikimo_system_order/security/account_security.xml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data noupdate="0"> <!-- noupdate表示,当模块升级时是否更新本条数据-->
|
||||||
|
<!--运维权限组-->
|
||||||
|
<record id="group_operations_permissions_rwc" model="res.groups">
|
||||||
|
<field name="name">运维权限</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="system_order_user_rule" model="ir.rule">
|
||||||
|
<field name="name">用户访问工单信息</field>
|
||||||
|
<field name="model_id" ref="model_system_work_order"/>
|
||||||
|
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
|
||||||
|
<field name="domain_force">[('initiator_id', '=', user.id)]</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="system_order_group_operations_rule" model="ir.rule">
|
||||||
|
<field name="name">运维访问工单信息</field>
|
||||||
|
<field name="model_id" ref="model_system_work_order"/>
|
||||||
|
<field name="groups" eval="[(4, ref('jikimo_system_order.group_operations_permissions_rwc'))]"/>
|
||||||
|
<field name="domain_force">[(1, '=', 1)]</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
16
jikimo_system_order/security/ir.model.access.csv
Normal file
16
jikimo_system_order/security/ir.model.access.csv
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||||
|
|
||||||
|
inside_system_order_classify_r,jikimo_system_order.order_classify,model_order_classify,,1,1,1,1
|
||||||
|
inside_system_work_order_rc,jikimo_system_order.system_work_order,model_system_work_order,,1,1,1,1
|
||||||
|
inside_work_order_template_r,jikimo_system_order.work_order_template,model_work_order_template,,1,1,1,1
|
||||||
|
|
||||||
|
inside_system_order_classify_rwc,jikimo_system_order.order_classify,model_order_classify,group_operations_permissions_rwc,1,1,1,0
|
||||||
|
inside_system_work_order_rwc,jikimo_system_order.system_work_order,model_system_work_order,group_operations_permissions_rwc,1,1,1,0
|
||||||
|
inside_work_order_template_rwc,jikimo_system_order.work_order_template,model_work_order_template,group_operations_permissions_rwc,1,1,1,0
|
||||||
|
|
||||||
|
order_close_wizard_group_user,jikimo_system_order.order_close_wizard,model_order_close_wizard,base.group_user,1,1,1,1
|
||||||
|
order_other_wizard_group_user,jikimo_system_order.order_other_wizard,model_order_other_wizard,base.group_user,1,1,1,1
|
||||||
|
order_technician_wizard_group_user,jikimo_system_order.order_technician_wizard,model_order_technician_wizard,base.group_user,1,1,1,1
|
||||||
|
system_work_order_wizard_group_user,jikimo_system_order.system_work_order_wizard,model_system_work_order_wizard,base.group_user,1,1,1,1
|
||||||
|
|
||||||
|
system_order_notice_group_user,jikimo_system_order.system_order_notice,model_system_order_notice,base.group_user,1,1,1,1
|
||||||
|
BIN
jikimo_system_order/static/description/icon.png
Normal file
BIN
jikimo_system_order/static/description/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
58
jikimo_system_order/views/notice_user_config.xml
Normal file
58
jikimo_system_order/views/notice_user_config.xml
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
# ---------- 工单通知处理人设置 ------------
|
||||||
|
|
||||||
|
<record model="ir.ui.view" id="tree_system_order_notice_view">
|
||||||
|
<field name="name">tree.system.order.notice</field>
|
||||||
|
<field name="model">system.order.notice</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<tree string="工单处理人设置" editable="top">
|
||||||
|
<field name="notice_user_ids" widget="many2many_tags" required="1" options="{'no_create': True, 'no_edit': True}"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
<record model="ir.ui.view" id="search_system_order_notice_view">
|
||||||
|
<field name="name">search.system.order.notice</field>
|
||||||
|
<field name="model">system.order.notice</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<search string="工单处理人设置">
|
||||||
|
<field name="notice_user_ids" string="模糊搜索"
|
||||||
|
filter_domain="[('notice_user_ids', 'ilike', self)]"/>
|
||||||
|
<separator></separator>
|
||||||
|
|
||||||
|
<field name="notice_user_ids" string="处理人"/>
|
||||||
|
|
||||||
|
</search>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
<record model="ir.actions.act_window" id="action_system_order_notice_view">
|
||||||
|
<field name="name">工单处理人</field>
|
||||||
|
<field name="res_model">system.order.notice</field>
|
||||||
|
<field name="view_mode">tree</field>
|
||||||
|
<field name="domain">[]</field>
|
||||||
|
<field name="context">{}</field>
|
||||||
|
<field name="help" type="html">
|
||||||
|
<p class="o_view_nocontent_smiling_face">
|
||||||
|
[工单处理人] 还没有哦!点左上角的[创建]按钮,沙发归你了!
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
</p>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
23
jikimo_system_order/views/work_order_number.xml
Normal file
23
jikimo_system_order/views/work_order_number.xml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<odoo>
|
||||||
|
<data noupdate="True">
|
||||||
|
<!-- 工单流水号 -->
|
||||||
|
<record id="seq_work_order" model="ir.sequence">
|
||||||
|
<field name="name">seq_work_order</field>
|
||||||
|
<field name="company_id"/>
|
||||||
|
<field name="code">system.work.order</field>
|
||||||
|
<field name="prefix">SO%(year)s%(month)s%(day)s</field>
|
||||||
|
<field name="padding">1</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- 模板编号 -->
|
||||||
|
<record id="seq_order_template" model="ir.sequence">
|
||||||
|
<field name="name">seq_order_template</field>
|
||||||
|
<field name="company_id"/>
|
||||||
|
<field name="code">work.order.template</field>
|
||||||
|
<field name="prefix">TL</field>
|
||||||
|
<field name="padding">1</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
243
jikimo_system_order/views/yizuo_system_order_view.xml
Normal file
243
jikimo_system_order/views/yizuo_system_order_view.xml
Normal file
@@ -0,0 +1,243 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<!--工单信息-->
|
||||||
|
<record model="ir.ui.view" id="work_order_tree">
|
||||||
|
<field name="name">工单信息</field>
|
||||||
|
<field name="model">system.work.order</field><!--对应表单名称-->
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<tree>
|
||||||
|
<field name="state" widget="badge" decoration-primary="state == 'draft'"
|
||||||
|
decoration-success="state in ('processed', 'completed')"
|
||||||
|
decoration-danger="state == 'pending'" decoration-warning="state in ('unconfirmed')"/>
|
||||||
|
<field name="order_number"/>
|
||||||
|
<field name="title"/>
|
||||||
|
<field name="initiator_id"/>
|
||||||
|
<field name="date"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!--新建系统工单-->
|
||||||
|
<record model="ir.ui.view" id="ork_order_form">
|
||||||
|
<field name="name">新建系统工单</field>
|
||||||
|
<field name="model">system.work.order</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form>
|
||||||
|
<header>
|
||||||
|
<field name="is_display" invisible="1"/>
|
||||||
|
<button string='提交' class="oe_read_only oe_highlight" states="draft"
|
||||||
|
type="object" name="do_unconfirmed"
|
||||||
|
attrs="{'invisible': [('state', '!=', 'draft')]}"/>
|
||||||
|
<button string='追回编辑' states="unconfirmed"
|
||||||
|
type="action" name="%(system_work_order_wizard_view_act_window)d"
|
||||||
|
context="{'explain':'确认要执行此操作吗?','object_name':'system.work.order','function_name':'do_draft','object_id':id}"/>
|
||||||
|
|
||||||
|
<button name="do_pending" states="unconfirmed"
|
||||||
|
string="确认可处理" type="object" class="oe_highlight"
|
||||||
|
groups="jikimo_system_order.group_operations_permissions_rwc"/>
|
||||||
|
|
||||||
|
<button string='处理工单' class="oe_highlight" states="pending"
|
||||||
|
type="action" name="%(launch_order_technician_wizard)d"
|
||||||
|
groups="jikimo_system_order.group_operations_permissions_rwc"/>
|
||||||
|
<button string='评价' class="oe_highlight" attrs="{'invisible': [('is_display', '=', False)]}"
|
||||||
|
type="action" name="%(launch_order_other_wizard)d" context="{'active_id':id}"/>
|
||||||
|
<button name="%(launch_order_close_wizard)d" string="关闭该工单"
|
||||||
|
attrs="{'invisible': ['|',('state', '=', 'draft'),'|',('state','=','completed'),('state','=','closed')]}"
|
||||||
|
type="action" context="{'active_id':id}"/>
|
||||||
|
|
||||||
|
<field name="state" widget="statusbar"/>
|
||||||
|
</header>
|
||||||
|
<sheet>
|
||||||
|
<group>
|
||||||
|
<!-- <label for="order_number" class="oe_edit_only"/>-->
|
||||||
|
<group>
|
||||||
|
<field name="order_number" required="True" readonly="1"/>
|
||||||
|
<field name="order_type" required="True" attrs="{'readonly': [('state', '!=', 'draft')]}" options="{'no_create': True}"/>
|
||||||
|
<field name="date" required="True" readonly="True"/>
|
||||||
|
<field name="order_template_id" attrs="{'readonly': [('state', '!=', 'draft')]}"
|
||||||
|
domain="[('work_order_type','=',order_type),('state','=',True)]" options="{'no_create': True}"/>
|
||||||
|
<field name="confirmation_date" readonly="True"/>
|
||||||
|
<field name="urgency_degree" required="True" attrs="{'readonly': [('state','!=','draft')]}" widget="priority"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="initiator_company_id" required="True" readonly="True"/>
|
||||||
|
<!-- <field name="initiator_department_id" required="True" readonly="True"/>-->
|
||||||
|
<field name="initiator_id" required="True" readonly="True"/>
|
||||||
|
<field name="confirm_id" readonly="True"/>
|
||||||
|
<field name="solve_people_id" readonly="True"/>
|
||||||
|
<field name="close_user_id" readonly="True"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="title" attrs="{'readonly': [('state', '!=', 'draft')]}" required="True"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<notebook>
|
||||||
|
<page string="工单内容">
|
||||||
|
<field name="text" attrs="{'readonly': [('state','!=','draft')]}" required="True"/>
|
||||||
|
</page>
|
||||||
|
<page string="解决方案">
|
||||||
|
<group>
|
||||||
|
<field name="users_problem" readonly="True"/>
|
||||||
|
<field name="solution" readonly="True"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
<page string="其他">
|
||||||
|
<group>
|
||||||
|
<field name="close_cause" readonly="True"/>
|
||||||
|
<field name="close_time" readonly="True"/>
|
||||||
|
<field name="grade" readonly="True"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
</sheet>
|
||||||
|
<!-- <div class="oe_chatter">-->
|
||||||
|
<!-- <field name="message_follower_ids" widget="mail_followers"/>-->
|
||||||
|
<!-- <field name="message_ids" widget="mail_thread"/>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- 搜索工单 -->
|
||||||
|
<record model="ir.ui.view" id="restaurant_search">
|
||||||
|
<field name="name">搜索工单</field>
|
||||||
|
<field name="model">system.work.order</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<search>
|
||||||
|
<field string='发起人' name="initiator_id" widget="char" required="True"/>
|
||||||
|
<field string='标题' name="title" widget="char"/>
|
||||||
|
<field string='正文' name="text" widget="html"/>
|
||||||
|
<field string='实际问题' name="users_problem" widget="text"/>
|
||||||
|
<field string='解决方案' name="solution" widget="text"/>
|
||||||
|
<filter name="today" string="今日工单" domain="[('date','=',time.strftime('%%Y-%%m-%%d'))]"/>
|
||||||
|
<filter name="yesterday" string="昨日工单"
|
||||||
|
domain="[('date', '=', (context_today() - relativedelta(days=1)).strftime('%Y-%m-%d'))]"/>
|
||||||
|
<filter name="month" string="本月工单"
|
||||||
|
domain="[('date','>=', time.strftime('%Y-%m-01')),('date','<', (context_today() + relativedelta(months=1)).strftime('%Y-%m-01'))]"/>
|
||||||
|
<filter name="last_month" string="上月工单"
|
||||||
|
domain="[('date','<', time.strftime('%Y-%m-01')),('date','>=', (context_today() - relativedelta(months=1)).strftime('%Y-%m-01'))]"/>
|
||||||
|
<filter name="unconfirmed" string="待确认" domain="[('state','=','unconfirmed')]"/>
|
||||||
|
<filter name="pending" string="待处理" domain="[('state','=','pending')]"/>
|
||||||
|
<filter name="processed" string="已处理"
|
||||||
|
domain="['|', ('state','=','processed'), ('state','=','closed')]"/>
|
||||||
|
<group>
|
||||||
|
<filter string='发起人' name="initiator_id" context='{"group_by":"initiator_id"}'/>
|
||||||
|
<filter string='工单分类' name="order_type" context='{"group_by":"order_type"}'/>
|
||||||
|
<filter string='模板' name="order_template_id" context='{"group_by":"order_template_id"}'/>
|
||||||
|
<filter string='状态' name="state" context='{"group_by":"state"}'/>
|
||||||
|
<filter string='紧急情况' name="state" context='{"group_by":"urgency_degree"}'/>
|
||||||
|
</group>
|
||||||
|
</search>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.ui.view" id="graph_tree">
|
||||||
|
<field name="name">工单图表</field>
|
||||||
|
<field name="model">system.work.order</field><!--对应表单名称-->
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<pivot>
|
||||||
|
<field name="date" type="row" interval="day"/>
|
||||||
|
<field name="order_type" type="col"/>
|
||||||
|
<field name="state" type="row"/>
|
||||||
|
</pivot>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- 工单 -->
|
||||||
|
<record model="ir.actions.act_window" id="system_order">
|
||||||
|
<field name="name">工单</field>
|
||||||
|
<field name="res_model">system.work.order</field>
|
||||||
|
<field name="view_mode">tree,form,search,graph,pivot</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!--工单模板信息-->
|
||||||
|
<record model="ir.ui.view" id="order_template_tree">
|
||||||
|
<field name="name">工单模板信息</field>
|
||||||
|
<field name="model">work.order.template</field><!--对应表单名称-->
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<tree>
|
||||||
|
<field name="num"/>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="work_order_type"/>
|
||||||
|
<field name="title_template"/>
|
||||||
|
<field name="template_explain"/>
|
||||||
|
<field name="state"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!--新建系统工单模板-->
|
||||||
|
<record model="ir.ui.view" id="order_template_form">
|
||||||
|
<field name="name">新建系统工单模板</field>
|
||||||
|
<field name="model">work.order.template</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form>
|
||||||
|
<sheet>
|
||||||
|
<group>
|
||||||
|
<field name="num" required="True" readonly="True"/>
|
||||||
|
<field name="name" required="True"/>
|
||||||
|
<field name="work_order_type" required="True"/>
|
||||||
|
<field name="template_explain" required="True" style="height: 50px;"/>
|
||||||
|
<field name="title_template" required="True"/>
|
||||||
|
<field name="state"/>
|
||||||
|
<field name="text_template" required="True"/>
|
||||||
|
</group>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- 工单模板 -->
|
||||||
|
<record model="ir.actions.act_window" id="work_template">
|
||||||
|
<field name="name">工单模板</field>
|
||||||
|
<field name="res_model">work.order.template</field>
|
||||||
|
<field name="view_mode">tree,form</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!--工单分类信息-->
|
||||||
|
<record model="ir.ui.view" id="order_type_tree">
|
||||||
|
<field name="name">工单分类信息</field>
|
||||||
|
<field name="model">order.classify</field><!--对应表单名称-->
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<tree>
|
||||||
|
<field name="sequence" widget="handle"/>
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="state"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!--新建系统分类信息-->
|
||||||
|
<record model="ir.ui.view" id="order_type_form">
|
||||||
|
<field name="name">新建系统分类信息</field>
|
||||||
|
<field name="model">order.classify</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form>
|
||||||
|
<sheet>
|
||||||
|
<group>
|
||||||
|
<field name="name" required="True"/>
|
||||||
|
<field name="sequence" invisible="True"/>
|
||||||
|
<field name="state"/>
|
||||||
|
</group>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- 工单分类 -->
|
||||||
|
<record model="ir.actions.act_window" id="classify">
|
||||||
|
<field name="name">工单分类</field>
|
||||||
|
<field name="res_model">order.classify</field>
|
||||||
|
<field name="view_mode">tree,form</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
<menuitem name="系统工单" id="work_order_1_list" web_icon="jikimo_system_order,static/description/icon.png"/>
|
||||||
|
<menuitem name="工单" id="work_order" parent="work_order_1_list" action="system_order"/>
|
||||||
|
<menuitem name="工单模板" id="work_order_template" parent="work_order_1_list" action="work_template" groups="jikimo_system_order.group_operations_permissions_rwc"/>
|
||||||
|
<menuitem name="工单分类" id="work_order_type" parent="work_order_1_list" action="classify" groups="jikimo_system_order.group_operations_permissions_rwc"/>
|
||||||
|
<menuitem name="工单设置" id="system_order_notice_user_config" parent="work_order_1_list" action="action_system_order_notice_view" groups="jikimo_system_order.group_operations_permissions_rwc"/>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
6
jikimo_system_order/wizard/__init__.py
Normal file
6
jikimo_system_order/wizard/__init__.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import order_other_wizard
|
||||||
|
from . import order_technician_wizard
|
||||||
|
from . import order_close_wizard
|
||||||
|
from . import system_work_order_wizard
|
||||||
79
jikimo_system_order/wizard/order_close_wizard.py
Normal file
79
jikimo_system_order/wizard/order_close_wizard.py
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from odoo import models, fields, api
|
||||||
|
from odoo.addons.jikimo_system_order.models.constant import STATE_SELECTION
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
import datetime, logging
|
||||||
|
|
||||||
|
|
||||||
|
class OrderCloseWizard(models.TransientModel):
|
||||||
|
_name = 'order.close.wizard'
|
||||||
|
|
||||||
|
|
||||||
|
def get_context(self):
|
||||||
|
if self._context.get('active_id'):
|
||||||
|
obj = self.env['system.work.order'].browse(self._context.get('active_id'))
|
||||||
|
if obj.initiator_id.id != self.env.user.id:
|
||||||
|
raise ValidationError(u'非本人无法操作')
|
||||||
|
return obj
|
||||||
|
|
||||||
|
order_id = fields.Many2one('system.work.order', string=u'工单ID',
|
||||||
|
default=lambda self: self.get_context().id)
|
||||||
|
# 关闭原因
|
||||||
|
close_cause = fields.Text(string=u'关闭问题原因', default=lambda self: self.get_context().close_cause)
|
||||||
|
# 关闭时间
|
||||||
|
close_time = fields.Datetime(string=u'关闭问题时间', default=fields.datetime.now())
|
||||||
|
# 状态
|
||||||
|
state = fields.Selection(STATE_SELECTION, default='closed', string=u'状态')
|
||||||
|
# 关闭人
|
||||||
|
close_user_id = fields.Many2one('res.users', string=u'关闭人', default=lambda self: self.env.user)
|
||||||
|
|
||||||
|
|
||||||
|
def sure(self):
|
||||||
|
self.order_id.close_cause = self.close_cause
|
||||||
|
self.order_id.close_time = self.close_time
|
||||||
|
if self.order_id.state == 'unconfirmed':
|
||||||
|
state_remark = u'待确认 --> 已关闭'
|
||||||
|
if self.order_id.state == 'pending':
|
||||||
|
state_remark = u'待处理 --> 已关闭'
|
||||||
|
if self.order_id.state == 'processed':
|
||||||
|
state_remark = u'已处理待评分 --> 已关闭'
|
||||||
|
# self.order_id.message_post(u'操作人:%s,操作时间:%s,状态变更过程:%s' % (
|
||||||
|
# self.env.user.name,
|
||||||
|
# (datetime.datetime.now() + datetime.timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S'), state_remark))
|
||||||
|
self.order_id.state = self.state
|
||||||
|
self.order_id.close_user_id = self.close_user_id
|
||||||
|
we_employee_ids = []
|
||||||
|
if self.order_id.initiator_id.we_employee_id:
|
||||||
|
we_employee_ids.append(self.order_id.initiator_id.we_employee_id)
|
||||||
|
lost_agent_id = self.env['ir.config_parameter'].sudo().get_param('lost_agent_id')
|
||||||
|
wechat = self.env['we.config'].sudo().get_wechat(agent_id=lost_agent_id)
|
||||||
|
# agent_id, user_ids, content
|
||||||
|
content = """您提交的工单-**工单标题:{0}**-<font color=\"#FF0000\">**已关闭**</font>
|
||||||
|
>提交时间:{1}
|
||||||
|
>处理时间:{2}
|
||||||
|
>处理人:{3}
|
||||||
|
如有问题,请联系系统管理员!
|
||||||
|
""".format(self.order_id.title,
|
||||||
|
(self.order_id.date + datetime.timedelta(hours=8)).strftime(
|
||||||
|
'%Y-%m-%d %H:%M'), (datetime.datetime.now() + datetime.timedelta(
|
||||||
|
hours=8)).strftime('%Y-%m-%d %H:%M'), self.env.user.name or '')
|
||||||
|
# wechat.message.send_markdown(agent_id=lost_agent_id, user_ids=we_employee_ids, content=content)
|
||||||
|
for we_employee_id in we_employee_ids:
|
||||||
|
try:
|
||||||
|
wechat.message.send_markdown(agent_id=lost_agent_id, user_ids=we_employee_id, content=content)
|
||||||
|
except Exception as e:
|
||||||
|
logging.error('工单关闭发送消息异常%s' % str(e))
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
42
jikimo_system_order/wizard/order_other_wizard.py
Normal file
42
jikimo_system_order/wizard/order_other_wizard.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from odoo import models, fields, api
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
from odoo.addons.jikimo_system_order.models.constant import STATE_SELECTION, GRADE
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
|
class OrderOtherWizard(models.TransientModel):
|
||||||
|
_name = 'order.other.wizard'
|
||||||
|
|
||||||
|
|
||||||
|
def get_context(self):
|
||||||
|
if self._context.get('active_id'):
|
||||||
|
obj = self.env['system.work.order'].browse(self._context.get('active_id'))
|
||||||
|
if obj.initiator_id.id != self.env.user.id:
|
||||||
|
raise ValidationError(u'非本人无法操作')
|
||||||
|
return obj
|
||||||
|
|
||||||
|
order_id = fields.Many2one('system.work.order', string=u'工单ID',
|
||||||
|
default=lambda self: self.get_context().id)
|
||||||
|
# 关闭时间
|
||||||
|
close_time = fields.Datetime(string=u'关闭时间', default=fields.datetime.now())
|
||||||
|
# 状态
|
||||||
|
state = fields.Selection(STATE_SELECTION, default='completed', string=u'状态')
|
||||||
|
# 打分
|
||||||
|
grade = fields.Selection(GRADE, string=u'评分')
|
||||||
|
# 关闭人
|
||||||
|
close_user_id = fields.Many2one('res.users', string=u'关闭人', default=lambda self: self.env.user)
|
||||||
|
|
||||||
|
|
||||||
|
def sure(self):
|
||||||
|
self.order_id.close_time = self.close_time
|
||||||
|
self.order_id.grade = self.grade
|
||||||
|
if self.order_id.state == 'processed':
|
||||||
|
state_remark = u'已处理待评分 --> 已完成'
|
||||||
|
# self.order_id.message_post(u'操作人:%s,操作时间:%s,状态变更过程:%s' % (
|
||||||
|
# self.env.user.name,
|
||||||
|
# (datetime.datetime.now() + datetime.timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S'), state_remark))
|
||||||
|
self.order_id.state = self.state
|
||||||
|
self.order_id.close_user_id = self.close_user_id
|
||||||
|
return {}
|
||||||
59
jikimo_system_order/wizard/order_technician_wizard.py
Normal file
59
jikimo_system_order/wizard/order_technician_wizard.py
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from odoo import models, fields, api
|
||||||
|
from odoo.addons.jikimo_system_order.models.constant import STATE_SELECTION
|
||||||
|
import datetime
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
class OrderTechnicianWizard(models.TransientModel):
|
||||||
|
_name = 'order.technician.wizard'
|
||||||
|
|
||||||
|
order_id = fields.Many2one('system.work.order', string=u'工单ID',
|
||||||
|
default=lambda self: self.env.context.get('active_id'))
|
||||||
|
# 解决人
|
||||||
|
solve_people_id = fields.Many2one('res.users', string=u'解决人', default=lambda self: self.env.user)
|
||||||
|
# 用户实际问题
|
||||||
|
users_problem = fields.Text(string=u'用户实际问题')
|
||||||
|
# 最终解决方案
|
||||||
|
solution = fields.Text(string=u'最终解决方案')
|
||||||
|
# 状态
|
||||||
|
state = fields.Selection(STATE_SELECTION, default='processed', string=u'状态')
|
||||||
|
|
||||||
|
def sure(self):
|
||||||
|
self.order_id.solve_people_id = self.solve_people_id
|
||||||
|
self.order_id.users_problem = self.users_problem
|
||||||
|
self.order_id.solution = self.solution
|
||||||
|
if self.order_id.state == 'pending':
|
||||||
|
state_remark = u'待处理 --> 已处理待评分'
|
||||||
|
# self.order_id.message_post(u'操作人:%s,操作时间:%s,状态变更过程:%s' % (
|
||||||
|
# self.env.user.name,
|
||||||
|
# (datetime.datetime.now() + datetime.timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S'), state_remark))
|
||||||
|
self.order_id.state = self.state
|
||||||
|
# 获取通知人
|
||||||
|
# objs = self.env['system.order.notice'].search([])
|
||||||
|
# user_ids = objs.notice_user_ids.filtered(lambda item: item.we_employee_id not in ['', False])
|
||||||
|
# we_employee_ids = user_ids.mapped('we_employee_id')
|
||||||
|
we_employee_ids = []
|
||||||
|
if self.order_id.initiator_id.we_employee_id:
|
||||||
|
we_employee_ids.append(self.order_id.initiator_id.we_employee_id)
|
||||||
|
print(we_employee_ids)
|
||||||
|
lost_agent_id = self.env['ir.config_parameter'].sudo().get_param('lost_agent_id')
|
||||||
|
wechat = self.env['we.config'].sudo().get_wechat(agent_id=lost_agent_id)
|
||||||
|
# agent_id, user_ids, content
|
||||||
|
content = """您提交的工单-**工单标题:{0}**-<font color=\"info\">**已处理**</font>
|
||||||
|
>提交时间:{1}
|
||||||
|
>处理反馈:{4}
|
||||||
|
>处理时间:{2}
|
||||||
|
>处理人:{3}
|
||||||
|
如有问题,请联系系统管理员!
|
||||||
|
""".format(self.order_id.title,
|
||||||
|
(self.order_id.date + datetime.timedelta(hours=8)).strftime('%Y-%m-%d %H:%M'), (datetime.datetime.now() + datetime.timedelta(hours=8)).strftime('%Y-%m-%d %H:%M'), self.env.user.name or '', self.solution or '')
|
||||||
|
# wechat.message.send_markdown(agent_id=lost_agent_id, user_ids=we_employee_ids, content=content)
|
||||||
|
for we_employee_id in we_employee_ids:
|
||||||
|
try:
|
||||||
|
wechat.message.send_markdown(agent_id=lost_agent_id, user_ids=we_employee_id, content=content)
|
||||||
|
except Exception as e:
|
||||||
|
logging.error('工单处理发送消息异常%s' % str(e))
|
||||||
|
|
||||||
|
return {}
|
||||||
122
jikimo_system_order/wizard/order_wizard.xml
Normal file
122
jikimo_system_order/wizard/order_wizard.xml
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<!-- 技术员向导form-->
|
||||||
|
<record model="ir.ui.view" id="wizard_technician_form_view">
|
||||||
|
<field name="name">技术员向导</field>
|
||||||
|
<field name="model">order.technician.wizard</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="技术员编辑">
|
||||||
|
<group>
|
||||||
|
<field name="order_id" required="1" readonly="1"/>
|
||||||
|
<field name="solve_people_id" required="1"/>
|
||||||
|
<field name="users_problem" required="1" style="height: 50px;"/>
|
||||||
|
<field name="solution" required="1" style="height: 50px;"/>
|
||||||
|
</group>
|
||||||
|
<footer>
|
||||||
|
<button name="sure" string="确定" type="object" class="oe_highlight"/>
|
||||||
|
or
|
||||||
|
<button string="取消" class="oe_link" special="cancel"/>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.actions.act_window" id="launch_order_technician_wizard">
|
||||||
|
<field name="name">技术员编辑</field>
|
||||||
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
<field name="res_model">order.technician.wizard</field>
|
||||||
|
<field name="view_mode">form</field>
|
||||||
|
<field name="view_id" ref="wizard_technician_form_view"/>
|
||||||
|
<field name="context">{'display_default_code':False}</field>
|
||||||
|
<field name="target">new</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 其它向导form-->
|
||||||
|
<record model="ir.ui.view" id="wizard_other_form_view">
|
||||||
|
<field name="name">其它向导</field>
|
||||||
|
<field name="model">order.other.wizard</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="其它编辑">
|
||||||
|
<group>
|
||||||
|
<field name="order_id" required="1" readonly="1"/>
|
||||||
|
<field name="close_time" required="1" readonly="1"/>
|
||||||
|
<field name="grade" required="1"/>
|
||||||
|
<field name="close_user_id" required="1" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
<footer>
|
||||||
|
<button name="sure" string="确定" type="object" class="oe_highlight"/>
|
||||||
|
or
|
||||||
|
<button string="取消" class="oe_link" special="cancel"/>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.actions.act_window" id="launch_order_other_wizard">
|
||||||
|
<field name="name">其它编辑</field>
|
||||||
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
<field name="res_model">order.other.wizard</field>
|
||||||
|
<field name="view_mode">form</field>
|
||||||
|
<field name="view_id" ref="wizard_other_form_view"/>
|
||||||
|
<field name="context">{'display_default_code':False}</field>
|
||||||
|
<field name="target">new</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!--关闭向导form-->
|
||||||
|
<record model="ir.ui.view" id="wizard_close_form_view">
|
||||||
|
<field name="name">关闭向导</field>
|
||||||
|
<field name="model">order.close.wizard</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="关闭工单">
|
||||||
|
<group>
|
||||||
|
<field name="order_id" required="1" readonly="1"/>
|
||||||
|
<field name="close_cause" required="1" style="height: 50px;"/>
|
||||||
|
<field name="close_time" required="1" readonly="1"/>
|
||||||
|
<field name="close_user_id" required="1" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
<footer>
|
||||||
|
<button name="sure" string="确定" type="object" class="oe_highlight"/>
|
||||||
|
or
|
||||||
|
<button string="取消" class="oe_link" special="cancel"/>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.actions.act_window" id="launch_order_close_wizard">
|
||||||
|
<field name="name">关闭工单</field>
|
||||||
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
<field name="res_model">order.close.wizard</field>
|
||||||
|
<field name="view_mode">form</field>
|
||||||
|
<field name="view_id" ref="wizard_close_form_view"/>
|
||||||
|
<field name="context">{'display_default_code':False}</field>
|
||||||
|
<field name="target">new</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="system_work_order_wizard_view" model="ir.ui.view">
|
||||||
|
<field name="name">system_work_order_wizard_view</field>
|
||||||
|
<field name="model">system.work.order.wizard</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="二次确认">
|
||||||
|
<field name="explain" readonly="1"/>
|
||||||
|
<footer>
|
||||||
|
<button name="sure" string="确定" type="object" class="oe_highlight"/>
|
||||||
|
or
|
||||||
|
<button string="取消" class="oe_link" special="cancel"/>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.actions.act_window" id="system_work_order_wizard_view_act_window">
|
||||||
|
<field name="name">二次确认</field>
|
||||||
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
<field name="res_model">system.work.order.wizard</field>
|
||||||
|
<field name="view_mode">form</field>
|
||||||
|
<field name="target">new</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
42
jikimo_system_order/wizard/system_work_order_wizard.py
Normal file
42
jikimo_system_order/wizard/system_work_order_wizard.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# @Time : 2017/12/12 9:46
|
||||||
|
# @Author : GuoXiang
|
||||||
|
# @Site :
|
||||||
|
# @File : system_work_order_wizard.py
|
||||||
|
# @Software: PyCharm
|
||||||
|
# @Desc :
|
||||||
|
# @license : Copyright©2018 www.dasmaster.com All Rights Reserved.
|
||||||
|
# @Contact : xg1230205321@163.com
|
||||||
|
from odoo import models, api, fields
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
|
||||||
|
|
||||||
|
class SystemWorkOrderWizard(models.TransientModel):
|
||||||
|
_name = "system.work.order.wizard"
|
||||||
|
_description = u"追回确认"
|
||||||
|
|
||||||
|
|
||||||
|
def _get_explain(self):
|
||||||
|
if self._context.get('object_id'):
|
||||||
|
obj = self.env['system.work.order'].browse(self._context.get('object_id'))
|
||||||
|
if obj.initiator_id.id != self.env.user.id:
|
||||||
|
raise ValidationError(u'非本人无法操作')
|
||||||
|
if self._context.get('explain'):
|
||||||
|
return self._context["explain"]
|
||||||
|
|
||||||
|
explain = fields.Char(default=_get_explain)
|
||||||
|
|
||||||
|
|
||||||
|
def sure(self):
|
||||||
|
"""
|
||||||
|
确认
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
if self._context.get('object_id') and self._context.get('object_name') and self._context.get(
|
||||||
|
'explain') and self._context.get('function_name'):
|
||||||
|
work_sheet_obj = self.env[self._context["object_name"]].search([('id', '=', int(self._context["object_id"]))])
|
||||||
|
class_name = self._context.get('object_name') # 获得对象类名
|
||||||
|
method_name = self._context.get('function_name') # 获得对象的方法
|
||||||
|
obj_function = getattr(self.env[class_name], method_name)
|
||||||
|
obj_function(work_sheet_obj)
|
||||||
Reference in New Issue
Block a user