Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/新增工件装夹

This commit is contained in:
jinling.yang
2023-07-06 17:33:47 +08:00
33 changed files with 1133 additions and 301 deletions

View File

@@ -156,30 +156,30 @@ if env.user.has_group('mrp.group_mrp_workorder_dependencies'):
</field> </field>
</record> </record>
<record model="ir.actions.act_window" id="mrp_workorder_action_tablet"> <!-- <record model="ir.actions.act_window" id="mrp_workorder_action_tablet">-->
<field name="name">Work Orders</field> <!-- <field name="name">Work Orders</field>-->
<field name="type">ir.actions.act_window</field> <!-- <field name="type">ir.actions.act_window</field>-->
<field name="res_model">mrp.workorder</field> <!-- <field name="res_model">mrp.workorder</field>-->
<field name="view_mode">kanban,tree,form</field> <!-- <field name="view_mode">kanban,tree,form</field>-->
<field name="view_ids" eval="[(5, 0, 0), <!-- <field name="view_ids" eval="[(5, 0, 0),-->
(0, 0, {'view_mode': 'kanban', 'view_id': ref('mrp.workcenter_line_kanban')}), <!-- (0, 0, {'view_mode': 'kanban', 'view_id': ref('mrp.workcenter_line_kanban')}),-->
(0, 0, {'view_mode': 'tree', 'view_id': ref('mrp.mrp_production_workorder_tree_editable_view')}) ]"/> <!-- (0, 0, {'view_mode': 'tree', 'view_id': ref('mrp.mrp_production_workorder_tree_editable_view')}) ]"/>-->
<field name="target">fullscreen</field> <!-- <field name="target">fullscreen</field>-->
<field name="domain">[('state', 'not in', ['done', 'cancel'])]</field> <!-- <field name="domain">[('state', 'not in', ['done', 'cancel'])]</field>-->
<field name="context">{'search_default_workcenter_id': active_id}</field> <!-- <field name="context">{'search_default_workcenter_id': active_id}</field>-->
<field name="help" type="html"> <!-- <field name="help" type="html">-->
<p class="o_view_nocontent_workorder"> <!-- <p class="o_view_nocontent_workorder">-->
No work orders to do! <!-- No work orders to do!-->
</p><p> <!-- </p><p>-->
Work orders are operations to do as part of a manufacturing order. <!-- Work orders are operations to do as part of a manufacturing order.-->
Operations are defined in the bill of materials or added in the manufacturing order directly. <!-- Operations are defined in the bill of materials or added in the manufacturing order directly.-->
</p><p> <!-- </p><p>-->
Use the table work center control panel to register operations in the shop floor directly. <!-- Use the table work center control panel to register operations in the shop floor directly.-->
The tablet provides worksheets for your workers and allow them to scrap products, track time, <!-- The tablet provides worksheets for your workers and allow them to scrap products, track time,-->
launch a maintenance request, perform quality tests, etc. <!-- launch a maintenance request, perform quality tests, etc.-->
</p> <!-- </p>-->
</field> <!-- </field>-->
</record> <!-- </record>-->
<!-- override to change the no content image --> <!-- override to change the no content image -->
<record model="ir.actions.act_window" id="mrp.mrp_workorder_todo"> <record model="ir.actions.act_window" id="mrp.mrp_workorder_todo">

View File

@@ -5,50 +5,40 @@ class Assemble(models.Model):
_name = 'sf.assemble' _name = 'sf.assemble'
_description = "组合装夹" _description = "组合装夹"
functional_fixture_code = fields.Char(string="功能夹具编码", size=25, required=True) functional_fixture_code = fields.Char(string="功能夹具编码", readonly=True)
functional_fixture_name = fields.Char(string="功能夹具名称", size=25, required=True) name = fields.Char(string="功能夹具名称", readonly=True)
functional_fixture_type = fields.Char(string="功能夹具类型", required=True) functional_fixture_type_id = fields.Many2one('sf.functional.fixture.type', string="功能夹具类型", readonly=True)
chuck_name = fields.Char(string="卡盘名称", required=True) chuck_name = fields.Char(string="卡盘名称")
chuck_brand_id = fields.Many2one('sf.machine.brand', string="卡盘品牌", required=True) chuck_brand_id = fields.Many2one('sf.machine.brand', string="卡盘品牌")
chuck_type_id = fields.Char(string="卡盘类型", required=True) chuck_type_id = fields.Char(string="卡盘类型")
chuck_model_id = fields.Char(string="卡盘型号", required=True) chuck_model_id = fields.Char(string="卡盘型号")
tray_name = fields.Char(string="托盘名称", required=True) tray_name = fields.Char(string="托盘名称")
tray_brand_id = fields.Many2one('sf.machine.brand', string="托盘品牌", required=True) tray_brand_id = fields.Many2one('sf.machine.brand', string="托盘品牌")
tray_type_id = fields.Char(string="托盘类型", required=True) tray_type_id = fields.Char(string="托盘类型")
tray_model_id = fields.Char(string="托盘型号", required=True) tray_model_id = fields.Char(string="托盘型号")
real_code = fields.Char(string="真实坯料编码", size=25, required=True) real_code = fields.Char(string="真实坯料编码")
real_name = fields.Char(string="真实坯料名称", size=25, required=True) real_name = fields.Char(string="真实坯料名称")
total_wight = fields.Float(string="总重量", required=True) real_width = fields.Float(string="真实宽度")
real_length = fields.Float(string="真实长度")
real_height = fields.Float(string="真实高度")
real_diameter = fields.Float(string="真实直径")
total_wight = fields.Float(string="总重量")
maximum_carrying_weight = fields.Char(string="最大承载重量[kg]") maximum_carrying_weight = fields.Char(string="最大承载重量[kg]")
maximum_clamping_force = fields.Char(string="最大夹持力[n]") maximum_clamping_force = fields.Char(string="最大夹持力[n]")
production_line = fields.Char(string="生产线", required=True) production_line = fields.Char(string="生产线")
# 以下为智能工厂工单带过来的机床信息 # 以下为智能工厂工单带过来的机床信息
machine_tool = fields.Many2one('sf.machine_tool', string="机床名称", required=True) machine_tool = fields.Many2one('sf.machine_tool', string="机床名称")
machine_tool_startime = fields.Date(string="机床开始加工时间", required=True) machine_tool_startime = fields.Date(string="机床开始加工时间")
# 以下为智能工厂工单带过来的信息 # 以下为智能工厂工单带过来的信息
apply_staff = fields.Char(string="申请人", required=True) apply_staff = fields.Char(string="申请人")
machine_tool_code = fields.Char(string="机床编码", required=True) machine_tool_code = fields.Char(string="机床编码")
apply_time = fields.Date(string="申请时间", required=True) apply_time = fields.Date(string="申请时间")
apply_reason = fields.Char(string="申请原因", required=True) apply_reason = fields.Char(string="申请原因")
# 以下为装夹的信息 # 以下为装夹的信息
preset_staff = fields.Char(string="预调名称", required=True) preset_staff = fields.Char(string="预调名称")
preset_time = fields.Date(string="预调时间", required=True) preset_time = fields.Date(string="预调时间")
material_taker = fields.Char(string="领料人", required=True) material_taker = fields.Char(string="领料人")
material_removal_time = fields.Date(string="领料出库时间", required=True) material_removal_time = fields.Date(string="领料出库时间")
remark = fields.Char(string="备注", required=True) remark = fields.Char(string="备注")
# 以下为出库的信息
stock_removal_code = fields.Char(string="出库人")

View File

@@ -10,8 +10,8 @@
<search string="工件夹具"> <search string="工件夹具">
<field name="functional_fixture_code" string="编码" <field name="functional_fixture_code" string="编码"
filter_domain="[('functional_fixture_code', 'ilike', self)]"/> filter_domain="[('functional_fixture_code', 'ilike', self)]"/>
<field name="functional_fixture_name" string="名称" <field name="name" string="名称"
filter_domain="[('functional_fixture_name', 'ilike', self)]"/> filter_domain="[('name', 'ilike', self)]"/>
<!-- <field name="material_id" string="材质"--> <!-- <field name="material_id" string="材质"-->
<!-- filter_domain="[('material_id.name', 'ilike', self)]"/>--> <!-- filter_domain="[('material_id.name', 'ilike', self)]"/>-->
</search> </search>
@@ -24,8 +24,8 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="工件夹具"> <tree string="工件夹具">
<field name="functional_fixture_code"/> <field name="functional_fixture_code"/>
<field name="functional_fixture_name"/> <field name="name"/>
<field name="functional_fixture_type"/> <field name="functional_fixture_type_id"/>
<field name="chuck_type_id"/> <field name="chuck_type_id"/>
<field name="chuck_name"/> <field name="chuck_name"/>
<field name="chuck_brand_id"/> <field name="chuck_brand_id"/>
@@ -65,87 +65,57 @@
<group string="基本信息"> <group string="基本信息">
<group> <group>
<field name="functional_fixture_code"/> <field name="functional_fixture_code"/>
<field name="functional_fixture_type_id"/>
</group>
<group>
<field name="functional_fixture_type"/>
</group>
</group>
<!-- <group string="坯料(工件)申请信息">-->
<!-- <group>-->
<!-- <field name="functional_fixture_code"/>-->
<!-- <field name="functional_fixture_type"/>-->
<!--&lt;!&ndash; <field name="surface_accuracy"/>&ndash;&gt;-->
<!-- </group>-->
<!-- <group>-->
<!-- <field name="functional_fixture_name"/>-->
<!-- <label for="apply_length" string="尺寸[mm]"-->
<!-- />-->
<!-- <div class="o_address_format"-->
<!-- >-->
<!-- <label for="apply_length" string="长"/>-->
<!-- <field name="apply_length" class="o_address_zip"-->
<!-- options="{'format': false}"-->
<!-- />-->
<!-- <span>&amp;nbsp;</span>-->
<!-- <label for="apply_width" string="宽"/>-->
<!-- <field name="apply_width" class="o_address_zip"-->
<!-- options="{'format': false}"-->
<!-- />-->
<!-- <span>&amp;nbsp;</span>-->
<!-- <label for="apply_height" string="高"/>-->
<!-- <field name="apply_height" class="o_address_zip"-->
<!-- options="{'format': false}"-->
<!-- />-->
<!-- </div>-->
<!-- <field name="apply_weight"/>-->
<!-- <field name="apply_diameter"/>-->
<!-- </group>-->
<!-- </group>-->
<group string="坯料(工件)装夹信息">
<group string="卡盘">
<field name="chuck_name"/>
<field name="chuck_brand_id"/>
<field name="chuck_type_id"/>
<field name="chuck_model_id"/>
</group>
<group string="托盘">
<field name="tray_name"/>
<field name="tray_brand_id"/>
<field name="tray_type_id"/>
<field name="tray_model_id"/>
</group>
<group>
<field name="real_code"/>
<field name="real_name"/>
<!-- <label for="real_length" string="尺寸[mm]"-->
<!-- />-->
<!-- <div class="o_address_format"-->
<!-- >-->
<!-- <label for="real_length" string="长"/>-->
<!-- <field name="real_length" class="o_address_zip"-->
<!-- options="{'format': false}"-->
<!-- />-->
<!-- <span>&amp;nbsp;</span>-->
<!-- <label for="real_width" string="宽"/>-->
<!-- <field name="real_width" class="o_address_zip"-->
<!-- options="{'format': false}"-->
<!-- />-->
<!-- <span>&amp;nbsp;</span>-->
<!-- <label for="real_height" string="高"/>-->
<!-- <field name="real_height" class="o_address_zip"-->
<!-- options="{'format': false}"-->
<!-- />-->
<!-- </div>-->
<!-- <field name="real_diameter"/>-->
</group>
</group>
<group string="其他">
<group>
<field name="remark"/> <field name="remark"/>
</group> </group>
<group>
<field name="name"/>
</group>
</group> </group>
<notebook>
<page string="装夹" name="clamping" attrs="{'invisible': [('chuck_type_id', '=', False)]}">
<group>
<group string="卡盘">
<field name="chuck_type_id"></field>
<field name="chuck_name"></field>
<field name="chuck_brand_id"></field>
<field name="chuck_model_id"></field>
</group>
<group string="托盘">
<field name="tray_type_id"></field>
<field name="tray_name"></field>
<field name="tray_brand_id"></field>
<field name="tray_model_id"></field>
</group>
<group string="坯料">
<field name="real_code" string="坯料编码"></field>
<field name="real_name" string="坯料名称"></field>
<label for="real_length" string="尺寸[mm]"/>
<div class="o_address_format">
<label for="real_length" string="长"/>
<field name="real_length" class="o_address_zip"
options="{'format': false}"/>
<span>&amp;nbsp;</span>
<label for="real_width" string="宽"/>
<field name="real_width" class="o_address_zip"
options="{'format': false}"/>
<span>&amp;nbsp;</span>
<label for="real_height" string="高"/>
<field name="real_height" class="o_address_zip"
options="{'format': false}"/>
</div>
<field name="real_diameter" string="直径[mm]"></field>
</group>
</group>
</page>
<page string="出库" name="stock_removal"
attrs="{'invisible': [('production_line', '=', False)]}">
<group>
<field name="production_line"></field>
<field name="machine_tool" string="机台"></field>
</group>
</page>
</notebook>
</sheet> </sheet>
</form> </form>
</field> </field>

View File

@@ -4,22 +4,24 @@
<field name="name">sf.stock.removal.wizard.form.view</field> <field name="name">sf.stock.removal.wizard.form.view</field>
<field name="model">sf.stock.removal.wizard</field> <field name="model">sf.stock.removal.wizard</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="出库"> <form string="装夹">
<group> <sheet>
<group> <group>
<field name="code" string="编码"></field> <group>
<field name="type" string="类型"></field> <field name="code" string="功能夹具编码"></field>
<field name="machine_tool" string="类型"></field> <field name="type" string="类型"></field>
<field name="machine_tool" string="机台"></field>
</group>
<group>
<field name="name" string="功能夹具名称"></field>
<field name="production_line"></field>
</group>
</group> </group>
<group> <footer>
<field name="name" string="名称"></field> <button string="确定" name="submit" type="object" class="oe_highlight"/>
<field name="production_line" string="类型"></field> <button string="取消" class="btn btn-secondary" special="cancel"/>
</group> </footer>
</group> </sheet>
<footer>
<button string="确定" name="submit" type="object" class="oe_highlight"/>
<button string="取消" class="btn btn-secondary" special="cancel"/>
</footer>
</form> </form>
</field> </field>
</record> </record>

View File

@@ -5,70 +5,74 @@
<field name="model">sf.workpiece.clamping.wizard</field> <field name="model">sf.workpiece.clamping.wizard</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="装夹"> <form string="装夹">
<group string="坯料(工件)申请信息"> <sheet>
<group> <group string="坯料(工件)申请信息">
<field name="apply_code" string="编码"></field> <group>
<field name="material_id" string="材质"></field> <field name="apply_code" string="坯料编码"></field>
<field name="material_id" string="坯料材质"></field>
</group>
<group>
<field name="apply_name" string="坯料名称"></field>
<label for="apply_length" string="尺寸[mm]"/>
<div class="o_address_format">
<label for="apply_length" string="长"/>
<field name="apply_length" class="o_address_zip"
options="{'format': false}"/>
<span>&amp;nbsp;</span>
<label for="apply_width" string="宽"/>
<field name="apply_width" class="o_address_zip"
options="{'format': false}"/>
<span>&amp;nbsp;</span>
<label for="apply_height" string="高"/>
<field name="apply_height" class="o_address_zip"
options="{'format': false}"/>
</div>
<field name="apply_diameter" string="直径[mm]"></field>
</group>
</group>
<group string="坯料(工件)装夹信息">
<group string="卡盘">
<field name="chuck_type_id"></field>
<field name="chuck_name"></field>
<field name="chuck_brand_id"></field>
<field name="chuck_model_id"></field>
</group>
<group string="托盘">
<field name="tray_type_id"></field>
<field name="tray_name"></field>
<field name="tray_brand_id"></field>
<field name="tray_model_id"></field>
</group>
<group string="坯料">
<field name="real_code" string="坯料编码"></field>
<field name="real_name" string="坯料名称"></field>
<label for="real_length" string="尺寸[mm]"/>
<div class="o_address_format">
<label for="real_length" string="长"/>
<field name="real_length" class="o_address_zip"
options="{'format': false}"/>
<span>&amp;nbsp;</span>
<label for="real_width" string="宽"/>
<field name="real_width" class="o_address_zip"
options="{'format': false}"/>
<span>&amp;nbsp;</span>
<label for="real_height" string="高"/>
<field name="real_height" class="o_address_zip"
options="{'format': false}"/>
</div>
<field name="real_diameter" string="直径[mm]"></field>
</group>
</group> </group>
<group> <group>
<field name="apply_name" string="名称"></field> <group>
<label for="apply_length" string="尺寸[mm]"/> <field name="preset_program_information"></field>
<div class="o_address_format"> </group>
<label for="apply_length" string="长"/>
<field name="apply_length" class="o_address_zip"
options="{'format': false}"/>
<span>&amp;nbsp;</span>
<label for="apply_width" string="宽"/>
<field name="apply_width" class="o_address_zip"
options="{'format': false}"/>
<span>&amp;nbsp;</span>
<label for="apply_height" string="高"/>
<field name="apply_height" class="o_address_zip"
options="{'format': false}"/>
</div>
<field name="apply_diameter" string="直径"></field>
</group> </group>
</group> <footer>
<group string="坯料(工件)装夹信息"> <button string="确定" name="submit" type="object" class="oe_highlight"/>
<group string="卡盘"> <button string="取消" class="btn btn-secondary" special="cancel"/>
<field name="chuck_type_id"></field> </footer>
<field name="chuck_name"></field> </sheet>
<field name="chuck_brand_id"></field>
<field name="chuck_model_id"></field>
</group>
<group string="托盘">
<field name="tray_type_id"></field>
<field name="tray_name"></field>
<field name="tray_brand_id"></field>
<field name="tray_model_id"></field>
</group>
<group string="坯料">
<field name="real_code"></field>
<field name="real_name"></field>
<label for="real_length" string="尺寸[mm]"/>
<div class="o_address_format">
<label for="real_length" string="长"/>
<field name="real_length" class="o_address_zip"
options="{'format': false}"/>
<span>&amp;nbsp;</span>
<label for="real_width" string="宽"/>
<field name="real_width" class="o_address_zip"
options="{'format': false}"/>
<span>&amp;nbsp;</span>
<label for="real_height" string="高"/>
<field name="real_height" class="o_address_zip"
options="{'format': false}"/>
</div>
<field name="real_diameter" string="直径"></field>
</group>
<group>
<field name="preset_program_information"></field>
</group>
</group>
<footer>
<button string="确定" name="submit" type="object" class="oe_highlight"/>
<button string="取消" class="btn btn-secondary" special="cancel"/>
</footer>
</form> </form>
</field> </field>
</record> </record>

View File

@@ -33,8 +33,8 @@ class StatusChange(models.Model):
'process_start_time': process_start_time, 'process_start_time': process_start_time,
}, },
} }
url1 = config['bfm_url'] + '/api/get/state/get_order' # url1 = config['bfm_url'] + '/api/get/state/get_order'
requests.post(url1, json=json1, data=None) # requests.post(url1, json=json1, data=None)
logging.info('接口已经执行=============') logging.info('接口已经执行=============')
return res return res
@@ -57,8 +57,8 @@ class StatusChange(models.Model):
'state': '待派单', 'state': '待派单',
}, },
} }
url1 = config['bfm_url'] + '/api/get/state/cancel_order' # url1 = config['bfm_url'] + '/api/get/state/cancel_order'
requests.post(url1, json=json1, data=None) # requests.post(url1, json=json1, data=None)
return res return res

View File

@@ -24,8 +24,7 @@ class SfEquipmentSaintenanceStandards(models.Model):
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)
maintenance_equipment_category_id = fields.Many2one('maintenance.equipment.category', string='设备类别') maintenance_equipment_category_id = fields.Many2one('maintenance.equipment.category', string='设备类别')
maintenance_equipment_ids = fields.Many2many('maintenance.equipment', 'sf_maintenance_equipment_ids', string='设备') maintenance_equipment_ids = fields.Many2many('maintenance.equipment', 'sf_maintenance_equipment_ids', string='设备')
maintenance_projects = fields.Char('维保项目') maintenance_standards_ids = fields.One2many('maintenance.standards', 'equipment_maintenance_standards_id', string='维保项目')
maintenance_standards = fields.Char('维保标准')
eq_maintenance_ids = fields.One2many('maintenance.equipment', 'eq_maintenance_id', string='保养设备') eq_maintenance_ids = fields.One2many('maintenance.equipment', 'eq_maintenance_id', string='保养设备')
overhaul_ids = fields.One2many('maintenance.equipment', 'overhaul_id', string='检修设备') overhaul_ids = fields.One2many('maintenance.equipment', 'overhaul_id', string='检修设备')
@@ -37,7 +36,14 @@ 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)]})
class SfSaintenanceStandards(models.Model):
_name = 'maintenance.standards'
_description = '维保项目'
name = fields.Char('维保项目')
maintenance_standards = fields.Char('维保标准')
equipment_maintenance_standards_id = fields.Many2one('equipment.maintenance.standards', string='设备维保标准')
maintenance_request_id = fields.Many2one('maintenance.request', string='设备维保计划')

View File

@@ -4,10 +4,12 @@ import base64
from odoo import api, fields, models, SUPERUSER_ID, _ from odoo import api, fields, models, SUPERUSER_ID, _
from odoo.exceptions import UserError from odoo.exceptions import UserError
import logging import logging
from datetime import date, datetime, timedelta
import requests import requests
import json import json
from odoo.addons.sf_base.commons.common import Common from odoo.addons.sf_base.commons.common import Common
class SfMaintenanceEquipmentCategory(models.Model): class SfMaintenanceEquipmentCategory(models.Model):
_inherit = 'maintenance.equipment.category' _inherit = 'maintenance.equipment.category'
_description = '设备类别' _description = '设备类别'
@@ -20,6 +22,7 @@ class SfMaintenanceEquipment(models.Model):
_description = '设备' _description = '设备'
crea_url = "/api/machine_tool/create" crea_url = "/api/machine_tool/create"
def get_no(self): def get_no(self):
partner = self.env['maintenance.equipment'].sudo().search( partner = self.env['maintenance.equipment'].sudo().search(
[('MTcode', '!=', '')], [('MTcode', '!=', '')],
@@ -33,19 +36,23 @@ class SfMaintenanceEquipment(models.Model):
num = "%04d" % m num = "%04d" % m
return num return num
equipment_maintenance_standards_ids = fields.Many2many('equipment.maintenance.standards', 'sf_maintenance_equipment_ids', string='设备维保标准') equipment_maintenance_standards_ids = fields.Many2many('equipment.maintenance.standards',
eq_maintenance_id =fields.Many2one('equipment.maintenance.standards', string='设备保标准', domain="[('maintenance_type','=','保养')]") 'sf_maintenance_equipment_ids', string='设备保标准')
eq_maintenance_id = fields.Many2one('equipment.maintenance.standards', string='设备保养标准',
domain="[('maintenance_type','=','保养')]")
overhaul_date = fields.Date(string='下次预防检修') overhaul_date = fields.Date(string='下次预防检修')
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='设备检修标准', domain="[('maintenance_type','=','检修')]") overhaul_id = fields.Many2one('equipment.maintenance.standards', string='设备检修标准',
domain="[('maintenance_type','=','检修')]")
@api.onchange('eq_maintenance_id', 'overhaul_id') @api.onchange('eq_maintenance_id', 'overhaul_id')
def _compute_equipment_maintenance_standards_ids(self): def _compute_equipment_maintenance_standards_ids(self):
for record in self: for record in self:
if record.eq_maintenance_id and record.overhaul_id: if record.eq_maintenance_id and record.overhaul_id:
record.equipment_maintenance_standards_ids = [(6, 0, [record.eq_maintenance_id.id, record.overhaul_id.id])] record.equipment_maintenance_standards_ids = [
(6, 0, [record.eq_maintenance_id.id, record.overhaul_id.id])]
break break
if record.eq_maintenance_id: if record.eq_maintenance_id:
record.equipment_maintenance_standards_ids = [(6, 0, [record.eq_maintenance_id.id])] record.equipment_maintenance_standards_ids = [(6, 0, [record.eq_maintenance_id.id])]
@@ -56,12 +63,10 @@ class SfMaintenanceEquipment(models.Model):
else: else:
record.equipment_maintenance_standards_ids = False record.equipment_maintenance_standards_ids = False
MTcode = fields.Char("编码", default=get_no) MTcode = fields.Char("编码", default=get_no)
created_user = fields.Many2one('res.users', string='创建人', default=lambda self: self.env.user) created_user = fields.Many2one('res.users', string='创建人', default=lambda self: self.env.user)
equipment_type = fields.Selection([('机床', '机床')], related='category_id.equipment_type') equipment_type = fields.Selection([('机床', '机床')], related='category_id.equipment_type')
code = fields.Char('行业编码') code = fields.Char('机台号')
name = fields.Char('名称') name = fields.Char('名称')
knife_type = fields.Selection( knife_type = fields.Selection(
[("BT40", "BT40"), ("BT30", "BT30")], [("BT40", "BT40"), ("BT30", "BT30")],
@@ -139,7 +144,16 @@ class SfMaintenanceEquipment(models.Model):
control_system_id = fields.Many2one('sf.machine.control_system', control_system_id = fields.Many2one('sf.machine.control_system',
string="控制系统") string="控制系统")
active = fields.Boolean('有效', default=True) active = fields.Boolean('有效', default=True)
code = fields.Char('编码')
def name_get(self):
result = []
for parameter in self:
if parameter.code:
name = parameter.name + '-' + parameter.code
else:
name = parameter.name
result.append((parameter.id, name))
return result
@api.constrains('rotate_speed') @api.constrains('rotate_speed')
def _check_rotate_speed(self): def _check_rotate_speed(self):
@@ -279,7 +293,6 @@ class SfMaintenanceEquipment(models.Model):
'tool_diameter_max': item.tool_diameter_max, 'tool_diameter_max': item.tool_diameter_max,
'machine_tool_category': item.machine_tool_category.code, 'machine_tool_category': item.machine_tool_category.code,
} }
machine_tool_list.append(val) machine_tool_list.append(val)
# kw = machine_tool_list # kw = machine_tool_list
@@ -293,4 +306,168 @@ class SfMaintenanceEquipment(models.Model):
else: else:
raise UserError("没有注册机床信息") raise UserError("没有注册机床信息")
# 修改原生方法,生成维保日期
@api.depends('effective_date', 'period', 'maintenance_ids.request_date', 'maintenance_ids.close_date',
'overhaul_period')
def _compute_next_maintenance(self):
date_now = fields.Date.context_today(self)
equipments = self.filtered(lambda x: x.period > 0)
if equipments:
for equipment in equipments:
next_maintenance_todo = self.env['maintenance.request'].search([
('equipment_id', '=', equipment.id),
('sf_maintenance_type', '=', '保养'),
('stage_id.done', '!=', True),
('close_date', '=', False)], order="request_date asc", limit=1)
last_maintenance_done = self.env['maintenance.request'].search([
('equipment_id', '=', equipment.id),
('sf_maintenance_type', '=', '保养'),
('stage_id.done', '=', True),
('close_date', '!=', False)], order="close_date desc", limit=1)
if next_maintenance_todo and last_maintenance_done:
next_date = next_maintenance_todo.request_date
date_gap = next_maintenance_todo.request_date - last_maintenance_done.close_date
# If the gap between the last_maintenance_done and the next_maintenance_todo one is bigger than 2 times the period and next request is in the future
# We use 2 times the period to avoid creation too closed request from a manually one created
if date_gap > timedelta(0) and date_gap > timedelta(
days=equipment.period) * 2 and next_maintenance_todo.request_date > date_now:
# If the new date still in the past, we set it for today
if last_maintenance_done.close_date + timedelta(days=equipment.period) < date_now:
next_date = date_now
else:
next_date = last_maintenance_done.close_date + timedelta(days=equipment.period)
elif next_maintenance_todo:
next_date = next_maintenance_todo.request_date
date_gap = next_maintenance_todo.request_date - date_now
# If next maintenance to do is in the future, and in more than 2 times the period, we insert an new request
# We use 2 times the period to avoid creation too closed request from a manually one created
if date_gap > timedelta(0) and date_gap > timedelta(days=equipment.period) * 2:
next_date = date_now + timedelta(days=equipment.period)
elif last_maintenance_done:
next_date = last_maintenance_done.close_date + timedelta(days=equipment.period)
# If when we add the period to the last maintenance done and we still in past, we plan it for today
if next_date < date_now:
next_date = date_now
else:
next_date = equipment.effective_date + timedelta(days=equipment.period)
equipment.next_action_date = next_date
else:
self.next_action_date = False
overhaul_equipments = self.filtered(lambda x: x.overhaul_period > 0)
if overhaul_equipments:
for equipment in overhaul_equipments:
next_maintenance_todo = self.env['maintenance.request'].search([
('equipment_id', '=', equipment.id),
('sf_maintenance_type', '=', '检修'),
('stage_id.done', '!=', True),
('close_date', '=', False)], order="request_date asc", limit=1)
last_maintenance_done = self.env['maintenance.request'].search([
('equipment_id', '=', equipment.id),
('sf_maintenance_type', '=', '检修'),
('stage_id.done', '=', True),
('close_date', '!=', False)], order="close_date desc", limit=1)
if next_maintenance_todo and last_maintenance_done:
next_date = next_maintenance_todo.request_date
date_gap = next_maintenance_todo.request_date - last_maintenance_done.close_date
# If the gap between the last_maintenance_done and the next_maintenance_todo one is bigger than 2 times the period and next request is in the future
# We use 2 times the period to avoid creation too closed request from a manually one created
if date_gap > timedelta(0) and date_gap > timedelta(
days=equipment.overhaul_period) * 2 and next_maintenance_todo.request_date > date_now:
# If the new date still in the past, we set it for today
if last_maintenance_done.close_date + timedelta(days=equipment.overhaul_period) < date_now:
next_date = date_now
else:
next_date = last_maintenance_done.close_date + timedelta(days=equipment.overhaul_period)
elif next_maintenance_todo:
next_date = next_maintenance_todo.request_date
date_gap = next_maintenance_todo.request_date - date_now
# If next maintenance to do is in the future, and in more than 2 times the period, we insert an new request
# We use 2 times the period to avoid creation too closed request from a manually one created
if date_gap > timedelta(0) and date_gap > timedelta(days=equipment.overhaul_period) * 2:
next_date = date_now + timedelta(days=equipment.overhaul_period)
elif last_maintenance_done:
next_date = last_maintenance_done.close_date + timedelta(days=equipment.overhaul_period)
# If when we add the period to the last maintenance done and we still in past, we plan it for today
if next_date < date_now:
next_date = date_now
else:
next_date = equipment.effective_date + timedelta(days=equipment.overhaul_period)
equipment.overhaul_date = next_date
else:
self.overhaul_date = False
# 拼接维保请求字符串
def _prepare_maintenance_request_vals(self, date):
self.ensure_one()
return {
'name': _('Preventive Maintenance - %s', self.name),
'request_date': date,
'schedule_date': date,
'category_id': self.category_id.id,
'equipment_id': self.id,
'maintenance_type': 'preventive',
'owner_user_id': self.owner_user_id.id,
'user_id': self.technician_user_id.id,
'maintenance_team_id': self.maintenance_team_id.id,
'duration': self.maintenance_duration,
'company_id': self.company_id.id or self.env.company.id,
'equipment_maintenance_id': self.eq_maintenance_id.id,
'sf_maintenance_type': '保养'
}
# 拼接维保请求字符串
def _prepare_maintenance_request_vals1(self, date):
self.ensure_one()
return {
'name': _('Preventive Maintenance - %s', self.name),
'request_date': date,
'schedule_date': date,
'category_id': self.category_id.id,
'equipment_id': self.id,
'maintenance_type': 'preventive',
'owner_user_id': self.owner_user_id.id,
'user_id': self.technician_user_id.id,
'maintenance_team_id': self.maintenance_team_id.id,
'duration': self.overhaul_duration,
'company_id': self.company_id.id or self.env.company.id,
'equipment_maintenance_id': self.overhaul_id.id,
'sf_maintenance_type': '检修'
}
# 创建维保请求
def _create_new_request(self, date):
self.ensure_one()
vals = self._prepare_maintenance_request_vals(date)
maintenance_requests = self.env['maintenance.request'].create(vals)
return maintenance_requests
def _create_new_request1(self, date):
self.ensure_one()
vals = self._prepare_maintenance_request_vals1(date)
maintenance_requests = self.env['maintenance.request'].create(vals)
return maintenance_requests
# 生成维保请求定时器
@api.model
def _cron_generate_requests(self):
"""
Generates maintenance request on the next_action_date or today if none exists
"""
for equipment in self.search([('period', '>', 0)]):
next_requests = self.env['maintenance.request'].search([('stage_id.done', '=', False),
('equipment_id', '=', equipment.id),
('maintenance_type', '=', 'preventive'),
('request_date', '=', equipment.next_action_date),
('sf_maintenance_type', '=', '保养')])
if not next_requests:
equipment._create_new_request(equipment.next_action_date)
for equipment in self.search([('overhaul_period', '>', 0)]):
next_requests = self.env['maintenance.request'].search([('stage_id.done', '=', False),
('equipment_id', '=', equipment.id),
('maintenance_type', '=', 'preventive'),
('request_date', '=', equipment.overhaul_date),
('sf_maintenance_type', '=', '检修')])
if not next_requests:
equipment._create_new_request1(equipment.overhaul_date)

View File

@@ -26,8 +26,8 @@ class SfMaintenanceEquipmentCategory(models.Model):
record.equipment_maintenance_id = False record.equipment_maintenance_id = False
maintenance_projects = fields.Char(string='维保项目', related='equipment_maintenance_id.maintenance_projects')
maintenance_standards = fields.Char(string='维保标准', related='equipment_maintenance_id.maintenance_standards') maintenance_standards = fields.One2many('maintenance.standards','maintenance_request_id', string='维保标准', related='equipment_maintenance_id.maintenance_standards_ids')
@api.constrains('equipment_maintenance_id') @api.constrains('equipment_maintenance_id')
def _check_equipment_maintenance_id(self): def _check_equipment_maintenance_id(self):
@@ -35,6 +35,12 @@ class SfMaintenanceEquipmentCategory(models.Model):
if not record.equipment_maintenance_id: if not record.equipment_maintenance_id:
raise UserError(_("设备维保标准不能为空,请选择后再保存")) raise UserError(_("设备维保标准不能为空,请选择后再保存"))
def confirm_maintenance(self):
self.write({'stage_id': 2})
def confirm_maintenance_done(self):
self.write({'stage_id': 3})

View File

@@ -2,5 +2,6 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_equipment_maintenance_standards,equipment_maintenance_standards,model_equipment_maintenance_standards,base.group_user,1,1,1,1 access_equipment_maintenance_standards,equipment_maintenance_standards,model_equipment_maintenance_standards,base.group_user,1,1,1,1
access_sf_maintenance_logs,sf_maintenance_logs,model_sf_maintenance_logs,base.group_user,1,1,1,1 access_sf_maintenance_logs,sf_maintenance_logs,model_sf_maintenance_logs,base.group_user,1,1,1,1
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
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_equipment_maintenance_standards equipment_maintenance_standards model_equipment_maintenance_standards base.group_user 1 1 1 1
3 access_sf_maintenance_logs sf_maintenance_logs model_sf_maintenance_logs base.group_user 1 1 1 1
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
7

View File

@@ -2,31 +2,42 @@
<odoo> <odoo>
<record id="view_equipment_maintenance_standards_form" model="ir.ui.view"> <record id="view_equipment_maintenance_standards_form" model="ir.ui.view">
<field name="name">equipment.maintenance.standards.form</field> <field name="name">equipment.maintenance.standards.form</field>
<field name="model">equipment.maintenance.standards</field> <field name="model">equipment.maintenance.standards</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="设备维保标准"> <form string="设备维保标准">
<sheet> <sheet>
<group> <group>
<field name="code" readonly="1" force_save="1"/> <field name="code" readonly="1" force_save="1"/>
<field name="maintenance_type" required="1"/> <field name="maintenance_type" required="1"/>
<field name="name" required="1"/> <field name="name" required="1"/>
<field name="created_user_id"/> <field name="eq_maintenance_ids" invisible='1'/>
<field name="maintenance_equipment_category_id" required="1"/> <field name="overhaul_ids" invisible='1'/>
<field name="maintenance_equipment_ids" widget="many2many_tags"/>
<field name="maintenance_projects" required="1"/>
<field name="maintenance_standards" required="1"/>
<field name="eq_maintenance_ids"/>
<field name="overhaul_ids" />
</group>
</sheet>
</form>
</field>
</record>
<record id="view_equipment_maintenance_standards_tree" model="ir.ui.view"> </group>
<group>
<field name="created_user_id"/>
<field name="maintenance_equipment_category_id" required="1"/>
<field name="maintenance_equipment_ids" widget="many2many_tags"/>
</group>
<notebook>
<page string="维保项目">
<field name="maintenance_standards_ids" widget="ony2many">
<tree editable="top" create="true" string="维保项目">
<field name="name"/>
<field name="maintenance_standards"/>
</tree>
</field>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record id="view_equipment_maintenance_standards_tree" model="ir.ui.view">
<field name="name">equipment.maintenance.standards.tree</field> <field name="name">equipment.maintenance.standards.tree</field>
<field name="model">equipment.maintenance.standards</field> <field name="model">equipment.maintenance.standards</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
@@ -36,9 +47,7 @@
<field name="name" required="1"/> <field name="name" required="1"/>
<field name="maintenance_equipment_category_id" required="1"/> <field name="maintenance_equipment_category_id" required="1"/>
<field name="maintenance_equipment_ids"/> <field name="maintenance_equipment_ids"/>
<field name="maintenance_projects" required="1"/> <field name="created_user_id"/>
<field name="maintenance_standards" required="1"/>
<field name="created_user_id"/>
<field name="create_date" string="创建时间"/> <field name="create_date" string="创建时间"/>
</tree> </tree>
@@ -50,7 +59,7 @@
<field name="model">equipment.maintenance.standards</field> <field name="model">equipment.maintenance.standards</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search> <search>
<searchpanel> <searchpanel>
<field name="maintenance_type" icon="fa-building" enable_counters="1"/> <field name="maintenance_type" icon="fa-building" enable_counters="1"/>
</searchpanel> </searchpanel>
<field name="code" string="编码"/> <field name="code" string="编码"/>
@@ -58,14 +67,11 @@
<field name="name" string="日常机床保养"/> <field name="name" string="日常机床保养"/>
<field name="created_user_id" string="创建人"/> <field name="created_user_id" string="创建人"/>
<field name="maintenance_equipment_category_id" string="设备类别"/> <field name="maintenance_equipment_category_id" string="设备类别"/>
<field name="maintenance_projects" string="维保项目"/>
<field name="maintenance_standards" string="维保标准"/>
</search> </search>
</field> </field>
</record> </record>
<record id="action_equipment_maintenance_standards" model="ir.actions.act_window"> <record id="action_equipment_maintenance_standards" 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>
@@ -79,12 +85,12 @@
</field> </field>
</record> </record>
<menuitem <menuitem
id="menu_equipment_maintenance_standards" id="menu_equipment_maintenance_standards"
name="设备维保标准" name="设备维保标准"
parent="maintenance.menu_maintenance_configuration" parent="maintenance.menu_maintenance_configuration"
action="action_equipment_maintenance_standards" action="action_equipment_maintenance_standards"
sequence="4"/> sequence="4"/>
</odoo> </odoo>

View File

@@ -7,6 +7,10 @@
<field name="model">maintenance.request</field> <field name="model">maintenance.request</field>
<field name="inherit_id" ref="maintenance.hr_equipment_request_view_form"/> <field name="inherit_id" ref="maintenance.hr_equipment_request_view_form"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//button[@name='archive_equipment_request']" position="before">
<button name="confirm_maintenance" string="确认维保计划" type="object" class="btn-primary" attrs="{'invisible': [('stage_id', '!=', 1)]}" />
<button name="confirm_maintenance_done" string="标记已完成" type="object" class="btn-primary" attrs="{'invisible': [('stage_id', '!=', 2)]}" />
</xpath>
<xpath expr="//field[@name='maintenance_type']" position="replace"> <xpath expr="//field[@name='maintenance_type']" position="replace">
<field name="sf_maintenance_type" widget="radio"/> <field name="sf_maintenance_type" widget="radio"/>
<field name="equipment_maintenance_id"/> <field name="equipment_maintenance_id"/>
@@ -17,8 +21,12 @@
<notebook> <notebook>
<page string="维保标准" attrs="{'invisible': [('equipment_maintenance_id', '=', False)]}"> <page string="维保标准" attrs="{'invisible': [('equipment_maintenance_id', '=', False)]}">
<group> <group>
<field name="maintenance_projects"/> <field name="maintenance_standards" widget="ony2many">
<field name="maintenance_standards"/> <tree create="False" string="维保项目">
<field name="name"/>
<field name="maintenance_standards"/>
</tree>
</field>
</group> </group>
</page> </page>

View File

@@ -16,7 +16,7 @@
'security/group_security.xml', 'security/group_security.xml',
'security/ir.model.access.csv', 'security/ir.model.access.csv',
'report/tray_report.xml', 'report/tray_report.xml',
'views/mrp_maintenance_views.xml', # 'views/mrp_maintenance_views.xml',
'views/mrp_routing_workcenter_view.xml', 'views/mrp_routing_workcenter_view.xml',
'views/mrp_workcenter_views.xml', 'views/mrp_workcenter_views.xml',
'views/mrp_workorder_view.xml', 'views/mrp_workorder_view.xml',

View File

@@ -11,6 +11,8 @@ class MrpProduction(models.Model):
maintenance_count = fields.Integer(compute='_compute_maintenance_count', string="Number of maintenance requests") maintenance_count = fields.Integer(compute='_compute_maintenance_count', string="Number of maintenance requests")
request_ids = fields.One2many('maintenance.request', 'production_id') request_ids = fields.One2many('maintenance.request', 'production_id')
model_file = fields.Binary('模型文件', related='product_id.model_file') model_file = fields.Binary('模型文件', related='product_id.model_file')
schedule_state = fields.Selection([('未排', '未排'), ('已排', '已排')],
string='排程状态', default='未排')
@api.depends('request_ids') @api.depends('request_ids')
def _compute_maintenance_count(self): def _compute_maintenance_count(self):
@@ -336,7 +338,7 @@ class MrpProduction(models.Model):
current_sequence += 1 current_sequence += 1
if work.name == '获取CNC加工程序': if work.name == '获取CNC加工程序':
work.button_start() work.button_start()
work.fetchCNC() #work.fetchCNC()
# 创建工单并进行排序 # 创建工单并进行排序
def _create_workorder(self): def _create_workorder(self):

View File

@@ -28,7 +28,7 @@ class ResMrpWorkOrder(models.Model):
store=True, check_company=True, string="材料") store=True, check_company=True, string="材料")
product_tmpl_id_materials_type_id = fields.Many2one(related='production_id.product_tmpl_id.materials_type_id', product_tmpl_id_materials_type_id = fields.Many2one(related='production_id.product_tmpl_id.materials_type_id',
readonly=True, store=True, check_company=True, string="型号") readonly=True, store=True, check_company=True, string="型号")
workcenter_id = fields.Many2one('mrp.workcenter', required=False) workcenter_id = fields.Many2one('mrp.workcenter', string='工作中心', required=False)
users_ids = fields.Many2many("res.users", 'users_workorder', related="workcenter_id.users_ids") users_ids = fields.Many2many("res.users", 'users_workorder', related="workcenter_id.users_ids")
processing_panel = fields.Char('加工面') processing_panel = fields.Char('加工面')
sequence = fields.Integer(string='工序') sequence = fields.Integer(string='工序')
@@ -106,6 +106,8 @@ class ResMrpWorkOrder(models.Model):
picking_in_id = fields.Many2one('stock.picking', string='外协入库单') picking_in_id = fields.Many2one('stock.picking', string='外协入库单')
picking_out_id = fields.Many2one('stock.picking', string='外协出库单') picking_out_id = fields.Many2one('stock.picking', string='外协出库单')
supplier_id = fields.Many2one('res.partner', string='外协供应商') supplier_id = fields.Many2one('res.partner', string='外协供应商')
equipment_id = fields.Many2one('maintenance.equipment', string='加工设备')
schedule_state = fields.Selection(related='production_id.schedule_state', store=True)
def get_no_data(self, production_id): def get_no_data(self, production_id):
process_parameter_workorder = self.search( process_parameter_workorder = self.search(
@@ -165,7 +167,7 @@ class ResMrpWorkOrder(models.Model):
'operation_id': False, 'operation_id': False,
'name': route.route_workcenter_id.name, 'name': route.route_workcenter_id.name,
'processing_panel': k, 'processing_panel': k,
'quality_point_ids':route.route_workcenter_id.quality_point_ids, 'quality_point_ids': route.route_workcenter_id.quality_point_ids,
'routing_type': route.routing_type, 'routing_type': route.routing_type,
'work_state': '' if not route.routing_type == '获取CNC加工程序' else '待发起', 'work_state': '' if not route.routing_type == '获取CNC加工程序' else '待发起',
'workcenter_id': self.env['mrp.routing.workcenter'].get_workcenter(route.workcenter_ids.ids, 'workcenter_id': self.env['mrp.routing.workcenter'].get_workcenter(route.workcenter_ids.ids,

View File

@@ -231,18 +231,8 @@ class ProductionLot(models.Model):
1] 1]
now = datetime.now().strftime("%Y-%m-%d") now = datetime.now().strftime("%Y-%m-%d")
# formatted_date = now.strftime("%Y-%m-%d") # formatted_date = now.strftime("%Y-%m-%d")
if product.integral_cutting_tool_type_id: if product.cutting_tool_model_id:
return "%s-%s-%03d" % (product.integral_cutting_tool_type_id.code, now, 1) return "%s-%s-%03d" % (product.cutting_tool_model_id.code, now, 1)
if product.blade_type_id:
return "%s-%s-%03d" % (product.blade_type_id.code, now, 1)
if product.cutter_bar_type_id:
return "%s-%s-%03d" % (product.cutter_bar_type_id.code, now, 1)
if product.cutter_pad_type_id:
return "%s-%s-%03d" % (product.cutter_pad_type_id.code, now, 1)
if product.handle_type_id:
return "%s-%s-%03d" % (product.handle_type_id.code, now, 1)
if product.chuck_type_id:
return "%s-%s-%03d" % (product.chuck_type_id.code, now, 1)
return "%s-%03d" % (product.name, 1) return "%s-%03d" % (product.name, 1)

View File

@@ -7,9 +7,11 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<field name="name" position="replace"> <field name="name" position="replace">
<field name="is_subcontract" invisible="1"/> <field name="is_subcontract" invisible="1"/>
<field name="name" decoration-success="is_subcontract" decoration-bf="is_subcontract"/> <field name="name" decoration-success="is_subcontract" decoration-bf="is_subcontract"/>
</field> </field>
<field name="name" position="before"> <field name="name" position="before">
<field name="schedule_state"/>
<field name="sequence"/> <field name="sequence"/>
<field name='user_permissions' invisible="1"/> <field name='user_permissions' invisible="1"/>
</field> </field>
@@ -19,6 +21,9 @@
<field name="state" position="after"> <field name="state" position="after">
<field name="work_state" optional="hide"/> <field name="work_state" optional="hide"/>
</field> </field>
<field name="product_id" position="after">
<field name="equipment_id" optional="hide"/>
</field>
<xpath expr="//field[@name='date_planned_start']" position="replace"> <xpath expr="//field[@name='date_planned_start']" position="replace">
<field name="date_planned_start" string="计划开始日期" optional="show"/> <field name="date_planned_start" string="计划开始日期" optional="show"/>
</xpath> </xpath>
@@ -73,7 +78,7 @@
(0, 0, {'view_mode': 'kanban', 'view_id': ref('mrp.workcenter_line_kanban')}) ]"/> (0, 0, {'view_mode': 'kanban', 'view_id': ref('mrp.workcenter_line_kanban')}) ]"/>
<!-- <field name="target">fullscreen</field>--> <!-- <field name="target">fullscreen</field>-->
<field name="target">current</field> <field name="target">current</field>
<field name="domain">[('state', '!=', 'cancel')]</field> <field name="domain">[('state', '!=', 'cancel'),('schedule_state', '=', '已排')]</field>
<field name="context">{'search_default_workcenter_id': active_id}</field> <field name="context">{'search_default_workcenter_id': active_id}</field>
<field name="help" type="html"> <field name="help" type="html">
<p class="o_view_nocontent_workorder"> <p class="o_view_nocontent_workorder">
@@ -91,6 +96,28 @@
</field> </field>
</record> </record>
<record model="ir.actions.act_window" id="mrp_workorder_action_scheduled">
<field name="name">工单</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">mrp.workorder</field>
<field name="view_mode">tree,kanban,form</field>
<field name="view_id" ref="view_mrp_production_workorder_tree_editable_inherit_sf"/>
<!-- <field name="view_ids" eval="[(5, 0, 0),-->
<!-- (0, 0, {'view_mode': 'tree', 'view_id': ref('mrp.mrp_production_workorder_tree_view')}),-->
<!-- (0, 0, {'view_mode': 'kanban', 'view_id': ref('mrp.workcenter_line_kanban')}) ]"/>-->
<!-- <field name="target">fullscreen</field>-->
<!-- <field name="search_view_id" ref="mrp.view_mrp_production_workorder_form_view_filter"/>-->
<!-- <field name="domain">[('state', '!=', 'cancel'),('schedule_state', '=', '已排')]</field>-->
<!-- <field name="context">{'search_default_workcenter_id': active_id}</field>-->
<field name="help" type="html">
<p class="o_view_nocontent_workorder">
没有已排程的工单!
</p>
</field>
</record>
<!-- <record model="ir.ui.view" id="view_mrp_production_workorder_form_inherit_sf">--> <!-- <record model="ir.ui.view" id="view_mrp_production_workorder_form_inherit_sf">-->
<!-- <field name="name">mrp.production.workorder.form.inherit.sf</field>--> <!-- <field name="name">mrp.production.workorder.form.inherit.sf</field>-->
<!-- <field name="model">mrp.workorder</field>--> <!-- <field name="model">mrp.workorder</field>-->
@@ -126,9 +153,9 @@
attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '!=', 'blocked'),('name','=','获取CNC加工程序')]}"/> attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '!=', 'blocked'),('name','=','获取CNC加工程序')]}"/>
</xpath> </xpath>
<!-- 隐藏物料清单--> <!-- 隐藏物料清单-->
<!-- <xpath expr="//page[@name='components']" position="attributes">--> <!-- <xpath expr="//page[@name='components']" position="attributes">-->
<!-- <attribute name="invisible">1</attribute>--> <!-- <attribute name="invisible">1</attribute>-->
<!-- </xpath>--> <!-- </xpath>-->
<!-- 隐藏物料清单--> <!-- 隐藏物料清单-->
<field name="production_id" position="after" invisible="0"> <field name="production_id" position="after" invisible="0">
@@ -141,6 +168,9 @@
sum="real duration"/> sum="real duration"/>
<field name="processing_panel" readonly="1" <field name="processing_panel" readonly="1"
attrs='{"invisible": [("routing_type","in",("获取CNC加工程序","切割"))]}'/> attrs='{"invisible": [("routing_type","in",("获取CNC加工程序","切割"))]}'/>
<field name="equipment_id"
attrs='{"invisible": [("routing_type","in",("获取CNC加工程序","切割"))]}'/>
</group> </group>
<group attrs='{"invisible": [("routing_type","=","获取CNC加工程序")]}'> <group attrs='{"invisible": [("routing_type","=","获取CNC加工程序")]}'>
<div> <div>
@@ -165,7 +195,7 @@
<group> <group>
<div class="col-12 col-lg-6 o_setting_box" style="white-space: nowrap"> <div class="col-12 col-lg-6 o_setting_box" style="white-space: nowrap">
<button type="object" class="oe_highlight" name="fetchCNC" string="获取CNC程序代码" <button type="object" class="oe_highlight" name="fetchCNC" string="获取CNC程序代码"
/> />
</div> </div>
</group> </group>

View File

@@ -787,6 +787,10 @@ class MachineToolType(models.Model):
result = json.loads(r['result']) result = json.loads(r['result'])
if result['status'] == 1: if result['status'] == 1:
for item in result['machine_tool_type_all_list']: for item in result['machine_tool_type_all_list']:
if item.get('machine_tool_picture'):
image = base64.b64decode(item['machine_tool_picture'])
else:
image = ''
brand = self.env['sf.machine_tool.type'].search( brand = self.env['sf.machine_tool.type'].search(
[("code", '=', item['code'])]) [("code", '=', item['code'])])
if not brand: if not brand:
@@ -811,7 +815,7 @@ class MachineToolType(models.Model):
[('code', '=', item['control_system_id'])]).id, [('code', '=', item['control_system_id'])]).id,
"active": item['active'], "active": item['active'],
'brand_id': self.env['sf.machine.brand'].search([('code', '=', item['brand_id'])]).id, 'brand_id': self.env['sf.machine.brand'].search([('code', '=', item['brand_id'])]).id,
'machine_tool_picture': base64.b64decode(item['machine_tool_picture']), 'machine_tool_picture':image,
"heightened_way": item['heightened_way'], "heightened_way": item['heightened_way'],
"workpiece_load": item['workpiece_load'], "workpiece_load": item['workpiece_load'],
"lead_screw": item['lead_screw'], "lead_screw": item['lead_screw'],

View File

@@ -0,0 +1 @@
from . import models

View File

@@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': '机企猫智能工厂 计划管理',
'version': '1.0',
'summary': '智能工厂计划管理',
'sequence': 1,
'description': """
在本模块,定义了计划管理的清单和原型
""",
'category': 'sf',
'website': 'https://www.sf.jikimo.com',
'depends': [],
'data': [
'security/ir.model.access.csv',
'views/paln_base_view.xml',
'views/menu_view.xml'
],
'demo': [
],
'assets': {
'web.assets_qweb': [
],
'web.assets_backend':[
]
},
'license': 'LGPL-3',
'installable': True,
'application': False,
'auto_install': False,
}

View File

@@ -0,0 +1,2 @@
from . import calendar_base
from . import base

View File

@@ -0,0 +1,43 @@
from odoo import models, fields
class ProductionLine(models.Model):
_name = 'sf.production.line'
_description = '生产线'
name = fields.Char(string='生产线名称')
class WorkingProcedure(models.Model):
_name = 'sf.working.procedure'
_description = '工序'
name = fields.Char(string='工序名称')
content = fields.Char(string='主要加工内容')
WorkingProcedure_to_ProductionLine_id = fields.Many2one('sf.production.line')
class ProcedureEquipmentResourceSetting(models.Model):
_name = 'sf.procedure.equipment.resource.setting'
_description = '工序设备资源设置'
equipment_to_working_procedure_id = fields.Many2one('sf.working.procedure', string='工序')
name = fields.Char(string='设备名称')
machine_tool_name = fields.Char(string='机台号')
brand = fields.Char(string='品牌')
model = fields.Char(string='型号')
production_capacity = fields.Char(string='产能')
working_calendar = fields.Many2one('sf.work.log.setting', string='工作日历')
working_shift = fields.Char(string='班次')
create_time = fields.Datetime(string='新增时间', default=lambda self: fields.Datetime.now())
stale_dated_time = fields.Datetime(string='过期时间')
status = fields.Selection([('0', '正常'), ('1', '故障停机'), ('2', '计划停机')], string='设备状态', default='0')
participate_in_scheduling = fields.Boolean(string='参与排程', default=True)

View File

@@ -0,0 +1,50 @@
from odoo import models, fields, api
import re
class WorkLogSetting(models.Model):
_name = 'sf.work.log.setting'
_description = '工作日历设置'
name = fields.Char(string='工作日历名称')
# start_time = fields.Char(string='日开始时间')
start_time = fields.Datetime(string='日开始时间')
end_time = fields.Char(string='日结束时间')
duration = fields.Char(string='时长')
day_off = fields.Char(string='休息日')
user_defined_working_shift_status = fields.Boolean(string='自定义班次', default=False)
working_shift = fields.Char(string='班次')
working_shift_char = fields.Char(string='班次')
working_shift_select = fields.Selection([('0', '早班00:00-08:00'),
('1', '白班08:00-16:00'),
('2', '晚班16:00-24:00'),
('3', '长白班08:00-20:00'),
('4', '长晚班20:00-08:00')], string='班次')
status = fields.Boolean(string='状态', default=True)
update_person = fields.Char(string='更新人', default=lambda self: self.env.user.name)
update_time = fields.Datetime(string='更新时间', default=lambda self: fields.Datetime.now())
@api.onchange('working_shift_char', 'working_shift_select')
def _onchange_working_shift(self):
for record in self:
if record.working_shift_select:
record.working_shift = record.working_shift_select
else:
record.working_shift = record.working_shift_char
# @api.onchange('start_time')
# def _onchange_start_time(self):
# pattern = re.compile(r'^(([0-9]|1[0-9]|2[0-3]):[0-5][0-9])|24:00$')
# if self.start_time and not pattern.match(self.start_time):
# raise models.ValidationError('输入的日开始时间不正确,请重新输入!')
@api.onchange('end_time')
def _onchange_end_time(self):
pattern = re.compile(r'^(([0-9]|1[0-9]|2[0-3]):[0-5][0-9])|24:00$')
for record in self:
if record.end_time and not pattern.match(record.end_time):
raise models.ValidationError('输入的日结束时间不正确,请重新输入!')

View File

@@ -0,0 +1,11 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_sf_work_log_setting,sf.work.log.setting,model_sf_work_log_setting,base.group_user,1,1,1,1
access_sf_production_line,sf.production.line,model_sf_production_line,base.group_user,1,1,1,1
access_sf_working_procedure,sf.working.procedure,model_sf_working_procedure,base.group_user,1,1,1,1
access_sf_procedure_equipment_resource_setting,sf.procedure.equipment.resource.setting,model_sf_procedure_equipment_resource_setting,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_sf_work_log_setting sf.work.log.setting model_sf_work_log_setting base.group_user 1 1 1 1
3 access_sf_production_line sf.production.line model_sf_production_line base.group_user 1 1 1 1
4 access_sf_working_procedure sf.working.procedure model_sf_working_procedure base.group_user 1 1 1 1
5 access_sf_procedure_equipment_resource_setting sf.procedure.equipment.resource.setting model_sf_procedure_equipment_resource_setting base.group_user 1 1 1 1

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<menuitem id="menu_sf_plan_manage"
name="计划管理"
parent="mrp.menu_mrp_root"
sequence="22"
/>
<menuitem id="menu_sf_basic_setting"
name="基础设置"
parent="menu_sf_plan_manage"
sequence="0"
/>
<menuitem id="menu_sf_work_log_setting"
name="工作日历设置"
parent="menu_sf_basic_setting"
action="sf_work_log_setting_act"
sequence="0"
/>
<menuitem id="menu_sf_procedure_equipment_resource_setting"
name="工序设备资源设置"
parent="menu_sf_basic_setting"
action="sf_procedure_equipment_resource_setting_act"
sequence="10"
/>
</odoo>

View File

@@ -0,0 +1,103 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!--========================================工作日历设置========================================-->
<record id="sf_work_log_setting_tree" model="ir.ui.view">
<field name="name">工作日历设置</field>
<field name="model">sf.work.log.setting</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="start_time"/>
<field name="end_time"/>
<field name="duration"/>
<field name="day_off"/>
<field name="working_shift"/>
<field name="status"/>
<field name="update_person"/>
<field name="update_time"/>
</tree>
</field>
</record>
<record id="sf_work_log_setting_form" model="ir.ui.view">
<field name="name">工作日历设置</field>
<field name="model">sf.work.log.setting</field>
<field name="arch" type="xml">
<form>
<sheet string-="工作日历设置">
<group string="基础信息">
<field name="name"/>
</group>
<group string="选择班次">
<group>
<field name="user_defined_working_shift_status"/>
<field name="working_shift" invisible="True"/>
</group>
<group>
<field name="working_shift_char" attrs="{'invisible': [('user_defined_working_shift_status', '=', False)]}"/>
<field name="working_shift_select" attrs="{'invisible': [('user_defined_working_shift_status', '!=', False)]}"/>
</group>
</group>
<group string="工作时间">
<group>
<!-- <field name="start_time" widget="char" placeholder="请输入的时间为00:00-24:00"/>-->
<field name="start_time" options="{'no_date': True, 'format': 'HH:mm:ss'}"/>
<field name="duration"/>
</group>
<group>
<field name="end_time" widget="char" placeholder="请输入的时间为00:00-24:00"/>
<field name="day_off"/>
</group>
</group>
<group string="日历状态">
<field name="status"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="sf_work_log_setting_act" model="ir.actions.act_window">
<field name="name">工作日历设置</field>
<field name="res_model">sf.work.log.setting</field>
<field name="view_mode">tree,form</field>
</record>
<!--========================================工序设备资源设置========================================-->
<record id="sf_procedure_equipment_resource_setting_tree" model="ir.ui.view">
<field name="name">工序设备资源设置</field>
<field name="model">sf.procedure.equipment.resource.setting</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="machine_tool_name"/>
<field name="brand"/>
<field name="model"/>
<field name="production_capacity"/>
<field name="working_calendar"/>
<field name="working_shift"/>
<field name="create_time"/>
<field name="stale_dated_time"/>
<field name="status"/>
<field name="participate_in_scheduling"/>
</tree>
</field>
</record>
<!-- <record id="sf_procedure_equipment_resource_setting_form" model="ir.ui.view">-->
<!-- <field name="name">工序设备资源设置</field>-->
<!-- <field name="model">sf.procedure.equipment.resource.setting</field>-->
<!-- <field name="arch" type="xml">-->
<!-- <form>-->
<!-- </form>-->
<!-- </field>-->
<!-- </record>-->
<record id="sf_procedure_equipment_resource_setting_act" model="ir.actions.act_window">
<field name="name">工序设备资源设置</field>
<field name="res_model">sf.procedure.equipment.resource.setting</field>
<field name="view_mode">tree,form</field>
</record>
</odoo>

3
sf_warehouse/__init__.py Normal file
View File

@@ -0,0 +1,3 @@
# -*-coding:utf-8-*-
from . import models

View File

@@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': '机企猫智能工厂 库存管理',
'version': '1.0',
'summary': '智能工厂库存管理',
'sequence': 1,
'description': """
在本模块升级了odoo原生的库存模块
""",
'category': 'sf',
'website': 'https://www.sf.jikimo.com',
'depends': ['stock', ],
'data': [
#'security/group_security.xml',
# 'security/ir.model.access.csv',
'views/view.xml',
],
'demo': [
],
'assets': {
'web.assets_qweb': [
],
'web.assets_backend':[
# 'sf_tool_management/static/src/change.scss'
]
},
'license': 'LGPL-3',
'installable': True,
'application': False,
'auto_install': False,
}

View File

@@ -0,0 +1,2 @@
from . import model

View File

@@ -0,0 +1,178 @@
# -*- coding: utf-8 -*-
from odoo import fields, models, api
from odoo.exceptions import ValidationError, UserError
class SfLocation(models.Model):
_inherit = 'stock.location'
# 重写字段定义
name = fields.Char('Location Name', required=True, size=20)
barcode = fields.Char('Barcode', copy=False, required=True, size=15)
# 仓库类别selection仓库、库区、库位、货位
location_type = fields.Selection([
('仓库', '仓库'),
('库区', '库区'),
('货架', '货架'),
('货位', '货位')
], string='仓库类别')
# 仓库类型(分类:成品库、坯料库、原材料库、刀具库、线边料库、线边刀库)
location_category = fields.Selection([
('成品库', '成品库'),
('坯料库', '坯料库'),
('原材料库', '原材料库'),
('刀具库', '刀具库'),
('线边料库', '线边料库'),
('线边刀库', '线边刀库')
], string='仓库类型')
# 库区类型selection拣货区、存货区、收货区、退货区、次品区
area_type = fields.Selection([
('拣货区', '拣货区'),
('存货区', '存货区'),
('收货区', '收货区'),
('退货区', '退货区'),
('次品区', '次品区')
], string='库区类型')
# 货架独有字段通道、方向、货架高度m、货架层数、层数容量
channel = fields.Char(string='通道', required=True)
direction = fields.Selection([
('R', 'R'),
('L', 'L')
], string='方向', required=True)
shelf_height = fields.Float(string='货架高度(m)')
shelf_layer = fields.Integer(string='货架层数', required=True)
layer_capacity = fields.Integer(string='层数容量', required=True)
# 货位独有字段:货位状态、产品(关联产品对象)、产品序列号(关联产品序列号对象)
location_status = fields.Selection([
('空闲', '空闲'),
('占用', '占用'),
('禁用', '禁用')
], string='货位状态', default='空闲')
# product_id = fields.Many2one('product.template', string='产品')
product_id = fields.Many2one('product.product', string='产品', compute='_compute_product_id', readonly=True)
product_sn_id = fields.Many2one('stock.lot', string='产品序列号')
# 添加SQL约束
_sql_constraints = [
('name_uniq', 'unique(name)', '位置名称必须唯一!'),
]
hide_location_type = fields.Boolean(compute='_compute_hide_what', string='隐藏仓库')
hide_area = fields.Boolean(compute='_compute_hide_what', string='隐藏库区')
hide_shelf = fields.Boolean(compute='_compute_hide_what', string='隐藏货架')
hide_location = fields.Boolean(compute='_compute_hide_what', string='隐藏货位')
# @api.constrains('shelf_height')
# def _check_shelf_height(self):
# for record in self:
# if not (0 <= record.shelf_height < 1000): # 限制字段值在0到999之间
# raise UserError('shelf_height的值必须在0到1000之间')
#
# @api.constrains('shelf_layer')
# def _check_shelf_layer(self):
# for record in self:
# if not (0 < record.shelf_layer < 1000):
# raise UserError('shelf_layer的值必须在0到999之间,且不能为0')
#
# @api.constrains('layer_capacity')
# def _check_layer_capacity(self):
# for record in self:
# if not (0 <= record.layer_capacity < 1000):
# raise UserError('layer_capacity的值必须在0到999之间,且不能为0')
@api.depends('product_sn_id')
def _compute_product_id(self):
for record in self:
if record.product_sn_id:
record.product_id = record.product_sn_id.product_id
record.location_status = '占用'
else:
record.product_id = False
record.location_status = '空闲'
@api.depends('location_type')
def _compute_hide_what(self):
"""
根据仓库类别,隐藏不需要的字段
:return:
"""
for record in self:
record.hide_location_type = False
record.hide_area = False
record.hide_shelf = False
record.hide_location = False
if record.location_type and record.location_type == '仓库':
record.hide_location_type = True
elif record.location_type and record.location_type == '库区':
record.hide_area = True
elif record.location_type and record.location_type == '货架':
record.hide_shelf = True
elif record.location_type and record.location_type == '货位':
record.hide_location = True
else:
pass
# # 添加Python约束
# @api.constrains('name', 'barcode')
# def _check_len(self):
# for rec in self:
# if len(rec.name) > 20:
# raise ValidationError("Location Name length must be less equal than 20!")
# if len(rec.barcode) > 15:
# raise ValidationError("Barcode length must be less equal than 15!")
# @api.model
# def default_get(self, fields):
# print('fields:', fields)
# res = super(SfLocation, self).default_get(fields)
# print('res:', res)
# if 'barcode' in fields and 'barcode' not in res:
# # 这里是你生成barcode的代码
# pass
# # res['barcode'] = self.generate_barcode() # 假设你有一个方法generate_barcode来生成barcode
# return res
# @api.model
# def create(self, vals):
# """
# 重写create方法当仓库类型为货架时自动生成其下面的货位数量为货架层数*层数容量
# """
# res = super(SfLocation, self).create(vals)
# if res.location_type == '货架':
# for i in range(res.shelf_layer):
# for j in range(res.layer_capacity):
# self.create({
# 'name': res.name + '-' + str(i+1) + '-' + str(j+1),
# 'location_id': res.id,
# 'location_type': '货位',
# 'barcode': self.generate_barcode(res, i, j),
# 'location_status': '空闲'
# })
# return res
# 生成货位
def create_location(self):
if self.location_type == '货架':
for i in range(self.shelf_layer):
for j in range(self.layer_capacity):
self.create({
'name': self.name + '-' + str(i + 1) + '' + '-' + str(j + 1) + '位置',
'location_id': self.id,
'location_type': '货位',
'barcode': self.generate_barcode(i, j),
'location_status': '空闲'
})
def generate_barcode(self, i, j):
# 这里是你生成barcode的代码
area_type_barcode = self.location_id.barcode
i_str = str(i + 1).zfill(3) # 确保是两位数如果不足两位左侧补0
j_str = str(j + 1).zfill(3) # 确保是两位数如果不足两位左侧补0
return area_type_barcode + self.channel + self.direction + '-' + self.barcode + '-' + i_str + '-' + j_str
# def generate_barcode(self, i, j):
# # 这里是你生成barcode的代码
# area_type_barcode = self.location_id.barcode
# return area_type_barcode + self.channel + self.direction + '-' + self.barcode + '-' + str(i + 1) + '-' + str(j + 1)

View File

@@ -0,0 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_stock_location,stock.location,model_stock_location,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_stock_location stock.location model_stock_location base.group_user 1 1 1 1

View File

@@ -0,0 +1,11 @@
.modal-content .o_cp_buttons {
display:none
}
.modal-content .o_control_panel {
display:none
}
.modal-content .o_list_button {
}

129
sf_warehouse/views/view.xml Normal file
View File

@@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="view_location_tree2_sf_inherit" model="ir.ui.view">
<field name="name">stock.location.tree.sf.inherit</field>
<field name="model">stock.location</field>
<field name="inherit_id" ref="stock.view_location_tree2"/>
<field name="arch" type="xml">
<xpath expr="//tree/field[@name='complete_name']" position="before">
<field name="barcode"/>
</xpath>
</field>
</record>
<record id="view_location_form_sf_inherit" model="ir.ui.view">
<field name="name">stock.location.form.sf.inherit</field>
<field name="model">stock.location</field>
<field name="inherit_id" ref="stock.view_location_form"/>
<field name="arch" type="xml">
<xpath expr="//form/sheet/group" position="before">
<group string="基本信息">
<group>
<field name="hide_location_type" invisible="1"/>
<field name="hide_area" invisible="1"/>
<field name="hide_shelf" invisible="1"/>
<field name="hide_location" invisible="1"/>
<field name="barcode" string="编码"/>
<field name="location_type"/>
<field name="channel" attrs="{'invisible': [('hide_shelf', '=', False)], 'required': [('hide_shelf', '!=', False)]}"/>
<field name="direction" attrs="{'invisible': [('hide_shelf', '=', False)], 'required': [('hide_shelf', '!=', False)]}"/>
<field name="product_sn_id" attrs="{'invisible': [('hide_location', '=', False)], 'required': [('hide_location', '!=', False)]}"/>
</group>
<group>
<field name="location_category" attrs="{'invisible': [('hide_location_type', '=', False)], 'required': [('hide_location_type', '!=', False)]}"/>
<field name="area_type" attrs="{'invisible': [('hide_area', '=', False)], 'required': [('hide_area', '!=', False)]}"/>
<field name="shelf_height" attrs="{'invisible': [('hide_shelf', '=', False)], 'required': [('hide_shelf', '!=', False)]}"/>
<field name="shelf_layer" attrs="{'invisible': [('hide_shelf', '=', False)], 'required': [('hide_shelf', '!=', False)]}"/>
<field name="layer_capacity" attrs="{'invisible': [('hide_shelf', '=', False)], 'required': [('hide_shelf', '!=', False)]}"/>
<field name="product_id" attrs="{'invisible': [('hide_location', '=', False)], 'required': [('hide_location', '!=', False)]}"/>
<field name="location_status" attrs="{'invisible': [('hide_location', '=', False)], 'required': [('hide_location', '!=', False)]}"/>
</group>
</group>
</xpath>
<!-- <xpath expr="//form/sheet/div/button" position="before"> -->
<!-- <button string="生成货位" name="create_location" type="object" class="oe_highlight" attrs="{'invisible': [('hide_shelf', '=', False)]}"/> -->
<!-- </xpath> -->
<xpath expr="//form/sheet" position="before">
<header>
<button string="生成货位" name="create_location" type="object" class="oe_highlight" attrs="{'invisible': [('hide_shelf', '=', False)]}"/>
</header>
</xpath>
</field>
</record>
<record id="view_location_search_sf_inherit" model="ir.ui.view">
<field name="name">stock.location.search.sf.inherit</field>
<field name="model">stock.location</field>
<field name="inherit_id" ref="stock.view_location_search"/>
<field name="arch" type="xml">
<xpath expr="//search[1]" position="inside">
<searchpanel class="account_root">
<!-- <field name="location_type" icon="fa-filter"/> -->
<field name="location_id" select="multi" domain="[('location_type', '=', '货架')]"/>
</searchpanel>
</xpath>
</field>
</record>
<record id="example_kanban_view" model="ir.ui.view">
<field name="name">example.kanban</field>
<field name="model">stock.location</field>
<field name="arch" type="xml">
<kanban class="o_kanban_mobile">
<templates>
<t t-name="kanban-box">
<div t-attf-class="oe_kanban_card">
<!-- 标题 -->
<div class="o_kanban_card_header">
<div class="o_kanban_card_header_title">
<field name="name"/>
</div>
</div>
<!-- 内容 -->
<div class="o_kanban_record_bottom">
<field name="location_status"/>
</div>
<div class="o_kanban_record_bottom">
<field name="product_sn_id"/>
<span> | </span>
<field name="product_id"/>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
<record id="kanban_action_id" model="ir.actions.act_window">
<field name="name">货位状态</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">stock.location</field>
<field name="view_mode">kanban,form</field>
</record>
<!-- <record id="example_action" model="ir.actions.act_window"> -->
<!-- <field name="name">Example</field> -->
<!-- <field name="type">ir.actions.act_window</field> -->
<!-- <field name="res_model">stock.location</field> -->
<!-- <field name="view_mode">kanban</field> -->
<!-- <field name="searchpanel">true</field> -->
<!-- <field name="searchpanel_field_label">货架</field> -->
<!-- <field name="searchpanel_field_name">parent_id</field> -->
<!-- <field name="searchpanel_field_group_by">['parent_id']</field> -->
<!-- <field name="domain">[('location_type', '=', '货位')]</field> -->
<!-- </record> -->
<menuitem id="menu_stock_location" name="货位状态" parent="stock.menu_stock_root"
sequence="50"
action="kanban_action_id"/>
</data>
</odoo>