Compare commits
1 Commits
master
...
feature/72
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
22f36d095c |
@@ -8,6 +8,8 @@
|
||||
<header>
|
||||
<button string="打印" name="button_action_print" type="object"
|
||||
class="btn-primary"/>
|
||||
<button string="创建工艺设计任务" name="%(sf_manufacturing.action_create_technology_design_task_wizard)d"
|
||||
type="action" class="btn-secondary" context="{'active_model': 'sf.production.demand.plan', 'active_ids': active_ids}"/>
|
||||
</header>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="id" optional="hide"/>
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
'wizard/sf_programming_reason_views.xml',
|
||||
'wizard/sale_order_cancel_views.xml',
|
||||
'wizard/process_outsourcing.xml',
|
||||
'wizard/create_technology_design_task_wizard_views.xml',
|
||||
'views/mrp_views_menus.xml',
|
||||
'views/agv_scheduling_views.xml',
|
||||
'views/stock_lot_views.xml',
|
||||
@@ -48,6 +49,8 @@
|
||||
'views/mrp_workorder_batch_replan.xml',
|
||||
'views/purchase_order_view.xml',
|
||||
'views/product_template_views.xml',
|
||||
'views/sf_technology_design_task_views.xml',
|
||||
'views/sf_technology_design_task_dashboard.xml',
|
||||
# 'views/stock_warehouse_orderpoint.xml',
|
||||
],
|
||||
'assets': {
|
||||
|
||||
@@ -36,6 +36,14 @@
|
||||
<field name="padding">5</field>
|
||||
</record>
|
||||
|
||||
<record id="sequence_technology_design_task" model="ir.sequence">
|
||||
<field name="name">工艺设计任务编码规则</field>
|
||||
<field name="code">sf.technology.design.task</field>
|
||||
<field name="prefix">TD/%(year)s%(month)s%(day)s/</field>
|
||||
<field name="padding">4</field>
|
||||
<field name="company_id" eval="False"/>
|
||||
</record>
|
||||
|
||||
<record id="stock_location_locations_virtual_outcontract" model="stock.location">
|
||||
<field name="name">外协</field>
|
||||
<field name="location_id" ref="stock.stock_location_locations_virtual"/>
|
||||
|
||||
@@ -18,4 +18,5 @@ from . import quick_easy_order
|
||||
from . import purchase_order
|
||||
from . import quality_check
|
||||
from . import purchase_request_line
|
||||
from . import sf_technology_design_task
|
||||
# from . import stock_warehouse_orderpoint
|
||||
251
sf_manufacturing/models/sf_technology_design_task.py
Normal file
251
sf_manufacturing/models/sf_technology_design_task.py
Normal file
@@ -0,0 +1,251 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from odoo import fields, models, api, _
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
|
||||
class SfTechnologyDesignTask(models.Model):
|
||||
_name = 'sf.technology.design.task'
|
||||
_description = '工艺设计任务'
|
||||
_order = 'create_date desc'
|
||||
_inherit = ['mail.thread', 'mail.activity.mixin']
|
||||
|
||||
# 基本信息
|
||||
name = fields.Char('任务编号', required=True, copy=False, readonly=True,
|
||||
default=lambda self: _('New'))
|
||||
state = fields.Selection([
|
||||
('pending', '待工艺设计'),
|
||||
('in_progress', '进行中'),
|
||||
('completed', '已完成'),
|
||||
('cancelled', '已取消'),
|
||||
], string='状态', default='pending', tracking=True)
|
||||
|
||||
# 关联需求计划
|
||||
demand_plan_id = fields.Many2one('sf.production.demand.plan', string='需求计划', required=True, ondelete='cascade')
|
||||
|
||||
# 销售订单信息
|
||||
sale_order_id = fields.Many2one('sale.order', string='销售订单', compute='_compute_sale_order_info', store=True)
|
||||
sale_order_line_id = fields.Many2one('sale.order.line', string='销售订单明细', compute='_compute_sale_order_info', store=True)
|
||||
customer_name = fields.Char('客户名称', compute='_compute_sale_order_info', store=True)
|
||||
|
||||
# 产品信息
|
||||
product_id = fields.Many2one('product.product', string='产品名称', compute='_compute_product_info', store=True)
|
||||
part_name = fields.Char('零件名称', compute='_compute_product_info', store=True)
|
||||
part_number = fields.Char('零件图号', compute='_compute_product_info', store=True)
|
||||
model_id = fields.Char('模型ID', compute='_compute_product_info', store=True)
|
||||
|
||||
# 产品类型和文件
|
||||
product_type = fields.Selection([
|
||||
('standard', '标准件'),
|
||||
('custom', '定制件'),
|
||||
('prototype', '样件'),
|
||||
], string='零件类型', default='custom', store=True)
|
||||
model_file = fields.Binary('模型文件', compute='_compute_model_info', store=True)
|
||||
model_filename = fields.Char('模型文件名', compute='_compute_model_info', store=True)
|
||||
|
||||
# 材料信息
|
||||
materials_id = fields.Many2one('sf.production.materials', string='材料及型号', compute='_compute_material_info', store=True)
|
||||
blank_type = fields.Selection([('圆料', '圆料'), ('方料', '方料')], string='坯料分类', compute='_compute_material_info', store=True)
|
||||
blank_precision = fields.Selection([('精坯', '精坯'), ('粗坯', '粗坯')], string='坯料类型', compute='_compute_material_info', store=True)
|
||||
embryo_long = fields.Char('坯料尺寸', compute='_compute_embryo_long', store=True)
|
||||
|
||||
# 加工信息
|
||||
machining_precision = fields.Selection([
|
||||
('0.10', '±0.10mm'),
|
||||
('0.05', '±0.05mm'),
|
||||
('0.03', '±0.03mm'),
|
||||
('0.02', '±0.02mm'),
|
||||
('0.01', '±0.01mm')
|
||||
], string='加工精度', compute='_compute_machining_info', store=True)
|
||||
machining_panel = fields.Char('加工面', compute='_compute_machining_info', store=True)
|
||||
|
||||
# 订单信息
|
||||
product_uom_qty = fields.Float('订单数量', compute='_compute_order_info', store=True)
|
||||
is_incoming_material = fields.Boolean('客供料', compute='_compute_order_info', store=True)
|
||||
|
||||
# 工艺参数
|
||||
clamping_times = fields.Integer('装夹次数', default=1)
|
||||
single_clamping_duration = fields.Float('单次装夹时长(分钟)', default=30.0)
|
||||
cnc_processing_duration = fields.Float('CNC加工时长(分钟)', default=0.0)
|
||||
|
||||
# 质量要求
|
||||
customer_quality_requirements = fields.Text('客户质量要求')
|
||||
processing_drawing_2d = fields.Binary('2D加工图纸')
|
||||
processing_drawing_filename = fields.Char('2D图纸文件名')
|
||||
|
||||
# 时间信息
|
||||
create_date = fields.Datetime('创建时间', default=fields.Datetime.now)
|
||||
start_date = fields.Datetime('开始时间')
|
||||
complete_date = fields.Datetime('完成时间')
|
||||
deadline = fields.Datetime('截止时间')
|
||||
|
||||
# 负责人
|
||||
assigned_to = fields.Many2one('res.users', string='负责人', tracking=True)
|
||||
created_by = fields.Many2one('res.users', string='创建人', default=lambda self: self.env.user, readonly=True)
|
||||
|
||||
# 备注
|
||||
notes = fields.Text('备注')
|
||||
|
||||
@api.depends('demand_plan_id')
|
||||
def _compute_sale_order_info(self):
|
||||
for record in self:
|
||||
if record.demand_plan_id:
|
||||
record.sale_order_id = record.demand_plan_id.sale_order_id
|
||||
record.sale_order_line_id = record.demand_plan_id.sale_order_line_id
|
||||
record.customer_name = record.demand_plan_id.customer_name
|
||||
else:
|
||||
record.sale_order_id = False
|
||||
record.sale_order_line_id = False
|
||||
record.customer_name = ""
|
||||
|
||||
@api.depends('demand_plan_id')
|
||||
def _compute_product_info(self):
|
||||
for record in self:
|
||||
if record.demand_plan_id and record.demand_plan_id.product_id:
|
||||
record.product_id = record.demand_plan_id.product_id
|
||||
if record.product_id.product_tmpl_id:
|
||||
record.part_name = record.product_id.product_tmpl_id.part_name
|
||||
record.part_number = record.product_id.product_tmpl_id.part_number
|
||||
record.model_id = record.product_id.product_tmpl_id.model_id
|
||||
else:
|
||||
record.part_name = ""
|
||||
record.part_number = ""
|
||||
record.model_id = ""
|
||||
else:
|
||||
record.product_id = False
|
||||
record.part_name = ""
|
||||
record.part_number = ""
|
||||
record.model_id = ""
|
||||
|
||||
@api.depends('product_id')
|
||||
def _compute_model_info(self):
|
||||
for record in self:
|
||||
if record.product_id and record.product_id.product_tmpl_id:
|
||||
template = record.product_id.product_tmpl_id
|
||||
record.model_file = template.model_file
|
||||
record.model_filename = template.model_name
|
||||
else:
|
||||
record.model_file = False
|
||||
record.model_filename = ""
|
||||
|
||||
@api.depends('product_id')
|
||||
def _compute_material_info(self):
|
||||
for record in self:
|
||||
if record.product_id and record.product_id.product_tmpl_id:
|
||||
template = record.product_id.product_tmpl_id
|
||||
record.materials_id = template.materials_id
|
||||
record.blank_type = template.blank_type
|
||||
record.blank_precision = template.blank_precision
|
||||
else:
|
||||
record.materials_id = False
|
||||
record.blank_type = False
|
||||
record.blank_precision = False
|
||||
|
||||
@api.depends('product_id')
|
||||
def _compute_machining_info(self):
|
||||
for record in self:
|
||||
if record.product_id and record.product_id.product_tmpl_id:
|
||||
template = record.product_id.product_tmpl_id
|
||||
record.machining_precision = template.model_machining_precision
|
||||
record.machining_panel = template.model_processing_panel
|
||||
else:
|
||||
record.machining_precision = False
|
||||
record.machining_panel = ""
|
||||
|
||||
@api.depends('demand_plan_id')
|
||||
def _compute_order_info(self):
|
||||
for record in self:
|
||||
if record.demand_plan_id:
|
||||
record.product_uom_qty = record.demand_plan_id.product_uom_qty
|
||||
record.is_incoming_material = record.demand_plan_id.is_incoming_material
|
||||
else:
|
||||
record.product_uom_qty = 0.0
|
||||
record.is_incoming_material = False
|
||||
|
||||
@api.depends('product_id')
|
||||
def _compute_embryo_long(self):
|
||||
for record in self:
|
||||
if record.product_id and record.product_id.product_tmpl_id:
|
||||
template = record.product_id.product_tmpl_id
|
||||
record.embryo_long = f"{template.model_long}×{template.model_width}×{template.model_height}"
|
||||
else:
|
||||
record.embryo_long = ""
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
if vals.get('name', _('New')) == _('New'):
|
||||
vals['name'] = self.env['ir.sequence'].next_by_code('sf.technology.design.task') or _('New')
|
||||
return super(SfTechnologyDesignTask, self).create(vals)
|
||||
|
||||
def action_start_design(self):
|
||||
"""开始工艺设计"""
|
||||
self.ensure_one()
|
||||
if self.state != 'pending':
|
||||
raise ValidationError(_('只有待工艺设计的任务才能开始设计'))
|
||||
self.write({
|
||||
'state': 'in_progress',
|
||||
'start_date': fields.Datetime.now(),
|
||||
})
|
||||
self.message_post(body=_('工艺设计任务已开始'))
|
||||
|
||||
def action_complete_design(self):
|
||||
"""完成工艺设计"""
|
||||
self.ensure_one()
|
||||
if self.state != 'in_progress':
|
||||
raise ValidationError(_('只有进行中的任务才能完成'))
|
||||
self.write({
|
||||
'state': 'completed',
|
||||
'complete_date': fields.Datetime.now(),
|
||||
})
|
||||
self.message_post(body=_('工艺设计任务已完成'))
|
||||
|
||||
def action_cancel_task(self):
|
||||
"""取消任务"""
|
||||
self.ensure_one()
|
||||
if self.state in ['completed']:
|
||||
raise ValidationError(_('已完成的任务不能取消'))
|
||||
self.write({
|
||||
'state': 'cancelled',
|
||||
})
|
||||
self.message_post(body=_('工艺设计任务已取消'))
|
||||
|
||||
def action_reset_to_pending(self):
|
||||
"""重置为待工艺设计"""
|
||||
self.ensure_one()
|
||||
if self.state not in ['in_progress', 'cancelled']:
|
||||
raise ValidationError(_('只有进行中或已取消的任务才能重置'))
|
||||
self.write({
|
||||
'state': 'pending',
|
||||
'start_date': False,
|
||||
'complete_date': False,
|
||||
})
|
||||
self.message_post(body=_('工艺设计任务已重置为待设计状态'))
|
||||
|
||||
@api.model
|
||||
def create_from_demand_plan(self, demand_plan_ids):
|
||||
"""从需求计划创建工艺设计任务"""
|
||||
tasks = self.env['sf.technology.design.task']
|
||||
for demand_plan in demand_plan_ids:
|
||||
# 检查是否已存在工艺设计任务
|
||||
existing_task = self.search([
|
||||
('demand_plan_id', '=', demand_plan.id),
|
||||
('state', 'not in', ['cancelled'])
|
||||
], limit=1)
|
||||
|
||||
if not existing_task:
|
||||
task_vals = {
|
||||
'demand_plan_id': demand_plan.id,
|
||||
'deadline': fields.Datetime.now() + fields.timedelta(days=3), # 默认3天期限
|
||||
}
|
||||
task = self.create(task_vals)
|
||||
tasks |= task
|
||||
|
||||
return tasks
|
||||
|
||||
def get_task_count_by_state(self):
|
||||
"""获取各状态的任务数量"""
|
||||
return {
|
||||
'pending': self.search_count([('state', '=', 'pending')]),
|
||||
'in_progress': self.search_count([('state', '=', 'in_progress')]),
|
||||
'completed': self.search_count([('state', '=', 'completed')]),
|
||||
'cancelled': self.search_count([('state', '=', 'cancelled')]),
|
||||
}
|
||||
@@ -195,4 +195,10 @@ access_sf_work_individuation_page_group_plan_dispatch,sf_work_individuation_page
|
||||
access_sf_sale_order_cancel_wizard,sf_sale_order_cancel_wizard,model_sf_sale_order_cancel_wizard,sf_base.group_sf_order_user,1,1,1,0
|
||||
access_sf_sale_order_cancel_line,sf_sale_order_cancel_line,model_sf_sale_order_cancel_line,sf_base.group_sf_order_user,1,0,1,1
|
||||
|
||||
access_product_creation_wizard,product_creation_wizard,model_product_creation_wizard,base.group_user,1,1,1,0
|
||||
access_product_creation_wizard,product_creation_wizard,model_product_creation_wizard,base.group_user,1,1,1,0
|
||||
access_sf_technology_design_task_group_sf_mrp_user,sf_technology_design_task_group_sf_mrp_user,model_sf_technology_design_task,sf_base.group_sf_mrp_user,1,1,1,0
|
||||
access_sf_technology_design_task_group_sf_mrp_manager,sf_technology_design_task_group_sf_mrp_manager,model_sf_technology_design_task,sf_base.group_sf_mrp_manager,1,1,1,1
|
||||
access_sf_technology_design_task_group_plan_dispatch,sf_technology_design_task_group_plan_dispatch,model_sf_technology_design_task,sf_base.group_plan_dispatch,1,1,1,0
|
||||
access_sf_technology_design_task_group_production_engineer,sf_technology_design_task_group_production_engineer,model_sf_technology_design_task,sf_base.group_production_engineer,1,1,1,0
|
||||
access_sf_create_technology_design_task_wizard_group_sf_mrp_user,sf_create_technology_design_task_wizard_group_sf_mrp_user,model_sf_create_technology_design_task_wizard,sf_base.group_sf_mrp_user,1,1,1,0
|
||||
access_sf_create_technology_design_task_wizard_group_sf_mrp_manager,sf_create_technology_design_task_wizard_group_sf_mrp_manager,model_sf_create_technology_design_task_wizard,sf_base.group_sf_mrp_manager,1,1,1,0
|
||||
|
@@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<!-- 工艺设计任务仪表板视图 -->
|
||||
<record id="view_sf_technology_design_task_dashboard" model="ir.ui.view">
|
||||
<field name="name">sf.technology.design.task.dashboard</field>
|
||||
<field name="model">sf.technology.design.task</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban class="o_kanban_small_column" default_group_by="state">
|
||||
<field name="name"/>
|
||||
<field name="state"/>
|
||||
<field name="product_id"/>
|
||||
<field name="part_name"/>
|
||||
<field name="assigned_to"/>
|
||||
<field name="deadline"/>
|
||||
<field name="create_date"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div class="oe_kanban_global_click">
|
||||
<div class="oe_kanban_content">
|
||||
<div class="o_kanban_record_top">
|
||||
<div class="o_kanban_record_headings">
|
||||
<strong class="o_kanban_record_title">
|
||||
<field name="name"/>
|
||||
</strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="o_kanban_record_body">
|
||||
<div class="o_kanban_primary_left">
|
||||
<field name="product_id"/>
|
||||
</div>
|
||||
<div class="o_kanban_primary_right">
|
||||
<field name="part_name"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="o_kanban_record_bottom">
|
||||
<div class="oe_kanban_bottom_left">
|
||||
<field name="assigned_to"/>
|
||||
</div>
|
||||
<div class="oe_kanban_bottom_right">
|
||||
<field name="deadline"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- 工艺设计任务仪表板动作 -->
|
||||
<record id="action_sf_technology_design_task_dashboard" model="ir.actions.act_window">
|
||||
<field name="name">工艺设计任务仪表板</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">sf.technology.design.task</field>
|
||||
<field name="view_mode">kanban</field>
|
||||
<field name="view_id" ref="view_sf_technology_design_task_dashboard"/>
|
||||
<field name="context">{'search_default_filter_pending': 1}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
创建第一个工艺设计任务
|
||||
</p>
|
||||
<p>
|
||||
工艺设计任务用于管理产品工艺设计流程,包括从需求计划到工艺完成的整个过程。
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- 工艺设计任务仪表板菜单 -->
|
||||
<menuitem id="menu_sf_technology_design_task_dashboard"
|
||||
name="工艺设计仪表板"
|
||||
sequence="15"
|
||||
action="action_sf_technology_design_task_dashboard"
|
||||
parent="mrp.menu_mrp_manufacturing"/>
|
||||
|
||||
</odoo>
|
||||
280
sf_manufacturing/views/sf_technology_design_task_views.xml
Normal file
280
sf_manufacturing/views/sf_technology_design_task_views.xml
Normal file
@@ -0,0 +1,280 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<!-- 工艺设计任务列表视图 -->
|
||||
<record id="view_sf_technology_design_task_tree" model="ir.ui.view">
|
||||
<field name="name">sf.technology.design.task.tree</field>
|
||||
<field name="model">sf.technology.design.task</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="工艺设计任务" default_order="create_date desc"
|
||||
class="technology_design_task_tree freeze-columns-before-part_number">
|
||||
<header>
|
||||
<button string="开始设计" name="action_start_design" type="object"
|
||||
class="btn-primary" attrs="{'invisible': [('state', '!=', 'pending')]}"/>
|
||||
<button string="完成设计" name="action_complete_design" type="object"
|
||||
class="btn-success" attrs="{'invisible': [('state', '!=', 'in_progress')]}"/>
|
||||
<button string="取消任务" name="action_cancel_task" type="object"
|
||||
class="btn-secondary" attrs="{'invisible': [('state', 'in', ['completed'])]}"/>
|
||||
<button string="重置任务" name="action_reset_to_pending" type="object"
|
||||
class="btn-warning" attrs="{'invisible': [('state', 'not in', ['in_progress', 'cancelled'])]}"/>
|
||||
</header>
|
||||
|
||||
<!-- 主要字段 -->
|
||||
<field name="name" string="任务编号"/>
|
||||
<field name="state" widget="badge"
|
||||
decoration-success="state == 'completed'"
|
||||
decoration-warning="state == 'in_progress'"
|
||||
decoration-danger="state == 'cancelled'"/>
|
||||
<field name="sale_order_id" string="销售单号"/>
|
||||
<field name="product_id" string="产品名称"/>
|
||||
<field name="part_name" string="零件名称"/>
|
||||
<field name="part_number" string="零件图号"/>
|
||||
<field name="product_type" string="零件类型"/>
|
||||
<field name="model_id" string="模型ID" optional="hide"/>
|
||||
<field name="model_filename" string="模型文件" optional="hide"/>
|
||||
<field name="materials_id" string="材料及型号"/>
|
||||
<field name="blank_type" string="坯料分类" optional="hide"/>
|
||||
<field name="blank_precision" string="坯料类型" optional="hide"/>
|
||||
<field name="embryo_long" string="坯料尺寸" optional="hide"/>
|
||||
<field name="machining_precision" string="加工精度" optional="hide"/>
|
||||
<field name="machining_panel" string="加工面" optional="hide"/>
|
||||
<field name="product_uom_qty" string="订单数量"/>
|
||||
<field name="is_incoming_material" string="客供料"/>
|
||||
<field name="clamping_times" string="装夹次数" optional="hide"/>
|
||||
<field name="single_clamping_duration" string="单次装夹时长" optional="hide"/>
|
||||
<field name="cnc_processing_duration" string="CNC加工时长" optional="hide"/>
|
||||
<field name="customer_quality_requirements" string="客户质量要求" optional="hide"/>
|
||||
<field name="processing_drawing_filename" string="2D加工图纸" optional="hide"/>
|
||||
<field name="customer_name" string="客户名称" optional="hide"/>
|
||||
|
||||
<!-- 时间字段 -->
|
||||
<field name="create_date" string="创建时间" optional="hide"/>
|
||||
<field name="start_date" string="开始时间" optional="hide"/>
|
||||
<field name="complete_date" string="完成时间" optional="hide"/>
|
||||
<field name="deadline" string="截止时间" optional="hide"/>
|
||||
|
||||
<!-- 负责人字段 -->
|
||||
<field name="assigned_to" string="负责人" optional="hide"/>
|
||||
<field name="created_by" string="创建人" optional="hide"/>
|
||||
|
||||
<!-- 备注 -->
|
||||
<field name="notes" string="备注" optional="hide"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- 工艺设计任务搜索视图 -->
|
||||
<record id="view_sf_technology_design_task_search" model="ir.ui.view">
|
||||
<field name="name">sf.technology.design.task.search</field>
|
||||
<field name="model">sf.technology.design.task</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="name"/>
|
||||
<field name="sale_order_id"/>
|
||||
<field name="product_id"/>
|
||||
<field name="part_name"/>
|
||||
<field name="part_number"/>
|
||||
<field name="customer_name"/>
|
||||
<field name="materials_id"/>
|
||||
<field name="assigned_to"/>
|
||||
<field name="created_by"/>
|
||||
|
||||
<filter name="filter_pending" string="待工艺设计" domain="[('state', '=', 'pending')]"/>
|
||||
<filter name="filter_in_progress" string="进行中" domain="[('state', '=', 'in_progress')]"/>
|
||||
<filter name="filter_completed" string="已完成" domain="[('state', '=', 'completed')]"/>
|
||||
<filter name="filter_cancelled" string="已取消" domain="[('state', '=', 'cancelled')]"/>
|
||||
|
||||
<separator/>
|
||||
|
||||
<filter name="filter_my_tasks" string="我的任务" domain="[('assigned_to', '=', uid)]"/>
|
||||
<filter name="filter_overdue" string="已逾期" domain="[('deadline', '<', context_today()), ('state', 'not in', ['completed', 'cancelled'])]"/>
|
||||
|
||||
<group expand="0" string="Group By">
|
||||
<filter name="group_by_state" string="状态" domain="[]" context="{'group_by': 'state'}"/>
|
||||
<filter name="group_by_sale_order" string="销售单号" domain="[]" context="{'group_by': 'sale_order_id'}"/>
|
||||
<filter name="group_by_product" string="产品" domain="[]" context="{'group_by': 'product_id'}"/>
|
||||
<filter name="group_by_customer" string="客户" domain="[]" context="{'group_by': 'customer_name'}"/>
|
||||
<filter name="group_by_assigned_to" string="负责人" domain="[]" context="{'group_by': 'assigned_to'}"/>
|
||||
<filter name="group_by_created_by" string="创建人" domain="[]" context="{'group_by': 'created_by'}"/>
|
||||
<filter name="group_by_create_date" string="创建日期" domain="[]" context="{'group_by': 'create_date:day'}"/>
|
||||
<filter name="group_by_deadline" string="截止日期" domain="[]" context="{'group_by': 'deadline:day'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- 工艺设计任务表单视图 -->
|
||||
<record id="view_sf_technology_design_task_form" model="ir.ui.view">
|
||||
<field name="name">sf.technology.design.task.form</field>
|
||||
<field name="model">sf.technology.design.task</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="工艺设计任务">
|
||||
<header>
|
||||
<button name="action_start_design" string="开始设计" type="object"
|
||||
class="btn-primary" attrs="{'invisible': [('state', '!=', 'pending')]}"/>
|
||||
<button name="action_complete_design" string="完成设计" type="object"
|
||||
class="btn-success" attrs="{'invisible': [('state', '!=', 'in_progress')]}"/>
|
||||
<button name="action_cancel_task" string="取消任务" type="object"
|
||||
class="btn-secondary" attrs="{'invisible': [('state', 'in', ['completed'])]}"/>
|
||||
<button name="action_reset_to_pending" string="重置任务" type="object"
|
||||
class="btn-warning" attrs="{'invisible': [('state', 'not in', ['in_progress', 'cancelled'])]}"/>
|
||||
<field name="state" widget="statusbar"
|
||||
statusbar_visible="pending,in_progress,completed"/>
|
||||
</header>
|
||||
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<h1>
|
||||
<field name="name" readonly="1"/>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<group>
|
||||
<group string="基本信息">
|
||||
<field name="demand_plan_id"/>
|
||||
<field name="sale_order_id"/>
|
||||
<field name="customer_name"/>
|
||||
<field name="assigned_to"/>
|
||||
<field name="created_by"/>
|
||||
</group>
|
||||
<group string="时间信息">
|
||||
<field name="create_date"/>
|
||||
<field name="start_date"/>
|
||||
<field name="complete_date"/>
|
||||
<field name="deadline"/>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<notebook>
|
||||
<page string="产品信息">
|
||||
<group>
|
||||
<group string="产品详情">
|
||||
<field name="product_id"/>
|
||||
<field name="part_name"/>
|
||||
<field name="part_number"/>
|
||||
<field name="product_type"/>
|
||||
<field name="model_id"/>
|
||||
<field name="model_file" filename="model_filename"/>
|
||||
<field name="model_filename" invisible="1"/>
|
||||
</group>
|
||||
<group string="材料信息">
|
||||
<field name="materials_id"/>
|
||||
<field name="blank_type"/>
|
||||
<field name="blank_precision"/>
|
||||
<field name="embryo_long"/>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
|
||||
<page string="加工信息">
|
||||
<group>
|
||||
<group string="加工参数">
|
||||
<field name="machining_precision"/>
|
||||
<field name="machining_panel"/>
|
||||
<field name="product_uom_qty"/>
|
||||
<field name="is_incoming_material"/>
|
||||
</group>
|
||||
<group string="工艺参数">
|
||||
<field name="clamping_times"/>
|
||||
<field name="single_clamping_duration"/>
|
||||
<field name="cnc_processing_duration"/>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
|
||||
<page string="质量要求">
|
||||
<group>
|
||||
<field name="customer_quality_requirements" nolabel="1"/>
|
||||
</group>
|
||||
<group string="图纸文件">
|
||||
<field name="processing_drawing_2d" filename="processing_drawing_filename"/>
|
||||
<field name="processing_drawing_filename" invisible="1"/>
|
||||
</group>
|
||||
</page>
|
||||
|
||||
<page string="备注">
|
||||
<field name="notes" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids"/>
|
||||
<field name="activity_ids"/>
|
||||
<field name="message_ids"/>
|
||||
</div>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- 工艺设计任务动作 -->
|
||||
<record id="action_sf_technology_design_task" model="ir.actions.act_window">
|
||||
<field name="name">工艺设计任务</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">sf.technology.design.task</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="context">{'search_default_filter_pending': 1}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
创建第一个工艺设计任务
|
||||
</p>
|
||||
<p>
|
||||
工艺设计任务用于管理产品工艺设计流程,包括从需求计划到工艺完成的整个过程。
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- 工艺设计任务菜单 -->
|
||||
<menuitem id="menu_sf_technology_design_task"
|
||||
name="工艺设计任务"
|
||||
sequence="20"
|
||||
action="action_sf_technology_design_task"
|
||||
parent="mrp.menu_mrp_manufacturing"/>
|
||||
|
||||
<!-- 工艺设计任务看板视图 -->
|
||||
<record id="view_sf_technology_design_task_kanban" model="ir.ui.view">
|
||||
<field name="name">sf.technology.design.task.kanban</field>
|
||||
<field name="model">sf.technology.design.task</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban class="o_kanban_small_column" default_group_by="state">
|
||||
<field name="name"/>
|
||||
<field name="state"/>
|
||||
<field name="product_id"/>
|
||||
<field name="part_name"/>
|
||||
<field name="assigned_to"/>
|
||||
<field name="deadline"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div class="oe_kanban_global_click">
|
||||
<div class="oe_kanban_content">
|
||||
<div class="o_kanban_record_top">
|
||||
<div class="o_kanban_record_headings">
|
||||
<strong class="o_kanban_record_title">
|
||||
<field name="name"/>
|
||||
</strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="o_kanban_record_body">
|
||||
<div class="o_kanban_primary_left">
|
||||
<field name="product_id"/>
|
||||
</div>
|
||||
<div class="o_kanban_primary_right">
|
||||
<field name="part_name"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="o_kanban_record_bottom">
|
||||
<div class="oe_kanban_bottom_left">
|
||||
<field name="assigned_to"/>
|
||||
</div>
|
||||
<div class="oe_kanban_bottom_right">
|
||||
<field name="deadline"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
@@ -6,4 +6,5 @@ from . import production_technology_re_adjust_wizard
|
||||
from . import mrp_workorder_batch_replan_wizard
|
||||
from . import sf_programming_reason
|
||||
from . import sale_order_cancel
|
||||
from . import process_outsourcing
|
||||
from . import process_outsourcing
|
||||
from . import create_technology_design_task_wizard
|
||||
@@ -0,0 +1,58 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from odoo import fields, models, api, _
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class CreateTechnologyDesignTaskWizard(models.TransientModel):
|
||||
_name = 'sf.create.technology.design.task.wizard'
|
||||
_description = '创建工艺设计任务向导'
|
||||
|
||||
demand_plan_ids = fields.Many2many('sf.production.demand.plan', string='需求计划', required=True)
|
||||
assigned_to = fields.Many2one('res.users', string='负责人', default=lambda self: self.env.user)
|
||||
deadline = fields.Datetime('截止时间', required=True)
|
||||
notes = fields.Text('备注')
|
||||
|
||||
@api.model
|
||||
def default_get(self, fields_list):
|
||||
res = super(CreateTechnologyDesignTaskWizard, self).default_get(fields_list)
|
||||
if self.env.context.get('active_model') == 'sf.production.demand.plan':
|
||||
demand_plan_ids = self.env.context.get('active_ids', [])
|
||||
res['demand_plan_ids'] = [(6, 0, demand_plan_ids)]
|
||||
return res
|
||||
|
||||
def action_create_tasks(self):
|
||||
"""创建工艺设计任务"""
|
||||
if not self.demand_plan_ids:
|
||||
raise UserError(_('请选择需求计划'))
|
||||
|
||||
# 检查是否已存在工艺设计任务
|
||||
existing_tasks = self.env['sf.technology.design.task'].search([
|
||||
('demand_plan_id', 'in', self.demand_plan_ids.ids),
|
||||
('state', 'not in', ['cancelled'])
|
||||
])
|
||||
|
||||
if existing_tasks:
|
||||
raise UserError(_('以下需求计划已存在工艺设计任务:\n%s') %
|
||||
'\n'.join([task.demand_plan_id.name for task in existing_tasks]))
|
||||
|
||||
# 创建工艺设计任务
|
||||
tasks = self.env['sf.technology.design.task']
|
||||
for demand_plan in self.demand_plan_ids:
|
||||
task_vals = {
|
||||
'demand_plan_id': demand_plan.id,
|
||||
'assigned_to': self.assigned_to.id,
|
||||
'deadline': self.deadline,
|
||||
'notes': self.notes,
|
||||
}
|
||||
task = self.env['sf.technology.design.task'].create(task_vals)
|
||||
tasks |= task
|
||||
|
||||
# 返回工艺设计任务列表视图
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': _('工艺设计任务'),
|
||||
'res_model': 'sf.technology.design.task',
|
||||
'view_mode': 'tree,form',
|
||||
'domain': [('id', 'in', tasks.ids)],
|
||||
'context': {'search_default_filter_pending': 1},
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="view_create_technology_design_task_wizard_form" model="ir.ui.view">
|
||||
<field name="name">sf.create.technology.design.task.wizard.form</field>
|
||||
<field name="model">sf.create.technology.design.task.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="创建工艺设计任务">
|
||||
<group>
|
||||
<field name="demand_plan_ids" widget="many2many_tags"/>
|
||||
<field name="assigned_to"/>
|
||||
<field name="deadline"/>
|
||||
<field name="notes"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="action_create_tasks" string="创建任务" type="object" class="btn-primary"/>
|
||||
<button string="取消" class="btn-secondary" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_create_technology_design_task_wizard" model="ir.actions.act_window">
|
||||
<field name="name">创建工艺设计任务</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">sf.create.technology.design.task.wizard</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user