Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/页面优化

# Conflicts:
#	sf_manufacturing/models/stock.py
This commit is contained in:
jinling.yang
2023-09-14 09:46:28 +08:00
19 changed files with 410 additions and 208 deletions

View File

@@ -31,7 +31,7 @@ export class MyCustomWidget extends Many2ManyCheckboxesField {
} }
} }
MyCustomWidget.template = "sf_plan.MyCustomWidget" MyCustomWidget.template = "jikimo_frontend.MyCustomWidget"
// MyCustomWidget.supportedTypes = ['many2many']; // MyCustomWidget.supportedTypes = ['many2many'];
registry.category("fields").add("custom_many2many_checkboxes", MyCustomWidget); registry.category("fields").add("custom_many2many_checkboxes", MyCustomWidget);

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve"> <templates xml:space="preserve">
<t t-name="sf_plan.MyCustomWidget" owl="1"> <t t-name="jikimo_frontend.MyCustomWidget" owl="1">
<div aria-atomic="true" class="many2many_flex"> <div aria-atomic="true" class="many2many_flex">
<t t-foreach="items" t-as="item" t-key="item[0]"> <t t-foreach="items" t-as="item" t-key="item[0]">
<div> <div>

View File

@@ -19,6 +19,7 @@ class SfEquipmentSaintenanceStandards(models.Model):
num = "%04d" % m num = "%04d" % m
return num return num
code = fields.Char(string='编码', default=get_no) code = fields.Char(string='编码', default=get_no)
remark = fields.Char('备注')
maintenance_type = fields.Selection([('保养', '保养'), ("检修", "检修")], string='类型', default='保养') maintenance_type = fields.Selection([('保养', '保养'), ("检修", "检修")], string='类型', default='保养')
name = fields.Char(string='名称') name = fields.Char(string='名称')
created_user_id = fields.Many2one('res.users', string='创建人', default=lambda self: self.env.user) created_user_id = fields.Many2one('res.users', string='创建人', default=lambda self: self.env.user)
@@ -26,7 +27,7 @@ class SfEquipmentSaintenanceStandards(models.Model):
maintenance_equipment_ids = fields.Many2many( maintenance_equipment_ids = fields.Many2many(
'maintenance.equipment', 'maintenance.equipment',
'sf_maintenance_equipment_ids', 'sf_maintenance_equipment_ids',
string='设备', string='适用设备',
domain="[('category_id', '=', maintenance_equipment_category_id)]" domain="[('category_id', '=', maintenance_equipment_category_id)]"
) )
@@ -42,23 +43,29 @@ class SfEquipmentSaintenanceStandards(models.Model):
if record.maintenance_type == '检修': if record.maintenance_type == '检修':
record.write({'overhaul_ids': [(6, 0, record.maintenance_equipment_ids.ids)]}) record.write({'overhaul_ids': [(6, 0, record.maintenance_equipment_ids.ids)]})
@api.onchange("maintenance_standards_ids") # @api.onchange("maintenance_standards_ids")
def _reset_work_order_sequence(self): # def _reset_work_order_sequence(self):
for rec in self: # for rec in self:
current_sequence = 1 # current_sequence = 1
for work in rec.maintenance_standards_ids: # for work in rec.maintenance_standards_ids:
work.sequence = current_sequence # work.sequence = current_sequence
current_sequence += 1 # current_sequence += 1
class SfSaintenanceStandards(models.Model): class SfSaintenanceStandards(models.Model):
_name = 'maintenance.standards' _name = 'maintenance.standards'
_description = '维保项目' _description = '维保项目'
_order = 'sequence'
sequence = fields.Integer('序号')
name = fields.Char('维保项目') name = fields.Char('维保项目')
maintenance_standards = fields.Char('维保标准') maintenance_standards = fields.Char('维保标准')
fault_type = fields.Selection(
[('电气类', '电气类'), ('机械类', '机械类'), ('程序类', '程序类'), ('系统类', '系统类')], string='类别')
equipment_maintenance_standards_id = fields.Many2one('equipment.maintenance.standards', string='设备维保标准') equipment_maintenance_standards_id = fields.Many2one('equipment.maintenance.standards', string='设备维保标准')
maintenance_request_id = fields.Many2one('maintenance.request', string='设备维保计划') maintenance_request_id = fields.Many2one('maintenance.request', string='设备维保计划')
images = fields.One2many('maintenance.standard.image', 'standard_id', string='反馈图片') images = fields.One2many('maintenance.standard.image', 'standard_id', string='反馈图片')
Period = fields.Integer('周期/频次(天)')
remark = fields.Char('备注说明')
class MaintenanceStandardImage(models.Model): class MaintenanceStandardImage(models.Model):

View File

@@ -44,6 +44,7 @@ class SfMaintenanceEquipment(models.Model):
overhaul_period = fields.Integer(string='预防检修频次') overhaul_period = fields.Integer(string='预防检修频次')
overhaul_duration = fields.Float(string='检修时长') overhaul_duration = fields.Float(string='检修时长')
overhaul_id = fields.Many2one('equipment.maintenance.standards', string='设备检修标准', overhaul_id = fields.Many2one('equipment.maintenance.standards', string='设备检修标准',
domain="[('maintenance_type','=','检修')]") domain="[('maintenance_type','=','检修')]")
@@ -142,7 +143,7 @@ class SfMaintenanceEquipment(models.Model):
active = fields.Boolean('有效', default=True) active = fields.Boolean('有效', default=True)
# 多个型号对应一个机床 # 多个型号对应一个机床
machine_tool_id = fields.Many2one('sf.machine_tool', '机床') machine_tool_id = fields.Many2one('sf.machine_tool', '机床')
sf_maintenance_logs_ids = fields.One2many('sf.maintenance.logs','maintenance_equipment_id', '设备故障日志') sf_maintenance_logs_ids = fields.One2many('sf.maintenance.logs', 'maintenance_equipment_id', '设备故障日志')
def name_get(self): def name_get(self):
@@ -474,3 +475,49 @@ class SfMaintenanceEquipment(models.Model):
('sf_maintenance_type', '=', '检修')]) ('sf_maintenance_type', '=', '检修')])
if not next_requests: if not next_requests:
equipment._create_new_request1(equipment.overhaul_date) equipment._create_new_request1(equipment.overhaul_date)
image_id = fields.Many2many('maintenance.equipment.image', 'equipment_id', string='设备图文')
class MaintenanceStandardImage(models.Model):
_name = 'maintenance.equipment.image'
_description = '设备图文展示'
active = fields.Boolean('有效', default=True)
name = fields.Char('加工能力')
image = fields.Binary(string='设备图文')
equipment_id = fields.Many2many('maintenance.equipment', 'image_id', string='设备')
@api.model
def name_search(self, name='', args=None, operator='ilike', limit=100):
# 调用父类的name_search方法获取原始的结果列表
res = super().name_search(name, args, operator, limit)
# 定义一个空字典用来存储id和name的映射关系
name_dict = {}
# 遍历结果列表将id和name存入字典中
for item in res:
id = item[0]
name = item[1]
name_dict[id] = name
# 根据id列表搜索符合条件的记录
records = self.browse(name_dict.keys())
# 定义一个新的结果列表用来存储修改后的结果
new_res = []
# 遍历每条记录
for record in records:
# 获取记录的idname和image属性
id = record.id
name = name_dict[id]
image = record.image
# 如果image不为空将其转换为data URI scheme
if image:
data_uri = f"data:image/png;base64,{image.decode('utf-8')}"
else:
data_uri = ""
# 将这三个属性组成一个数组,并添加到结果列表中 result.append([id, name, data_uri]) # 返回结果列表 return result
new_res.append([id, name, data_uri])
# 返回新的结果列表
return new_res

View File

@@ -22,3 +22,5 @@ class SfMaintenanceLogs(models.Model):
recovery_time = fields.Datetime(string='复原时间') recovery_time = fields.Datetime(string='复原时间')
fault_duration = fields.Float(string='故障时长') fault_duration = fields.Float(string='故障时长')
note = fields.Text(string='备注') note = fields.Text(string='备注')

View File

@@ -4,6 +4,7 @@ access_sf_maintenance_logs,sf_maintenance_logs,model_sf_maintenance_logs,base.gr
access_maintenance_equipment,maintenance_equipment,model_maintenance_equipment,base.group_user,1,1,1,1 access_maintenance_equipment,maintenance_equipment,model_maintenance_equipment,base.group_user,1,1,1,1
access_maintenance_standards,maintenance_standards,model_maintenance_standards,base.group_user,1,1,1,1 access_maintenance_standards,maintenance_standards,model_maintenance_standards,base.group_user,1,1,1,1
access_maintenance_standard_image,maintenance_standard_image,model_maintenance_standard_image,base.group_user,1,1,1,1 access_maintenance_standard_image,maintenance_standard_image,model_maintenance_standard_image,base.group_user,1,1,1,1
access_maintenance_equipment_image,maintenance_equipment_image,model_maintenance_equipment_image,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
4 access_maintenance_equipment maintenance_equipment model_maintenance_equipment base.group_user 1 1 1 1
5 access_maintenance_standards maintenance_standards model_maintenance_standards base.group_user 1 1 1 1
6 access_maintenance_standard_image maintenance_standard_image model_maintenance_standard_image base.group_user 1 1 1 1
7 access_maintenance_equipment_image maintenance_equipment_image model_maintenance_equipment_image base.group_user 1 1 1 1
8
9
10

View File

@@ -21,14 +21,26 @@
<group> <group>
<field name="maintenance_type" required="1"/> <field name="maintenance_type" required="1"/>
<field name="created_user_id"/> <field name="created_user_id"/>
<field name="remark"/>
</group> </group>
</group> </group>
<group> <group>
<field name="maintenance_equipment_ids" widget="many2many_tags" attrs="{'invisible': [('maintenance_equipment_category_id', '=', False)]}"/> <field name="maintenance_equipment_ids" widget="many2many_tags" attrs="{'invisible': [('maintenance_equipment_category_id', '=', False)]}"/>
</group> </group>
<notebook>
<page string="维保项目">
<field name="maintenance_standards_ids">
<tree editable="bottom">
<field name="name"/>
<field name="fault_type"/>
<field name="maintenance_standards"/>
<field name="Period"/>
</tree>
</field>
</page>
</notebook>
</sheet> </sheet>
</form> </form>
</field> </field>
@@ -46,6 +58,7 @@
<field name="maintenance_equipment_ids"/> <field name="maintenance_equipment_ids"/>
<field name="created_user_id"/> <field name="created_user_id"/>
<field name="create_date" string="创建时间"/> <field name="create_date" string="创建时间"/>
<field name="remark"/>
</tree> </tree>
</field> </field>

View File

@@ -34,25 +34,39 @@
<field name="model">sf.maintenance.logs</field> <field name="model">sf.maintenance.logs</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="设备故障日志"> <form string="设备故障日志">
<group> <header>
<field name="code"/> <field name="alarm_level" widget="statusbar"/>
<field name="name"/> </header>
<field name="type"/> <sheet>
<field name="brand"/> <div class="oe_title">
<field name="maintenance_equipment_id"/> <h1>
<field name="code_location"/> <field name="code" readonly="1"/>
<field name="fault_type"/> </h1>
<field name="fault_code"/> </div>
<field name="fault_alarm_info"/> <group>
<field name="alarm_level"/> <group>
<field name="alarm_time"/>
<field name="alarm_way"/> <field name="name"/>
<field name="fault_process"/> <field name="type" required="1" widget="radio" options="{'horizontal': true}"/>
<field name="operator"/> <field name="brand"/>
<field name="recovery_time"/> <field name="maintenance_equipment_id"/>
<field name="fault_duration"/> <field name="code_location"/>
<field name="note"/> <field name="fault_type" required="1" widget="radio" options="{'horizontal': true}"/>
</group> <field name="fault_code"/>
<field name="fault_process"/>
</group>
<group>
<field name="fault_alarm_info"/>
<field name="alarm_time"/>
<field name="alarm_way" required="1" widget="radio" options="{'horizontal': true}"/>
<field name="operator"/>
<field name="recovery_time"/>
<field name="fault_duration"/>
<field name="note"/>
</group>
</group>
</sheet>
</form> </form>
</field> </field>
</record> </record>
@@ -64,8 +78,8 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<search> <search>
<searchpanel> <searchpanel>
<field name="maintenance_equipment_id" icon="fa-building" enable_counters="1"/> <field name="maintenance_equipment_id" icon="fa-building" enable_counters="1"/>
</searchpanel> </searchpanel>
<field name="code"/> <field name="code"/>
<field name="name"/> <field name="name"/>
<field name="type"/> <field name="type"/>
@@ -90,28 +104,28 @@
<!-- Action --> <!-- Action -->
<record id="action_maintenance_logs" model="ir.actions.act_window"> <record id="action_maintenance_logs" model="ir.actions.act_window">
<field name="name">设备故障日志</field> <field name="name">设备故障日志</field>
<field name="type">ir.actions.act_window</field> <field name="type">ir.actions.act_window</field>
<field name="res_model">sf.maintenance.logs</field> <field name="res_model">sf.maintenance.logs</field>
<field name="view_mode">tree,form</field> <field name="view_mode">tree,form</field>
<field name="view_id" ref="view_maintenance_logs_tree"/> <field name="view_id" ref="view_maintenance_logs_tree"/>
<field name="help" type="html"> <field name="help" type="html">
<p class="oe_view_nocontent_create"> <p class="oe_view_nocontent_create">
设备故障日志 设备故障日志
</p> </p>
</field> </field>
</record> </record>
<!-- <record id="action_maintenance_logs" model="ir.actions.act_window">--> <!-- <record id="action_maintenance_logs" model="ir.actions.act_window">-->
<!-- <field name="name">设备故障日志</field>--> <!-- <field name="name">设备故障日志</field>-->
<!-- <field name="res_model">sf.maintenance.logs</field>--> <!-- <field name="res_model">sf.maintenance.logs</field>-->
<!-- <field name="view_type">form</field>--> <!-- <field name="view_type">form</field>-->
<!-- <field name="view_mode">tree,form</field>--> <!-- <field name="view_mode">tree,form</field>-->
<!-- <field name="view_id" ref="view_maintenance_logs_tree"/>--> <!-- <field name="view_id" ref="view_maintenance_logs_tree"/>-->
<!-- </record>--> <!-- </record>-->
<!-- Menu --> <!-- Menu -->
<menuitem name="设备故障日志" id="menu_maintenance_logs" parent="maintenance.menu_m_request" <menuitem name="设备故障日志" id="menu_maintenance_logs" parent="maintenance.menu_m_request"
sequence="10" action="action_maintenance_logs"/> sequence="10" action="action_maintenance_logs"/>
</data> </data>

View File

@@ -24,9 +24,11 @@
<page string="维保标准" attrs="{'invisible': [('equipment_maintenance_id', '=', False)]}"> <page string="维保标准" attrs="{'invisible': [('equipment_maintenance_id', '=', False)]}">
<field name="maintenance_standards" widget="ony2many"> <field name="maintenance_standards" widget="ony2many">
<tree> <tree>
<field name="sequence"/>
<field name="name"/> <field name="name"/>
<field name="maintenance_standards"/> <field name="maintenance_standards"/>
<field name="images"/> <field name="images"/>
<field name="remark"/>
</tree> </tree>
</field> </field>
@@ -78,8 +80,16 @@
<form string="设备维保项目"> <form string="设备维保项目">
<sheet> <sheet>
<group> <group>
<field name="name"/> <group>
<field name="maintenance_standards"/> <field name="sequence"/>
<field name="name"/>
</group>
<group>
<field name="maintenance_standards"/>
<field name="remark"/>
</group>
</group> </group>
<notebook> <notebook>
<page string="上传图片"> <page string="上传图片">

View File

@@ -34,6 +34,7 @@
<!-- <field string="Maintenance" name="maintenance_count" widget="statinfo"/>--> <!-- <field string="Maintenance" name="maintenance_count" widget="statinfo"/>-->
<xpath expr="//div[@name='button_box']" position="inside"> <xpath expr="//div[@name='button_box']" position="inside">
<button name="%(action_maintenance_logs)d" <button name="%(action_maintenance_logs)d"
type="action" type="action"
class="oe_stat_button" class="oe_stat_button"
@@ -46,6 +47,10 @@
</xpath> </xpath>
<xpath expr="//field[@name='maintenance_team_id']" position="before"> <xpath expr="//field[@name='maintenance_team_id']" position="before">
<field name="machine_tool_picture" widget="image"/> <field name="machine_tool_picture" widget="image"/>
<label for="enroll_machine_tool"/>
<div class="col-12 col-lg-6 o_setting_box" style="white-space: nowrap">
<button type="object" class="oe_highlight" name='enroll_machine_tool' string="机床注册"/>
</div>
</xpath> </xpath>
<xpath expr="//field[@name='category_id']" position="after"> <xpath expr="//field[@name='category_id']" position="after">
<field name="state_zc" readonly="1"/> <field name="state_zc" readonly="1"/>
@@ -172,6 +177,16 @@
</page> </page>
<page string="图文展示">
<field name='image_id' widget="custom_many2many_checkboxes">
<tree editable="bottom">
<field name="name"/>
<field name="image" widget="image"
options="{'size': [100, 100], 'click enlarge': True}"/>
</tree>
</field>
</page>
</xpath> </xpath>
@@ -210,11 +225,11 @@
</xpath> </xpath>
<xpath expr="//page[@name='maintenance']" position="after"> <xpath expr="//page[@name='maintenance']" position="after">
<page string="其他" attrs="{'invisible': [('type_id', '=', False)]}"> <page string="其他" attrs="{'invisible': [('type_id', '=', False)]}">
<group string="其他"> <group string="其他">
<field name="remark"/> <field name="remark"/>
</group> </group>
<button type="object" class="oe_highlight" name='enroll_machine_tool' string="机床注册"/>
</page> </page>
</xpath> </xpath>
@@ -360,7 +375,51 @@
<!-- name="设备管理"--> <!-- name="设备管理"-->
<!-- parent="menu_maintenance_title_sf"--> <!-- parent="menu_maintenance_title_sf"-->
<!-- groups="maintenance.group_equipment_manager,base.group_user"--> <!-- groups="maintenance.group_equipment_manager,base.group_user"-->
<!-- sequence="1"/>--> <!-- sequence="1"/-->
<!-- 设备图文展示-->
<record id="view_maintenance_equipment_image_tree" model="ir.ui.view">
<field name="name">maintenance.equipment.image.tree</field>
<field name="model">maintenance.equipment.image</field>
<field name="arch" type="xml">
<tree string="设备图文">
<field name="name"/>
<field name="image" widget="image"/>
<field name="equipment_id" invisible="1"/>
<field name="active" invisible="1"/>
</tree>
</field>
</record>
<record id="view_maintenance_equipment_image_form" model="ir.ui.view">
<field name="name">maintenance.equipment.image.form</field>
<field name="model">maintenance.equipment.image</field>
<field name="arch" type="xml">
<form string="设备图文">
<sheet>
<group>
<field name="name"/>
<field name="image" widget="image"/>
<field name="equipment_id" invisible="1"/>
<field name="active" invisible="1"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="action_maintenance_equipment_image" model="ir.actions.act_window">
<field name="name">设备图文图文</field>
<field name="res_model">maintenance.equipment.image</field>
<field name="view_mode">tree,form</field>
<field name="domain">[]</field>
</record>
<menuitem
id="maintenance_equipment_image_form"
name="设备图文展示"
parent="maintenance.menu_m_request"
action="action_maintenance_equipment_image"
groups="maintenance.group_equipment_manager,base.group_user"
sequence="2"/>
</odoo> </odoo>

View File

@@ -11,13 +11,18 @@ class ResWorkcenter(models.Model):
production_line_show = fields.Char(string='生产线名称') production_line_show = fields.Char(string='生产线名称')
machine_tool_id = fields.Many2one('sf.machine_tool', string='机床') machine_tool_id = fields.Many2one('sf.machine_tool', string='机床')
production_line_id = fields.Many2one('sf.production.line', string='生产线') production_line_id = fields.Many2one('sf.production.line', string='生产线')
is_process_outsourcing = fields.Boolean('工艺外协')
users_ids = fields.Many2many("res.users", 'users_workcenter')
equipment_id = fields.Many2one( equipment_id = fields.Many2one(
'maintenance.equipment', string="设备", 'maintenance.equipment', string="设备",
check_company=True) check_company=True)
is_process_outsourcing = fields.Boolean('工艺外协')
users_ids = fields.Many2many("res.users", 'users_workcenter')
equipment_status = fields.Selection( equipment_status = fields.Selection(
[("正常", "正常"), ("故障", "故障"), ("不可用", "不可用")], [("正常", "正常"), ("故障", "故障"), ("不可用", "不可用")],
string="设备状态", compute='_compute_equipment_id') string="设备状态", compute='_compute_equipment_id')

View File

@@ -189,28 +189,30 @@ class StockRule(models.Model):
'mail.message_origin_link', 'mail.message_origin_link',
values={'self': production, 'origin': origin_production}, values={'self': production, 'origin': origin_production},
subtype_id=self.env.ref('mail.mt_note').id) subtype_id=self.env.ref('mail.mt_note').id)
# '''
# 创建生产计划
# '''
# # 工单耗时
# workorder_duration = 0
# for workorder in production.workorder_ids:
# workorder_duration += workorder.duration_expected
#
# sale_order = self.env['sale.order'].sudo().search([('name', '=', production.origin)])
# if sale_order:
# bb = sale_order.deadline_of_delivery
# productions = self.env['sf.production.plan'].with_user(SUPERUSER_ID).sudo().with_company(company_id). \
# create({
# 'name': production.name,
# 'production_id': production.id,
# 'date_planned_start': production.date_planned_start,
# 'origin': production.origin,
# 'product_qty': production.product_qty,
# 'product_id': production.product_id.id,
# 'state': 'draft',
# })
'''
创建生产计划
'''
# 工单耗时
workorder_duration = 0
for workorder in production.workorder_ids:
workorder_duration += workorder.duration_expected
sale_order = self.env['sale.order'].sudo().search([('name', '=', production.origin)])
if sale_order:
bb = sale_order.deadline_of_delivery
productions = self.env['sf.production.plan'].with_user(SUPERUSER_ID).sudo().with_company(company_id). \
create({
'name': production.name,
'order_deadline': sale_order.deadline_of_delivery,
'production_id': production.id,
'date_planned_start': production.date_planned_start,
'origin': production.origin,
'product_qty': production.product_qty,
'product_id': production.product_id.id,
'state': 'draft',
})
return True return True

View File

@@ -84,11 +84,11 @@ class FeedPerTooth(models.Model):
cutting_speed = fields.Char('径向切宽 ae(mm)') cutting_speed = fields.Char('径向切宽 ae(mm)')
machining_method = fields.Selection([('直铣', '直铣'), ('坡铣', '坡铣')], string='加工方式') machining_method = fields.Selection([('直铣', '直铣'), ('坡铣', '坡铣')], string='加工方式')
materials_type_id = fields.Many2one('sf.materials.model', string='材料型号') materials_type_id = fields.Many2one('sf.materials.model', string='材料型号')
blade_diameter = fields.Float('刃部直径D1(mm)', readonly=True, compute='_compute_product_template_id') blade_diameter = fields.Float('刃部直径D1(mm)', readonly=True, related='product_template_id.cutting_tool_blade_diameter')
feed_per_tooth = fields.Char('每齿走刀量 (mm/z)') feed_per_tooth = fields.Char('每齿走刀量 (mm/z)')
unit = fields.Char('单位', default='fz') unit = fields.Char('单位', default='fz')
@api.depends('product_template_id') # @api.depends('product_template_id')
def _compute_product_template_id(self): # def _compute_product_template_id(self):
if self.product_template_id is not None: # if self.product_template_id is not None:
self.blade_diameter = self.product_template_id.cutting_tool_blade_diameter # self.blade_diameter = self.product_template_id.cutting_tool_blade_diameter

View File

@@ -12,25 +12,46 @@ class sf_production_plan(models.Model):
# _inherit = 'mrp.production' # _inherit = 'mrp.production'
_description = 'sf_production_plan' _description = 'sf_production_plan'
name = fields.Char(string='名称') state = fields.Selection([
('draft', '待排程'),
('done', '已排程'),
('processing', '已加工'),
('finished', '已完成')
], string='工单状态', tracking=True)
name = fields.Char(string='工单编号')
# selected = fields.Boolean(default=False) # selected = fields.Boolean(default=False)
# order_number = fields.Char(string='订单号')
order_deadline = fields.Datetime(string='订单交期')
production_id = fields.Many2one('mrp.production', '关联制造订单') production_id = fields.Many2one('mrp.production', '关联制造订单')
product_qty = fields.Float(string='数量', digits='Product Unit of Measure', required=True, default=0.0) product_qty = fields.Float(string='数量', digits='Product Unit of Measure', required=True, default=0.0)
production_line_id = fields.Many2one('sf.production.line', string='生产线')
date_planned_start = fields.Datetime(string='计划开始时间', required=True, index=True, copy=False, date_planned_start = fields.Datetime(string='计划开始时间', required=True, index=True, copy=False,
default=fields.Datetime.now) default=fields.Datetime.now)
date_planned_finished = fields.Datetime(string='计划结束时间') date_planned_finished = fields.Datetime(string='计划结束时间')
state = fields.Selection([ # 排程设置selection(倒排,顺排,默认倒排)
('draft', '未排程'), ('done', '已排程')], string='状态', copy=False, index=True, readonly=True, schedule_setting = fields.Selection([
store=True, tracking=True) ('reverse', '倒排'), ('positive', '顺排')], string='排程设置', default='reverse')
product_id = fields.Many2one('product.product', '关联产品') product_id = fields.Many2one('product.product', '关联产品')
origin = fields.Char(string='来源') origin = fields.Char(string='订单号')
# 加工时长
process_time = fields.Float(string='加工时长', digits=(16, 2))
# 实际加工时长、实际开始时间、实际结束时间
actual_process_time = fields.Float(string='实际加工时长', digits=(16, 2))
actual_start_time = fields.Datetime(string='实际开始时间')
actual_end_time = fields.Datetime(string='实际结束时间')
shift = fields.Char(string='班次')
# 序号、坯料编号、坯料名称、材质、数量、长度、宽度、厚度、直径、计划开始时间、计划结束时间、状态(已产出与待产出)、操作、创建人、创建时间、客户名称、订单号、行号、长度、宽度、厚度、直径、交货数量、交货日期 # 序号、坯料编号、坯料名称、材质、数量、长度、宽度、厚度、直径、计划开始时间、计划结束时间、状态(已产出与待产出)、操作、创建人、创建时间、客户名称、订单号、行号、长度、宽度、厚度、直径、交货数量、交货日期
# sequence = fields.Integer(string='序号', required=True, copy=False, readonly=True, index=True, # sequence = fields.Integer(string='序号', required=True, copy=False, readonly=True, index=True,
# default=lambda self: self.env['ir.sequence'].sudo().next_by_code('sf.pl.plan')) # default=lambda self: self.env['ir.sequence'].sudo().next_by_code('sf.pl.plan'))
sequence = fields.Integer(string='序号', copy=False, readonly=True, index=True) sequence = fields.Integer(string='序号', copy=False, readonly=True, index=True)
current_operation_name = fields.Char(string='当前工序名称', size=64, default='生产计划') current_operation_name = fields.Char(string='当前工序名称', size=64, default='生产计划')
production_line_id = fields.Many2one('sf.production.line', string='生产线')
# state = fields.Selection([ # state = fields.Selection([
# ('未排程', '未排程'), ('已排程', '已排程')], string='State', copy=False, index=True, readonly=True, # ('未排程', '未排程'), ('已排程', '已排程')], string='State', copy=False, index=True, readonly=True,

View File

@@ -9,11 +9,15 @@
<!-- <field name="selected" widget="boolean_toggle"/> --> <!-- <field name="selected" widget="boolean_toggle"/> -->
<!-- sequence、pl_no、pl_name、quantity、plan_start_time、plan_end_time、actual_start_time、actual_end_time、state、create_uid、create_date --> <!-- sequence、pl_no、pl_name、quantity、plan_start_time、plan_end_time、actual_start_time、actual_end_time、state、create_uid、create_date -->
<!-- <field name="sequence"/> --> <!-- <field name="sequence"/> -->
<field name="state" widget="badge" decoration-warning="state == 'draft'" decoration-success="state == 'done'"/>
<field name="name"/> <field name="name"/>
<field name="origin"/>
<field name="order_deadline"/>
<field name="product_qty"/> <field name="product_qty"/>
<field name="production_line_id"/>
<field name="date_planned_start"/> <field name="date_planned_start"/>
<field name="date_planned_finished"/> <field name="date_planned_finished"/>
<field name="state" widget="badge" decoration-warning="state == 'draft'" decoration-success="state == 'done'"/> <field name="schedule_setting"/>
<button name="do_production_schedule" class="btn schedule_done" string="生产排程" type="object" attrs="{'invisible': [('state', 'not in', ['draft'])]}"/> <button name="do_production_schedule" class="btn schedule_done" string="生产排程" type="object" attrs="{'invisible': [('state', 'not in', ['draft'])]}"/>
<button name="cancel_production_schedule" class="btn schedule_cancel" string="取消排程" type="object" attrs="{'invisible': [('state', 'not in', ['done'])]}"/> <button name="cancel_production_schedule" class="btn schedule_cancel" string="取消排程" type="object" attrs="{'invisible': [('state', 'not in', ['done'])]}"/>
</tree> </tree>
@@ -28,6 +32,7 @@
<header> <header>
<!-- <button string="执行排程" name="do_production_schedule" type="object" class="oe_highlight" icon="fa-step-forward"/> --> <!-- <button string="执行排程" name="do_production_schedule" type="object" class="oe_highlight" icon="fa-step-forward"/> -->
<button string="执行排程" name="do_production_schedule" type="object" class="oe_highlight"/> <button string="执行排程" name="do_production_schedule" type="object" class="oe_highlight"/>
<button string="取消排程" name="cancel_production_schedule" type="object" class="oe_highlight"/>
<!-- <button string="销售单" name="test_sale_order" type="object" class="oe_highlight"/> --> <!-- <button string="销售单" name="test_sale_order" type="object" class="oe_highlight"/> -->
<!-- <button string="测试流程" name="liucheng_cs" type="object" class="oe_highlight"/> --> <!-- <button string="测试流程" name="liucheng_cs" type="object" class="oe_highlight"/> -->
<!-- <field name="state" widget="statusbar" statusbar_visible="draft,produce"/> --> <!-- <field name="state" widget="statusbar" statusbar_visible="draft,produce"/> -->
@@ -40,14 +45,21 @@
</div> </div>
<group> <group>
<group string="基本信息"> <group string="基本信息">
<field name="production_id"/> <field name="production_id" widget="many2one_button"/>
<field name="product_id"/> <field name="product_id"/>
<field name="origin"/> <field name="origin"/>
<field name="product_qty"/> <field name="product_qty"/>
<field name="order_deadline"/>
<field name="process_time"/>
<field name="schedule_setting"/>
<field name="production_line_id"/>
<field name="date_planned_start"/> <field name="date_planned_start"/>
<field name="date_planned_finished"/> <field name="date_planned_finished"/>
<field name="actual_process_time"/>
<field name="actual_start_time"/>
<field name="actual_end_time"/>
<field name="state"/> <field name="state"/>
<field name="production_line_id"/> <field name="shift" widget="time"/>
</group> </group>
<!-- <group string="规格信息" col="1"> --> <!-- <group string="规格信息" col="1"> -->
<!-- <group col="3"> --> <!-- <group col="3"> -->
@@ -115,8 +127,11 @@
color="production_line_id" color="production_line_id"
decoration-success="state == 'done'" decoration-success="state == 'done'"
progress_bar="name" progress_bar="name"
form_view_id="sf_production_plan_form"> form_view_id="sf_production_plan_form"
default_scale="year"
scales="day,week,month,year"
precision="{'day': 'hour:quarter', 'week': 'day:half', 'month': 'day', 'year': 'month:quarter'}">
<field name="shift"/>
<field name="name"/> <field name="name"/>
<field name="product_qty"/> <field name="product_qty"/>
<field name="date_planned_start"/> <field name="date_planned_start"/>

View File

@@ -10,7 +10,7 @@
""", """,
'category': 'sf', 'category': 'sf',
'website': 'https://www.sf.jikimo.com', 'website': 'https://www.sf.jikimo.com',
'depends': ['sale_management', 'web_widget_model_viewer',], 'depends': ['sale_management', 'web_widget_model_viewer', 'sale_stock'],
'data': [ 'data': [
'security/group_security.xml', 'security/group_security.xml',
'security/ir.model.access.csv', 'security/ir.model.access.csv',

View File

@@ -4,7 +4,7 @@
<record id="view_order_tree_inherit_sf" model="ir.ui.view"> <record id="view_order_tree_inherit_sf" model="ir.ui.view">
<field name="name">sale.order.tree</field> <field name="name">sale.order.tree</field>
<field name="model">sale.order</field> <field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_tree"/> <field name="inherit_id" ref="sale_stock.view_order_tree"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//field[@name='name']" position="after"> <xpath expr="//field[@name='name']" position="after">
<!-- <attribute name="string">订单号</attribute>--> <!-- <attribute name="string">订单号</attribute>-->

View File

@@ -105,79 +105,79 @@ class SfToolMaterialSearch(models.Model):
cutting_speed_ids = fields.Many2many('sf.cutting.speed', string='切削速度Vc') cutting_speed_ids = fields.Many2many('sf.cutting.speed', string='切削速度Vc')
feed_per_tooth_ids = fields.Many2many('sf.feed.per.tooth', 'rel_feed_per_tooth_ids', '每齿走刀量fz') feed_per_tooth_ids = fields.Many2many('sf.feed.per.tooth', 'rel_feed_per_tooth_ids', '每齿走刀量fz')
@api.constrains('suitable_machining_method_ids') # @api.constrains('suitable_machining_method_ids')
def _check_suitable_machining_method_ids(self): # def _check_suitable_machining_method_ids(self):
for record in self: # for record in self:
if len(record.suitable_machining_method_ids) == 0 and self.cutting_tool_type == '整体式刀具': # if len(record.suitable_machining_method_ids) == 0 and self.cutting_tool_type == '整体式刀具':
raise ValidationError("适合加工方式不能为空!") # raise ValidationError("适合加工方式不能为空!")
#
@api.constrains('blade_tip_characteristics_ids') # @api.constrains('blade_tip_characteristics_ids')
def _check_blade_tip_characteristics_ids(self): # def _check_blade_tip_characteristics_ids(self):
for record in self: # for record in self:
if len(record.blade_tip_characteristics_ids) == 0 and self.cutting_tool_type == '整体式刀具': # if len(record.blade_tip_characteristics_ids) == 0 and self.cutting_tool_type == '整体式刀具':
raise ValidationError("刀尖特征不能为空!") # raise ValidationError("刀尖特征不能为空!")
if len(record.blade_tip_characteristics_ids) > 1 and self.cutting_tool_type == '整体式刀具': # if len(record.blade_tip_characteristics_ids) > 1 and self.cutting_tool_type == '整体式刀具':
raise ValidationError("刀尖特征只能单选!") # raise ValidationError("刀尖特征只能单选!")
#
@api.constrains('handle_type_ids') # @api.constrains('handle_type_ids')
def _check_handle_type_ids(self): # def _check_handle_type_ids(self):
for record in self: # for record in self:
if len(record.handle_type_ids) == 0 and self.cutting_tool_type == '整体式刀具': # if len(record.handle_type_ids) == 0 and self.cutting_tool_type == '整体式刀具':
raise ValidationError("柄部类型不能为空!") # raise ValidationError("柄部类型不能为空!")
if len(record.handle_type_ids) > 1 and self.cutting_tool_type == '整体式刀具': # if len(record.handle_type_ids) > 1 and self.cutting_tool_type == '整体式刀具':
raise ValidationError("柄部类型只能单选!") # raise ValidationError("柄部类型只能单选!")
#
@api.constrains('cutting_direction_ids') # @api.constrains('cutting_direction_ids')
def _check_cutting_direction_ids(self): # def _check_cutting_direction_ids(self):
for record in self: # for record in self:
if len(record.cutting_direction_ids) == 0 and self.cutting_tool_type == '整体式刀具': # if len(record.cutting_direction_ids) == 0 and self.cutting_tool_type == '整体式刀具':
raise ValidationError("走刀方向不能为空!") # raise ValidationError("走刀方向不能为空!")
#
@api.constrains('suitable_coolant_ids') # @api.constrains('suitable_coolant_ids')
def _check_suitable_coolant_ids(self): # def _check_suitable_coolant_ids(self):
for record in self: # for record in self:
if not record.suitable_coolant_ids and self.cutting_tool_type == '整体式刀具': # if not record.suitable_coolant_ids and self.cutting_tool_type == '整体式刀具':
raise ValidationError("适合冷却液不能为空!") # raise ValidationError("适合冷却液不能为空!")
#
@api.constrains('integral_total_length') # @api.constrains('integral_total_length')
def _check_integral_total_length(self): # def _check_integral_total_length(self):
if self.integral_total_length <= 0 and self.cutting_tool_type == '整体式刀具': # if self.integral_total_length <= 0 and self.cutting_tool_type == '整体式刀具':
raise ValidationError("总长度不能为0") # raise ValidationError("总长度不能为0")
#
@api.constrains('integral_shank_length') # @api.constrains('integral_shank_length')
def _check_integral_shank_length(self): # def _check_integral_shank_length(self):
if self.integral_shank_length <= 0 and self.cutting_tool_type == '整体式刀具': # if self.integral_shank_length <= 0 and self.cutting_tool_type == '整体式刀具':
raise ValidationError("柄部长度不能为0") # raise ValidationError("柄部长度不能为0")
#
@api.constrains('integral_blade_length') # @api.constrains('integral_blade_length')
def _check_integral_blade_length(self): # def _check_integral_blade_length(self):
if self.integral_blade_length <= 0 and self.cutting_tool_type == '整体式刀具': # if self.integral_blade_length <= 0 and self.cutting_tool_type == '整体式刀具':
raise ValidationError("刃部长度不能为0") # raise ValidationError("刃部长度不能为0")
#
@api.constrains('integral_blade_number') # @api.constrains('integral_blade_number')
def _check_integral_blade_number(self): # def _check_integral_blade_number(self):
if self.integral_blade_number <= 0 and self.cutting_tool_type == '整体式刀具': # if self.integral_blade_number <= 0 and self.cutting_tool_type == '整体式刀具':
raise ValidationError("刃数不能为0") # raise ValidationError("刃数不能为0")
#
@api.constrains('integral_shank_diameter') # @api.constrains('integral_shank_diameter')
def _check_integral_shank_diameter(self): # def _check_integral_shank_diameter(self):
if self.integral_shank_diameter <= 0 and self.cutting_tool_type == '整体式刀具': # if self.integral_shank_diameter <= 0 and self.cutting_tool_type == '整体式刀具':
raise ValidationError("柄部直径不能为0") # raise ValidationError("柄部直径不能为0")
#
@api.constrains('integral_blade_diameter') # @api.constrains('integral_blade_diameter')
def _check_integral_blade_diameter(self): # def _check_integral_blade_diameter(self):
if self.integral_blade_diameter <= 0 and self.cutting_tool_type == '整体式刀具': # if self.integral_blade_diameter <= 0 and self.cutting_tool_type == '整体式刀具':
raise ValidationError("刃部直径不能为0") # raise ValidationError("刃部直径不能为0")
#
@api.constrains('integral_run_out_accuracy_min') # @api.constrains('integral_run_out_accuracy_min')
def _check_integral_blade_diameter(self): # def _check_integral_blade_diameter(self):
if self.integral_run_out_accuracy_min <= 0 and self.cutting_tool_type == '整体式刀具': # if self.integral_run_out_accuracy_min <= 0 and self.cutting_tool_type == '整体式刀具':
raise ValidationError("端跳精度最小(min)不能为0") # raise ValidationError("端跳精度最小(min)不能为0")
#
@api.constrains('integral_run_out_accuracy_max') # @api.constrains('integral_run_out_accuracy_max')
def _check_integral_run_out_accuracy_max(self): # def _check_integral_run_out_accuracy_max(self):
if self.integral_run_out_accuracy_max <= 0 and self.cutting_tool_type == '整体式刀具': # if self.integral_run_out_accuracy_max <= 0 and self.cutting_tool_type == '整体式刀具':
raise ValidationError("端跳精度最大(max)不能为0") # raise ValidationError("端跳精度最大(max)不能为0")
# integral_front_angle = fields.Float('整体式刀具前角(°)') # integral_front_angle = fields.Float('整体式刀具前角(°)')
# integral_rear_angle = fields.Float('整体式刀具后角(°)') # integral_rear_angle = fields.Float('整体式刀具后角(°)')

View File

@@ -194,50 +194,56 @@
<group> <group>
<field name="integral_code" invisible="True"/> <field name="integral_code" invisible="True"/>
<field name="integral_total_length" string="总长度(mm)"/> <field name="integral_total_length" string="总长度(mm)"/>
<field name="integral_shank_length" string="柄部长度(mm)"/> <field name="mrs_materials_model_id" string="刀具材质" placeholder="请选择"
attrs="{'required': [('cutting_tool_type','=','整体式刀具')]}"/>
<field name="integral_hardness" string="刀具硬度(HRC)"/>
<field name="integral_blade_length" string="刃部长度(mm)"/> <field name="integral_blade_length" string="刃部长度(mm)"/>
<field name="integral_neck_length" string="颈部长度(mm)"/> <field name="integral_blade_diameter" string="刃部直径(mm)" class="diameter"/>
<field name="integral_blade_tip_taper" string="刀尖锥度(°)"/>
<field name="integral_blade_helix_angle" string="刃部螺旋角(°)"/>
<field name="integral_blade_type" string="刃部类型"/> <field name="integral_blade_type" string="刃部类型"/>
<field name="mrs_materials_model_id" string="刀具材质" attrs="{'required': [('cutting_tool_type','=','整体式刀具')]}"/> <field name="integral_blade_helix_angle" string="刃部螺旋角(°)"/>
<label for="integral_run_out_accuracy_min" string="端跳精度:"/> <field name="integral_blade_number" string="刃数(个)"/>
<div class="test_model">
<label for="integral_run_out_accuracy_min" string="最小(min)"/>
<field name="integral_run_out_accuracy_min" class="o_address_zip" required="1"
options="{'format': false}" attrs="{'required': [('cutting_tool_type','=','整体式刀具')]}"/>
<span>(mm)&amp;nbsp;</span>
<label for="integral_run_out_accuracy_max" string="最大(max)"/>
<field name="integral_run_out_accuracy_max" class="o_address_zip" required="1"
options="{'format': false}" attrs="{'required': [('cutting_tool_type','=','整体式刀具')]}"/>
<span>(mm)&amp;nbsp;</span>
</div>
</group> </group>
<group> <group>
<field name="integral_blade_number" string="刃数(个)"/> <field name="integral_shank_length" string="柄部长度(mm)"/>
<field name="integral_shank_diameter" string="柄部直径(mm)"/> <field name="integral_shank_diameter" string="柄部直径(mm)" class="diameter"/>
<field name="integral_blade_diameter" string="刃部直径(mm)"/> <field name="integral_neck_length" string="颈部长度(mm)"/>
<field name="integral_neck_diameter" string="颈部直径(mm)"/> <field name="integral_neck_diameter" string="颈部直径(mm)" class="diameter"/>
<field name="integral_blade_tip_diameter" string="刀尖直径(mm)"/> <field name="integral_blade_tip_diameter" string="刀尖直径(mm)" class="diameter"/>
<field name="integral_hardness" string="刀具硬度(HRC)"/> <field name="integral_blade_tip_taper" string="刀尖锥度(°)"/>
<field name="integral_coarse_medium_fine" string="粗/中/精" attrs="{'required': [('cutting_tool_type','=','整体式刀具')]}"/> <label for="integral_run_out_accuracy_min" string="端跳精度:"/>
<div class="test_model">
<label for="integral_run_out_accuracy_min" string="最小(min)"/>
<field name="integral_run_out_accuracy_min" class="o_address_zip" required="1"
options="{'format': false}" attrs="{'required': [('cutting_tool_type','=','整体式刀具')]}"/>
<span>(mm)&amp;nbsp;</span>
<label for="integral_run_out_accuracy_max" string="最大(max)"/>
<field name="integral_run_out_accuracy_max" class="o_address_zip" required="1"
options="{'format': false}" attrs="{'required': [('cutting_tool_type','=','整体式刀具')]}"/>
<span>(mm)&amp;nbsp;</span>
</div>
<field name="integral_coarse_medium_fine" string="粗/中/精" placeholder="请选择"
attrs="{'required': [('cutting_tool_type','=','整体式刀具')]}"/>
<field name="integral_coating_material" string="涂层材质"/> <field name="integral_coating_material" string="涂层材质"/>
</group> </group>
</group> </group>
<group string="适合加工方式"> <group string="适合加工方式">
<field name="suitable_machining_method_ids" string=""/> <field name="suitable_machining_method_ids" string="" widget="custom_many2many_checkboxes"/>
</group> </group>
<group string="刀尖特征"> <group>
<field name="blade_tip_characteristics_ids" string=""/> <group string="刀尖特征">
<field name="blade_tip_characteristics_ids" string="" widget="custom_many2many_checkboxes"/>
</group>
<group string="柄部类型">
<field name="handle_type_ids" string="" widget="custom_many2many_checkboxes"/>
</group>
</group> </group>
<group string="柄部类型"> <group>
<field name="handle_type_ids" string=""/> <group string="走刀方向">
</group> <field name="cutting_direction_ids" string="" widget="custom_many2many_checkboxes"/>
<group string="走刀方向"> </group>
<field name="cutting_direction_ids" string=""/> <group string="适合冷却液">
</group> <field name="suitable_coolant_ids" string="" widget="custom_many2many_checkboxes"/>
<group string="适合冷却液"> </group>
<field name="suitable_coolant_ids" string=""/>
</group> </group>
</page> </page>
<page string="切削速度Vc" attrs="{'invisible': [('cutting_tool_type','!=','整体式刀具')]}"> <page string="切削速度Vc" attrs="{'invisible': [('cutting_tool_type','!=','整体式刀具')]}">