Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/销售权限

# Conflicts:
#	sf_manufacturing/models/product_template.py
This commit is contained in:
jinling.yang
2023-11-23 17:39:35 +08:00
54 changed files with 1716 additions and 1623 deletions

View File

@@ -11,7 +11,7 @@ var Dialog = require('web.Dialog');
patch(FormStatusIndicator.prototype, 'jikimo_frontend.FormStatusIndicator', { patch(FormStatusIndicator.prototype, 'jikimo_frontend.FormStatusIndicator', {
// 你可以重写或者添加一些方法和属性 // 你可以重写或者添加一些方法和属性
async _onDiscardChanges() { async _onDiscardChanges() {
var self = this; // var self = this;
Dialog.confirm(this, _t("Are you sure you want to discard changes?"), { Dialog.confirm(this, _t("Are you sure you want to discard changes?"), {
title: _t("Discard Changes"), title: _t("Discard Changes"),
@@ -25,7 +25,8 @@ patch(FormStatusIndicator.prototype, 'jikimo_frontend.FormStatusIndicator', {
// if (window.confirm("Are you sure you want to discard changes?")) { // if (window.confirm("Are you sure you want to discard changes?")) {
// await this.props.discard(); // await this.props.discard();
// } // }
const result = await this._confirmDiscardChange(); // const result = await this._confirmDiscardChange();
await this._confirmDiscardChange();
await this.props.discard(); await this.props.discard();
}, },

View File

@@ -10,7 +10,7 @@ patch(ListRenderer.prototype, 'jikimo_frontend.ListRenderer', {
// The following code manipulates the DOM directly to avoid having to wait for a // The following code manipulates the DOM directly to avoid having to wait for a
// render + patch which would occur on the next frame and cause flickering. // render + patch which would occur on the next frame and cause flickering.
freezeColumnWidths() { freezeColumnWidths() {
console.log('ccccccccccccccccccccccccccc') // console.log('ccccccccccccccccccccccccccc')
if (!this.keepColumnWidths) { if (!this.keepColumnWidths) {
this.columnWidths = null; this.columnWidths = null;
} }

View File

@@ -1 +1 @@
from. import common from . import common

View File

@@ -1,5 +1,43 @@
<odoo> <odoo>
<data> <data>
<record id="group_sf_mrp_user" model="res.groups">
<field name="name">制造普通用户</field>
<field name="category_id" ref="base.module_category_manufacturing_manufacturing"/>
<field name="implied_ids" eval="[(4, ref('mrp.group_mrp_user'))]"/>
</record>
<!-- <record id="group_sf_mrp_manager" model="res.groups">-->
<!-- <field name="name">制造管理用户</field>-->
<!-- <field name="implied_ids" eval="[(4, ref('group_sf_mrp_user'))]"/>-->
<!-- </record>-->
<!-- <record id="group_sf_mrp_manager" model="res.groups">-->
<!-- <field name="name">制造管理用户</field>-->
<!-- <field name="implied_ids" eval="[(4, ref('group_sf_mrp_user'))]"/>-->
<!-- <field name="category_id" ref="base.module_category_manufacturing_manufacturing"/>-->
<!-- </record>-->
<record id="group_sf_equipment_user" model="res.groups">
<field name="name">机床操作岗</field>
<field name="implied_ids" eval="[(4, ref('group_sf_mrp_user'))]"/>
<field name="category_id" ref="base.module_category_manufacturing_manufacturing"/>
</record>
<record id="group_sf_tool_user" model="res.groups">
<field name="name">刀具组装岗</field>
<field name="implied_ids" eval="[(4, ref('group_sf_mrp_user'))]"/>
<field name="category_id" ref="base.module_category_manufacturing_manufacturing"/>
</record>
<record id="group_sf_order_user" model="res.groups">
<field name="name">工件装夹岗</field>
<field name="implied_ids" eval="[(4, ref('group_sf_mrp_user'))]"/>
<field name="category_id" ref="base.module_category_manufacturing_manufacturing"/>
</record>
<record id="group_sf_mrp_manager" model="res.groups">
<field name="name">生产总监</field>
<field name="implied_ids" eval="[(4, ref('group_sf_mrp_user'))]"/>
<field name="category_id" ref="base.module_category_manufacturing_manufacturing"/>
</record>
<record model="ir.module.category" id="module_category_plan"> <record model="ir.module.category" id="module_category_plan">
<field name="name">计划</field> <field name="name">计划</field>
<field name="sequence">20</field> <field name="sequence">20</field>

View File

@@ -40,3 +40,5 @@ access_maintenance_equipment_image,maintenance_equipment_image,model_maintenance
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
40
41
42
43
44

View File

@@ -2,4 +2,3 @@ from . import http
from . import models from . import models
from . import process_status from . import process_status
from . import jd_eclp from . import jd_eclp

View File

@@ -1,8 +1,8 @@
# import cpca
import base64 import base64
import logging import logging
from datetime import datetime from datetime import datetime
import requests import requests
import cpca
from odoo.exceptions import UserError from odoo.exceptions import UserError
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
from odoo import api, fields, models, SUPERUSER_ID, _ from odoo import api, fields, models, SUPERUSER_ID, _

View File

@@ -4,7 +4,6 @@ import uuid
import string import string
import random import random
from odoo import fields, models from odoo import fields, models
__author__ = 'jinling.yang' __author__ = 'jinling.yang'
@@ -25,4 +24,4 @@ class ResPartner(models.Model):
return ran_str return ran_str
sf_token = fields.Char(u'Token', default=get_token) sf_token = fields.Char(u'Token', default=get_token)
sf_secret_key = fields.Char(u'密钥', default=get_secret) sf_secret_key = fields.Char(u'密钥', default=get_secret)

View File

@@ -22,24 +22,25 @@
'views/ftp_button.xml', 'views/ftp_button.xml',
'views/compensation.xml', 'views/compensation.xml',
# 只有它被屏蔽了
# 'views/SfWorkOrderBarcodes.xml', # 'views/SfWorkOrderBarcodes.xml',
'views/WorkCenterBarcodes.xml', 'views/WorkCenterBarcodes.xml',
'views/Stock_picking_Barcodes.xml', 'views/Stock_picking_Barcodes.xml',
# 'views/machine_monitor.xml', 'views/machine_monitor.xml',
'views/machine_info_present.xml', 'views/machine_info_present.xml',
'views/delivery_record.xml', 'views/delivery_record.xml',
'views/res_config_settings_views.xml', 'views/res_config_settings_views.xml',
], ],
'assets': { 'assets': {
'web.assets_backend': [ 'web.assets_backend': [
# 'sf_machine_connect/static/src/xml/barcode_button.xml', # 'sf_machine_connect/static/src/xml/barcode_button.xml',
# 'sf_machine_connect/static/src/js/barcode_button.js', # 'sf_machine_connect/static/src/js/barcode_button.js',
# 'sf_machine_connect/static/src/css/barcode_button.css', # 'sf_machine_connect/static/src/css/barcode_button.css',
], ],
}, },
'external_dependencies': {'python': ['opcua(使用pip install opcua -i https://pypi.tuna.tsinghua.edu.cn/simple)']}, # 'external_dependencies': {'python': ['opcua(使用pip install opcua -i https://pypi.tuna.tsinghua.edu.cn/simple)']},
'installable': True, 'installable': True,
'application': True, 'application': True,

View File

@@ -60,11 +60,11 @@ class FtpButton(models.Model):
raise UserError("补偿值写入执行超时,请检查机床状态或者写入状态") raise UserError("补偿值写入执行超时,请检查机床状态或者写入状态")
# host="192.168.2.158", port=8080, username="MITSUBISHI", password="CNC" # host="192.168.2.158", port=8080, username="MITSUBISHI", password="CNC"
host = self.workorder_id.workcenter_id.machine_tool_id.ftp_host host = self.workorder_id.equipment_id.ftp_host
port = self.workorder_id.workcenter_id.machine_tool_id.ftp_port port = self.workorder_id.equipment_id.ftp_port
username = self.workorder_id.workcenter_id.machine_tool_id.ftp_num username = self.workorder_id.equipment_id.ftp_num
pwd = self.workorder_id.workcenter_id.machine_tool_id.ftp_pwd pwd = self.workorder_id.equipment_id.ftp_pwd
remote_path = self.workorder_id.workcenter_id.machine_tool_id.ftp_remote_path remote_path = self.workorder_id.equipment_id.ftp_remote_path
print(host, port, username, pwd, remote_path) print(host, port, username, pwd, remote_path)
ftp = ftp_operate.FtpController(host, port, username, pwd) ftp = ftp_operate.FtpController(host, port, username, pwd)
# ftp.delAllfile('C://Users//马广威//Desktop//ftp') # ftp.delAllfile('C://Users//马广威//Desktop//ftp')
@@ -107,8 +107,8 @@ class FtpButton(models.Model):
下发NC代码前自动补偿三元检测偏差值 下发NC代码前自动补偿三元检测偏差值
:return: :return:
""" """
hongbianliang550 = self.workorder_id.workcenter_id.machine_tool_id.x_compensation_node hongbianliang550 = self.workorder_id.equipment_id.x_compensation_node
hongbianliang551 = self.workorder_id.workcenter_id.machine_tool_id.y_compensation_node hongbianliang551 = self.workorder_id.equipment_id.y_compensation_node
try: try:
temp_dict = {} temp_dict = {}
temp_dict[hongbianliang550] = self.workorder_id.compensation_value_x temp_dict[hongbianliang550] = self.workorder_id.compensation_value_x
@@ -124,9 +124,9 @@ class Machine_ftp(models.Model):
""" """
数据采集类 数据采集类
""" """
_inherit = 'sf.machine_tool' _inherit = 'maintenance.equipment'
workorder_ids = fields.One2many('mrp.workorder', 'machine_tool_id', string='工单') # workorder_ids = fields.One2many('mrp.workorder', 'machine_tool_id', string='工单')
# 机床配置项目 # 机床配置项目
# ftp相关 # ftp相关
@@ -263,7 +263,7 @@ class WorkCenterBarcode(models.Model):
compensation_value_y = fields.Float(string='Y轴补偿值') compensation_value_y = fields.Float(string='Y轴补偿值')
button_compensation_state = fields.Boolean(string='是否已经补偿', readonly=True) button_compensation_state = fields.Boolean(string='是否已经补偿', readonly=True)
button_up_all_state = fields.Boolean(string='是否已经全部下发', readonly=True) button_up_all_state = fields.Boolean(string='是否已经全部下发', readonly=True)
machine_tool_id = fields.Many2one('sf.machine_tool', string='机床') machine_tool_id = fields.Many2one('sf.machine_tool.type', string='机床')
machine_tool_name = fields.Char(string='机床名称', default='未知机床', compute='_run_info', readonly=True) machine_tool_name = fields.Char(string='机床名称', default='未知机床', compute='_run_info', readonly=True)
machine_tool_type_id = fields.Char(string='机床型号', default='未知型号', compute='_run_info', readonly=True) machine_tool_type_id = fields.Char(string='机床型号', default='未知型号', compute='_run_info', readonly=True)
machine_tool_status = fields.Boolean(string='在线状态', compute='_run_info', readonly=True) machine_tool_status = fields.Boolean(string='在线状态', compute='_run_info', readonly=True)
@@ -281,27 +281,27 @@ class WorkCenterBarcode(models.Model):
machine_tool_compensation_value_y = fields.Char('y补偿值', compute='_run_info', readonly=True) machine_tool_compensation_value_y = fields.Char('y补偿值', compute='_run_info', readonly=True)
delivery_records = fields.One2many('delivery.record', 'workorder_id', string="下发记录") delivery_records = fields.One2many('delivery.record', 'workorder_id', string="下发记录")
@api.depends('workcenter_id.machine_tool_id.timestamp') @api.depends('equipment_id.timestamp')
def _run_info(self): def _run_info(self):
# self.machine_tool_name = '1号机床' # self.machine_tool_name = '1号机床'
self.machine_tool_name = self.workcenter_id.machine_tool_id.name self.machine_tool_name = self.equipment_id.name
self.machine_tool_type_id = self.workcenter_id.machine_tool_id.type_id.name self.machine_tool_type_id = self.equipment_id.type_id.name
self.machine_tool_status = self.workcenter_id.machine_tool_id.status self.machine_tool_status = self.equipment_id.status
self.machine_tool_run_status = self.workcenter_id.machine_tool_id.run_status self.machine_tool_run_status = self.equipment_id.run_status
self.machine_tool_timestamp = self.workcenter_id.machine_tool_id.timestamp self.machine_tool_timestamp = self.equipment_id.timestamp
self.machine_tool_time_on = self.workcenter_id.machine_tool_id.time_on self.machine_tool_time_on = self.equipment_id.time_on
self.machine_tool_time_on_now = self.workcenter_id.machine_tool_id.time_on_now self.machine_tool_time_on_now = self.equipment_id.time_on_now
self.machine_tool_tool_num = self.workcenter_id.machine_tool_id.tool_num self.machine_tool_tool_num = self.equipment_id.tool_num
self.machine_tool_program = self.workcenter_id.machine_tool_id.program self.machine_tool_program = self.equipment_id.program
self.machine_tool_machine_ip = self.workcenter_id.machine_tool_id.machine_ip self.machine_tool_machine_ip = self.equipment_id.machine_ip
self.machine_tool_cut_status = self.workcenter_id.machine_tool_id.cut_status self.machine_tool_cut_status = self.equipment_id.cut_status
self.machine_tool_compensation_value_x = self.compensation_value_x self.machine_tool_compensation_value_x = self.compensation_value_x
self.machine_tool_compensation_value_y = self.compensation_value_y self.machine_tool_compensation_value_y = self.compensation_value_y
def compensation(self): def compensation(self):
hongbianliang550 = self.workcenter_id.machine_tool_id.x_compensation_node hongbianliang550 = self.equipment_id.x_compensation_node
hongbianliang551 = self.workcenter_id.machine_tool_id.y_compensation_node hongbianliang551 = self.equipment_id.y_compensation_node
try: try:
temp_dict = {} temp_dict = {}
temp_dict[hongbianliang550] = self.compensation_value_x temp_dict[hongbianliang550] = self.compensation_value_x
@@ -339,11 +339,11 @@ class WorkCenterBarcode(models.Model):
except Exception: except Exception:
raise UserError("补偿值写入执行超时,请检查机床状态或者写入状态") raise UserError("补偿值写入执行超时,请检查机床状态或者写入状态")
sequence_collect = [] sequence_collect = []
host = self.workcenter_id.machine_tool_id.ftp_host host = self.equipment_id.ftp_host
port = self.workcenter_id.machine_tool_id.ftp_port port = self.equipment_id.ftp_port
username = self.workcenter_id.machine_tool_id.ftp_num username = self.equipment_id.ftp_num
pwd = self.workcenter_id.machine_tool_id.ftp_pwd pwd = self.equipment_id.ftp_pwd
remote_path = self.workcenter_id.machine_tool_id.ftp_remote_path remote_path = self.equipment_id.ftp_remote_path
_logger.info("=====================1666666661111================%s,%s,%s,%s" % (host, port, username, pwd)) _logger.info("=====================1666666661111================%s,%s,%s,%s" % (host, port, username, pwd))
ftp = ftp_operate.FtpController(host, port, username, pwd) ftp = ftp_operate.FtpController(host, port, username, pwd)
_logger.info("=====================1777777777111================") _logger.info("=====================1777777777111================")
@@ -403,11 +403,11 @@ class WorkCenterBarcode(models.Model):
except Exception: except Exception:
raise UserError("补偿值写入执行超时,请检查机床状态或者写入状态") raise UserError("补偿值写入执行超时,请检查机床状态或者写入状态")
sequence_collect = [] sequence_collect = []
host = self.workcenter_id.machine_tool_id.ftp_host host = self.equipment_id.ftp_host
port = self.workcenter_id.machine_tool_id.ftp_port port = self.equipment_id.ftp_port
username = self.workcenter_id.machine_tool_id.ftp_num username = self.equipment_id.ftp_num
pwd = self.workcenter_id.machine_tool_id.ftp_pwd pwd = self.equipment_id.ftp_pwd
remote_path = self.workcenter_id.machine_tool_id.ftp_remote_path remote_path = self.equipment_id.ftp_remote_path
_logger.info("=====================1666666661111================%s,%s,%s,%s" % (host, port, username, pwd)) _logger.info("=====================1666666661111================%s,%s,%s,%s" % (host, port, username, pwd))
ftp = ftp_operate.FtpController(host, port, username, pwd) ftp = ftp_operate.FtpController(host, port, username, pwd)
_logger.info("=====================1777777777111================") _logger.info("=====================1777777777111================")

View File

@@ -91,7 +91,6 @@ class FtpController:
""" """
self.ftp.close() self.ftp.close()
def delAllfile(self, ftppath): def delAllfile(self, ftppath):
""" """
删除ftp服务器端全部文件 删除ftp服务器端全部文件

View File

@@ -26,11 +26,11 @@ class Py2opcua:
""" """
# try: # try:
self.client.connect() self.client.connect()
# print("opcua服务器连接成功可以写入") # print("opcua服务器连接成功可以写入")
# return self.client # return self.client
# except Exception as e: # except Exception as e:
# print("opcua服务器连接失败请检查" + str(e)) # print("opcua服务器连接失败请检查" + str(e))
# temp_dict = temp_dict # temp_dict = temp_dict
temp_list = list(temp_dict.items()) temp_list = list(temp_dict.items())
for i in range(len(temp_list)): for i in range(len(temp_list)):
# 寻找节点上的变量 # 寻找节点上的变量

View File

@@ -10,7 +10,7 @@ class ResBFMConfigSettings(models.TransientModel):
bfm_url = fields.Selection( bfm_url = fields.Selection(
[("https://bfm.cs.jikimo.com", "开发环境(https://bfm.cs.jikimo.com)"), [("https://bfm.cs.jikimo.com", "开发环境(https://bfm.cs.jikimo.com)"),
("https://bfm.r.jikimo.com", "测试环境(https://bfm.r.jikimo.com)"), ("https://bfm.t.jikimo.com", "测试环境(https://bfm.t.jikimo.com)"),
# ("正式环境", "https://bfm.jikimo.com")], string='bfm环境', store=True) # ("正式环境", "https://bfm.jikimo.com")], string='bfm环境', store=True)
("https://bfm.jikimo.com", "正式环境(https://bfm.jikimo.com)")], string='bfm环境', store=True) ("https://bfm.jikimo.com", "正式环境(https://bfm.jikimo.com)")], string='bfm环境', store=True)

View File

@@ -1,12 +1,12 @@
odoo.define('my_module.barcode_handler', function (require) { odoo.define('my_module.barcode_handler', function (require) {
"use strict"; "use strict";
var core = require('web.core'); // var core = require('web.core');
var registry = require('web.field_registry'); var registry = require('web.field_registry');
var session = require('web.session'); var session = require('web.session');
var FieldChar = require('web.basic_fields').FieldChar; var FieldChar = require('web.basic_fields').FieldChar;
var _t = core._t; // var _t = core._t;
var BarcodeHandlerField = FieldChar.extend({ var BarcodeHandlerField = FieldChar.extend({
init: function () { init: function () {

View File

@@ -56,7 +56,7 @@ export class BarcodeHandlerField extends Component {
// }); // });
await this.actionService.doAction(response.result); await this.actionService.doAction(response.result);
} else { } else {
console.error("Barcode not found or RPC call failed."); // console.error("Barcode not found or RPC call failed.");
} }
} }

View File

@@ -2,14 +2,14 @@
<odoo> <odoo>
<record id="view_tree_mrs_machine_tool_inherited" model="ir.ui.view"> <record id="view_tree_mrs_machine_tool_inherited" model="ir.ui.view">
<field name="name">sf_base_extension</field> <field name="name">sf_base_extension</field>
<field name="model">sf.machine_tool</field> <field name="model">maintenance.equipment</field>
<field name="inherit_id" ref="sf_base.sf_machine_tool_form"/> <field name="inherit_id" ref="sf_maintenance.sf_hr_equipment_view_form"/>
<field eval="20" name="priority"/> <field eval="20" name="priority"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<!-- <xpath expr="//field[@name='knife_type']" position="before">--> <!-- <xpath expr="//field[@name='knife_type']" position="before">-->
<xpath expr="//form//notebook//page[1]" position="inside"> <xpath expr="//form//notebook//page[1]" position="after">
<!-- <xpath expr="//page[@name='other']" position="before">--> <!-- <xpath expr="//page[@name='other']" position="before">-->
<notebook> <!-- <notebook> -->
<page string="机床监控"> <page string="机床监控">
<group string='状态监控'> <group string='状态监控'>
<group> <group>
@@ -256,49 +256,51 @@
</group> </group>
</group> </group>
</page> </page>
</notebook> <!-- </notebook> -->
</xpath> </xpath>
</field> </field>
</record> </record>
<record id="view_cutting_tool_inherited" model="ir.ui.view">
<field name="name">sf_cutting_tool_extension</field>
<field name="model">sf.cutting_tool.type</field>
<field name="inherit_id" ref="sf_base.form_sf_cutting_tool_type"/>
<field name="arch" type="xml">
<xpath expr="//form//group" position="after">
<group string='刀具寿命'>
<group>
<field name="total_cut_time"/>
<field name="tool_position"/>
</group> <!-- 刀具寿命 -->
<group> <!-- <record id="view_cutting_tool_inherited" model="ir.ui.view"> -->
<field name="predict_life_time"/> <!-- <field name="name">sf_cutting_tool_extension</field> -->
<!-- <field name="model">sf.cutting_tool.type</field> -->
<!-- <field name="inherit_id" ref="sf_base.form_sf_machine_tool_type"/> -->
<!-- <field name="arch" type="xml"> -->
<!-- <xpath expr="//form//group" position="after"> -->
<!-- <group string='刀具寿命'> -->
<!-- <group> -->
<!-- <field name="total_cut_time"/> -->
<!-- <field name="tool_position"/> -->
</group> <!-- </group> -->
<!-- <group> -->
<!-- <field name="predict_life_time"/> -->
<div> <!-- </group> -->
<div> <!-- <div> -->
<field name='is_connect_tool_position' invisible='1'/>
<button string="绑定刀位" name="tool_connect_machine" type="object" confirm="是否确认绑定此刀位" <!-- <div> -->
class="btn-primary"/> <!-- <field name='is_connect_tool_position' invisible='1'/> -->
<!-- <button string="绑定刀位" name="tool_connect_machine" type="object" confirm="是否确认绑定此刀位" -->
<!-- class="btn-primary"/> -->
<!-- attrs='{"invisible": [("is_connect_tool_position","!=", --> <!-- attrs='{"invisible": [("is_connect_tool_position","!=", -->
<!-- "False")]}' --> <!-- "False")]}' -->
<span>&#32;</span> <!-- <span>&#32;</span> -->
<button string="解绑刀位" name="tool_unconnect_machine" type="object" confirm="是否解绑此刀位" <!-- <button string="解绑刀位" name="tool_unconnect_machine" type="object" confirm="是否解绑此刀位" -->
class="btn-primary"/> <!-- class="btn-primary"/> -->
<!-- attrs='{"invisible": [("is_connect_tool_position","!=", --> <!-- attrs='{"invisible": [("is_connect_tool_position","!=", -->
<!-- "False")]}' --> <!-- "False")]}' -->
</div> <!-- </div> -->
</div> <!-- </div> -->
</group> <!-- </group> -->
</xpath> <!-- </xpath> -->
</field> <!-- </field> -->
</record> <!-- </record> -->
</odoo> </odoo>

View File

@@ -2,6 +2,7 @@
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
class SfEquipmentSaintenanceStandards(models.Model): class SfEquipmentSaintenanceStandards(models.Model):
_name = 'equipment.maintenance.standards' _name = 'equipment.maintenance.standards'
_description = '设备维保标准' _description = '设备维保标准'
@@ -18,6 +19,7 @@ class SfEquipmentSaintenanceStandards(models.Model):
m = int(partner.code[-4:]) + 1 m = int(partner.code[-4:]) + 1
num = "%04d" % m num = "%04d" % m
return num return num
code = fields.Char(string='编码') code = fields.Char(string='编码')
remark = fields.Char('备注') remark = fields.Char('备注')
maintenance_type = fields.Selection([('保养', '保养'), ("检修", "检修")], string='类型', default='保养') maintenance_type = fields.Selection([('保养', '保养'), ("检修", "检修")], string='类型', default='保养')
@@ -69,6 +71,7 @@ class SfEquipmentSaintenanceStandards(models.Model):
# 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 = '维保项目'
@@ -92,7 +95,3 @@ class MaintenanceStandardImage(models.Model):
image = fields.Binary(string='维保图片') image = fields.Binary(string='维保图片')
standard_id = fields.Many2one('maintenance.standards', string='Standard') standard_id = fields.Many2one('maintenance.standards', string='Standard')

View File

@@ -12,7 +12,8 @@ class SfMaintenanceEquipmentCategory(models.Model):
_inherit = 'maintenance.equipment.category' _inherit = 'maintenance.equipment.category'
_description = '设备类别' _description = '设备类别'
equipment_type = fields.Selection([('机床', '机床'), ('机器人', '机器人'), ('AGV小车', 'AGV小车'), ('检测设备', '检测设备')], string='类型', default='机床') equipment_type = fields.Selection([('机床', '机床'), ('机器人', '机器人'), ('AGV小车', 'AGV小车'),
('检测设备', '检测设备')], string='类型', default='机床')
class SfMaintenanceEquipment(models.Model): class SfMaintenanceEquipment(models.Model):
@@ -62,9 +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([('机床', '机床'), ('机器人', '机器人'), ('AGV小车', 'AGV小车'), ('检测设备', '检测设备')], compute='_compute_category_id') equipment_type = fields.Selection([('机床', '机床'), ('机器人', '机器人'), ('AGV小车', 'AGV小车'), ('检测设备', '检测设备')]
, compute='_compute_category_id')
@api.depends('category_id') @api.depends('category_id')
def _compute_category_id(self): def _compute_category_id(self):
@@ -72,8 +74,8 @@ class SfMaintenanceEquipment(models.Model):
if record: if record:
record.equipment_type = record.category_id.equipment_type record.equipment_type = record.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"), ("BT50", "BT50")], [("BT40", "BT40"), ("BT30", "BT30"), ("BT50", "BT50")],
default="", string="刀把类型") default="", string="刀把类型")
@@ -152,6 +154,18 @@ class SfMaintenanceEquipment(models.Model):
result.append((parameter.id, name)) result.append((parameter.id, name))
return result return result
@api.model
def create(self, vals):
# 在创建设备之前执行一些自定义逻辑
equipment = super(SfMaintenanceEquipment, self).create(vals)
equipment.name = equipment.MTcode + '#' + equipment.category_id.name
# 在创建设备之后执行一些自定义逻辑
# ...
return equipment
# @api.constrains('rotate_speed') # @api.constrains('rotate_speed')
# def _check_rotate_speed(self): # def _check_rotate_speed(self):
# if self.rotate_speed <= 0: # if self.rotate_speed <= 0:
@@ -278,7 +292,8 @@ class SfMaintenanceEquipment(models.Model):
detect_y_axis = fields.Char('检测Y轴') detect_y_axis = fields.Char('检测Y轴')
detect_z_axis = fields.Char('检测Z轴') detect_z_axis = fields.Char('检测Z轴')
detect_precision = fields.Char('测量精度') detect_precision = fields.Char('测量精度')
detect_measurement_mode = fields.Selection([('光栅尺', '光栅尺'), ('容栅', '容栅'), ('磁栅', '磁栅'), ('激光干涉仪', '激光干涉仪')], string='测量方式') detect_measurement_mode = fields.Selection([('光栅尺', '光栅尺'), ('容栅', '容栅'), ('磁栅', '磁栅'),
('激光干涉仪', '激光干涉仪')], string='测量方式')
detect_resolution = fields.Char('分辨率') detect_resolution = fields.Char('分辨率')
detect_load_weight_max = fields.Char('最大负载重量') detect_load_weight_max = fields.Char('最大负载重量')
detect_weight = fields.Char('本体总重量') detect_weight = fields.Char('本体总重量')
@@ -304,13 +319,15 @@ class SfMaintenanceEquipment(models.Model):
robot_load_weight_max = fields.Char('最大负载重量') robot_load_weight_max = fields.Char('最大负载重量')
robot_weight = fields.Char('本体总重量') robot_weight = fields.Char('本体总重量')
robot_repeatable_positioning_accuracy = fields.Char('重复定位精度') robot_repeatable_positioning_accuracy = fields.Char('重复定位精度')
robot_axis_num = fields.Selection([('2轴', '2轴'), ('3轴', '3轴'), ('4轴', '4轴'), ('5轴', '5轴'), ('6轴', '6轴'), ('7轴', '7轴'), ('8轴', '8轴')], string='轴数') robot_axis_num = fields.Selection([('2轴', '2轴'), ('3轴', '3轴'), ('4轴', '4轴'), ('5轴', '5轴'), ('6轴', '6轴'),
('7轴', '7轴'), ('8轴', '8轴')], string='轴数')
axis_ids = fields.One2many('sf.robot.axis.num', 'equipment_id', string='动作范围') axis_ids = fields.One2many('sf.robot.axis.num', 'equipment_id', string='动作范围')
robot_track_dimensions_L = fields.Char('轨道尺寸(长)') robot_track_dimensions_L = fields.Char('轨道尺寸(长)')
robot_track_dimensions_W = fields.Char('轨道尺寸(宽)') robot_track_dimensions_W = fields.Char('轨道尺寸(宽)')
robot_track_dimensions_H = fields.Char('轨道尺寸(高)') robot_track_dimensions_H = fields.Char('轨道尺寸(高)')
robot_drive_mode = fields.Char('驱动方式') robot_drive_mode = fields.Char('驱动方式')
robot_installation_method = fields.Selection([('置地式', '置地式'), ('壁挂式', '壁挂式'), ('倒挂式', '倒挂式')], string='安装方式') robot_installation_method = fields.Selection([('置地式', '置地式'), ('壁挂式', '壁挂式'), ('倒挂式', '倒挂式')],
string='安装方式')
robot_operating_temperature = fields.Char('机器人环境温度') robot_operating_temperature = fields.Char('机器人环境温度')
robot_operating_humidity = fields.Char('机器人环境湿度') robot_operating_humidity = fields.Char('机器人环境湿度')
@@ -347,7 +364,7 @@ class SfMaintenanceEquipment(models.Model):
images_ids_names = [] images_ids_names = []
for a in self.env['maintenance.equipment.image'].search([('id', 'in', item.image_id.ids)]): for a in self.env['maintenance.equipment.image'].search([('id', 'in', item.image_id.ids)]):
images_ids_names.append(a.name) images_ids_names.append(a.name)
if item.machine_tool_picture != False: if item.machine_tool_picture:
image = base64.b64encode(item.machine_tool_picture).decode('utf-8') image = base64.b64encode(item.machine_tool_picture).decode('utf-8')
else: else:
image = False image = False
@@ -433,7 +450,8 @@ class SfMaintenanceEquipment(models.Model):
if next_maintenance_todo and last_maintenance_done: if next_maintenance_todo and last_maintenance_done:
next_date = next_maintenance_todo.request_date next_date = next_maintenance_todo.request_date
date_gap = next_maintenance_todo.request_date - last_maintenance_done.close_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 # 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 # 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( if date_gap > timedelta(0) and date_gap > timedelta(
days=equipment.period) * 2 and next_maintenance_todo.request_date > date_now: days=equipment.period) * 2 and next_maintenance_todo.request_date > date_now:
@@ -445,7 +463,8 @@ class SfMaintenanceEquipment(models.Model):
elif next_maintenance_todo: elif next_maintenance_todo:
next_date = next_maintenance_todo.request_date next_date = next_maintenance_todo.request_date
date_gap = next_maintenance_todo.request_date - date_now 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 # 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 # 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: if date_gap > timedelta(0) and date_gap > timedelta(days=equipment.period) * 2:
next_date = date_now + timedelta(days=equipment.period) next_date = date_now + timedelta(days=equipment.period)
@@ -475,7 +494,8 @@ class SfMaintenanceEquipment(models.Model):
if next_maintenance_todo and last_maintenance_done: if next_maintenance_todo and last_maintenance_done:
next_date = next_maintenance_todo.request_date next_date = next_maintenance_todo.request_date
date_gap = next_maintenance_todo.request_date - last_maintenance_done.close_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 # 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 # 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( if date_gap > timedelta(0) and date_gap > timedelta(
days=equipment.overhaul_period) * 2 and next_maintenance_todo.request_date > date_now: days=equipment.overhaul_period) * 2 and next_maintenance_todo.request_date > date_now:
@@ -487,7 +507,8 @@ class SfMaintenanceEquipment(models.Model):
elif next_maintenance_todo: elif next_maintenance_todo:
next_date = next_maintenance_todo.request_date next_date = next_maintenance_todo.request_date
date_gap = next_maintenance_todo.request_date - date_now 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 # 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 # 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: if date_gap > timedelta(0) and date_gap > timedelta(days=equipment.overhaul_period) * 2:
next_date = date_now + timedelta(days=equipment.overhaul_period) next_date = date_now + timedelta(days=equipment.overhaul_period)
@@ -577,7 +598,8 @@ class SfMaintenanceEquipment(models.Model):
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='加工能力', domain="[('type', '=', '加工能力')]") image_id = fields.Many2many('maintenance.equipment.image', 'equipment_id', string='加工能力',
domain="[('type', '=', '加工能力')]")
class SfRobotAxisNum(models.Model): class SfRobotAxisNum(models.Model):

View File

@@ -1,6 +1,7 @@
# -*-coding:utf-8-*- # -*-coding:utf-8-*-
from odoo import fields, models from odoo import fields, models
class SfMaintenanceLogs(models.Model): class SfMaintenanceLogs(models.Model):
_name = 'sf.maintenance.logs' _name = 'sf.maintenance.logs'
_description = '设备故障日志' _description = '设备故障日志'
@@ -11,16 +12,17 @@ class SfMaintenanceLogs(models.Model):
brand = fields.Many2one('sf.machine.brand', related='maintenance_equipment_id.brand_id', string='品牌') brand = fields.Many2one('sf.machine.brand', related='maintenance_equipment_id.brand_id', string='品牌')
maintenance_equipment_id = fields.Many2one('maintenance.equipment', string='设备') maintenance_equipment_id = fields.Many2one('maintenance.equipment', string='设备')
code_location = fields.Char(string='编码位置') code_location = fields.Char(string='编码位置')
fault_type = fields.Selection([('电气类', '电气类'), ('机械类', '机械类'), ('程序类', '程序类'), ('系统类', '系统类')], string='故障类型') fault_type = fields.Selection(
[('电气类', '电气类'), ('机械类', '机械类'), ('程序类', '程序类'), ('系统类', '系统类')], string='故障类型')
fault_code = fields.Char(string='故障代码') fault_code = fields.Char(string='故障代码')
fault_alarm_info = fields.Char(string='故障报警信息') fault_alarm_info = fields.Char(string='故障报警信息')
alarm_level = fields.Selection([('一级', '一级(严重)'), ('二级', '二级(中等)'), ('三级', '三级(轻微)')], string='报警级别') alarm_level = fields.Selection([('一级', '一级(严重)'), ('二级', '二级(中等)'), ('三级', '三级(轻微)')],
string='报警级别')
alarm_time = fields.Datetime(string='报警时间') alarm_time = fields.Datetime(string='报警时间')
alarm_way = fields.Selection([('文本提示报警', '文本提示报警'), ('声光报警', '声光报警'), ('图文报警', '图文报警')], string='报警方式') alarm_way = fields.Selection([('文本提示报警', '文本提示报警'), ('声光报警', '声光报警'), ('图文报警', '图文报警')],
string='报警方式')
fault_process = fields.Text(string='故障处理方法') fault_process = fields.Text(string='故障处理方法')
operator = fields.Many2one('res.users', string='处理人') operator = fields.Many2one('res.users', string='处理人')
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

@@ -12,7 +12,7 @@ class SfMaintenanceEquipmentCategory(models.Model):
sf_maintenance_type = fields.Selection([('保养', '保养'), ('检修', '检修')], string='维保类别', default='保养') sf_maintenance_type = fields.Selection([('保养', '保养'), ('检修', '检修')], string='维保类别', default='保养')
equipment_maintenance_id = fields.Many2one('equipment.maintenance.standards', string='设备维保标准', equipment_maintenance_id = fields.Many2one('equipment.maintenance.standards', string='设备维保标准',
domain="[('maintenance_type','=',sf_maintenance_type)]") domain="[('maintenance_type','=',sf_maintenance_type)]")
@api.onchange('sf_maintenance_type') @api.onchange('sf_maintenance_type')
def _compute_equipment_maintenance_request_id(self): def _compute_equipment_maintenance_request_id(self):
@@ -38,8 +38,3 @@ class SfMaintenanceEquipmentCategory(models.Model):
def confirm_maintenance_done(self): def confirm_maintenance_done(self):
self.write({'stage_id': 3}) self.write({'stage_id': 3})

View File

@@ -52,11 +52,13 @@
<button type="object" class="oe_highlight" name='enroll_machine_tool' string="机床注册" <button type="object" class="oe_highlight" name='enroll_machine_tool' string="机床注册"
attrs="{'invisible': [('equipment_type', '!=', '机床'), ('brand_id','!=',False),('type_id','!=',False),('control_system_id','!=',False)]}"/> attrs="{'invisible': [('equipment_type', '!=', '机床'), ('brand_id','!=',False),('type_id','!=',False),('control_system_id','!=',False)]}"/>
</div> </div>
</xpath>
<xpath expr="//field[@name='category_id']" position="before">
<field name="MTcode"/>
</xpath> </xpath>
<xpath expr="//field[@name='category_id']" position="after"> <xpath expr="//field[@name='category_id']" position="after">
<field name="state_zc"/> <field name="state_zc"/>
<field name="code"/> <field name="code" readonly="1"/>
<field name="equipment_type" invisible="1"/> <field name="equipment_type" invisible="1"/>
<field name="brand_id" force_save="1"/> <field name="brand_id" force_save="1"/>
<field name="type_id" attrs="{'required': [('equipment_type', '=', '机床')]}" <field name="type_id" attrs="{'required': [('equipment_type', '=', '机床')]}"

View File

@@ -10,11 +10,12 @@
""", """,
'category': 'sf', 'category': 'sf',
'website': 'https://www.sf.jikimo.com', 'website': 'https://www.sf.jikimo.com',
'depends': ['mrp_workorder', 'sf_base', 'sf_maintenance', 'web_widget_model_viewer', 'stock'], 'depends': ['sf_base', 'sf_maintenance', 'web_widget_model_viewer', 'stock'],
'data': [ 'data': [
'data/stock_data.xml', 'data/stock_data.xml',
'security/group_security.xml', 'security/group_security.xml',
'security/ir.model.access.csv', 'security/ir.model.access.csv',
'views/mrp_views_menus.xml',
'views/mrp_production_addional_change.xml', 'views/mrp_production_addional_change.xml',
'views/mrp_routing_workcenter_view.xml', 'views/mrp_routing_workcenter_view.xml',
'views/production_line_view.xml', 'views/production_line_view.xml',
@@ -22,6 +23,7 @@
'views/mrp_workorder_view.xml', 'views/mrp_workorder_view.xml',
'views/model_type_view.xml', 'views/model_type_view.xml',
'views/sf_maintenance_equipment.xml', 'views/sf_maintenance_equipment.xml',
], ],
'assets': { 'assets': {

View File

@@ -8,8 +8,3 @@ from . import mrp_routing_workcenter
from . import stock from . import stock
from . import res_user from . import res_user
from . import production_line_base from . import production_line_base

View File

@@ -1,7 +1,4 @@
from odoo import fields, models,api from odoo import fields, models, api
class ModelType(models.Model): class ModelType(models.Model):
@@ -42,8 +39,6 @@ class ProductModelTypeRoutingSort(models.Model):
# if record: # if record:
# record.routing_type = record.route_workcenter_id.routing_type # record.routing_type = record.route_workcenter_id.routing_type
routing_type = fields.Selection(string="工序类型", related='route_workcenter_id.routing_type') routing_type = fields.Selection(string="工序类型", related='route_workcenter_id.routing_type')
workcenter_ids = fields.Many2many('mrp.workcenter', required=False, related='route_workcenter_id.workcenter_ids') workcenter_ids = fields.Many2many('mrp.workcenter', required=False, related='route_workcenter_id.workcenter_ids')
@@ -77,7 +72,6 @@ class EmbryoModelTypeRoutingSort(models.Model):
# if record: # if record:
# record.routing_type = record.route_workcenter_id.routing_type # record.routing_type = record.route_workcenter_id.routing_type
routing_type = fields.Selection(string="工序类型", related='route_workcenter_id.routing_type') routing_type = fields.Selection(string="工序类型", related='route_workcenter_id.routing_type')
workcenter_ids = fields.Many2many('mrp.workcenter', required=False, related='route_workcenter_id.workcenter_ids') workcenter_ids = fields.Many2many('mrp.workcenter', required=False, related='route_workcenter_id.workcenter_ids')
@@ -111,7 +105,6 @@ class SurfaceTechnicsModelTypeRoutingSort(models.Model):
# if record: # if record:
# record.routing_type = record.route_workcenter_id.routing_type # record.routing_type = record.route_workcenter_id.routing_type
routing_type = fields.Selection(string="工序类型", related='route_workcenter_id.routing_type') routing_type = fields.Selection(string="工序类型", related='route_workcenter_id.routing_type')
workcenter_ids = fields.Many2many('mrp.workcenter', required=False, related='route_workcenter_id.workcenter_ids') workcenter_ids = fields.Many2many('mrp.workcenter', required=False, related='route_workcenter_id.workcenter_ids')

View File

@@ -67,4 +67,5 @@ class MaintenanceRequest(models.Model):
class SfMaintenanceLogs(models.Model): class SfMaintenanceLogs(models.Model):
_inherit = 'sf.maintenance.logs' _inherit = 'sf.maintenance.logs'
production_line_id = fields.Many2one('sf.production.line', string='生产线', related='maintenance_equipment_id.production_line_id', store=True) production_line_id = fields.Many2one('sf.production.line', string='生产线',
related='maintenance_equipment_id.production_line_id', store=True)

View File

@@ -12,7 +12,8 @@ class ResWorkcenter(models.Model):
equipment_id = fields.Many2one( equipment_id = fields.Many2one(
'maintenance.equipment', string="设备", 'maintenance.equipment', string="设备",
) )
production_line_id = fields.Many2one('sf.production.line', string='生产线', related='equipment_id.production_line_id', store=True) production_line_id = fields.Many2one('sf.production.line', string='生产线',
related='equipment_id.production_line_id', store=True)
is_process_outsourcing = fields.Boolean('工艺外协') is_process_outsourcing = fields.Boolean('工艺外协')
users_ids = fields.Many2many("res.users", 'users_workcenter') users_ids = fields.Many2many("res.users", 'users_workcenter')

View File

@@ -10,7 +10,6 @@ from OCC.Extend.DataExchange import read_step_file
from OCC.Extend.DataExchange import write_stl_file from OCC.Extend.DataExchange import write_stl_file
class ResProductMo(models.Model): class ResProductMo(models.Model):
_inherit = 'product.template' _inherit = 'product.template'
@@ -289,7 +288,7 @@ class ResProductMo(models.Model):
self.suitable_machining_method_ids = [(6, 0, [])] if not \ self.suitable_machining_method_ids = [(6, 0, [])] if not \
self.cutting_tool_model_id.suitable_machining_method_ids \ self.cutting_tool_model_id.suitable_machining_method_ids \
else [(6, 0, self.cutting_tool_model_id.suitable_machining_method_ids.ids)] else [(6, 0, self.cutting_tool_model_id.suitable_machining_method_ids.ids)]
self.blade_tip_characteristics_id = [(6, 0,[])] if not \ self.blade_tip_characteristics_id = [(6, 0, [])] if not \
self.cutting_tool_model_id.blade_tip_characteristics_id \ self.cutting_tool_model_id.blade_tip_characteristics_id \
else [(6, 0, self.cutting_tool_model_id.blade_tip_characteristics_id.ids)] else [(6, 0, self.cutting_tool_model_id.blade_tip_characteristics_id.ids)]
@@ -873,3 +872,11 @@ class SfMaintenanceEquipmentTool(models.Model):
alarm_value = fields.Char('报警值') alarm_value = fields.Char('报警值')
used_value = fields.Char('已使用值') used_value = fields.Char('已使用值')
code = fields.Char('机床刀位号') code = fields.Char('机床刀位号')
name = fields.Char('', compute='_compute_name')
@api.depends('code')
def _compute_name(self):
for record in self:
if record.code:
record.name = record.code

View File

@@ -1,4 +1,4 @@
from odoo import models,fields from odoo import models, fields
class ProductionLine(models.Model): class ProductionLine(models.Model):
@@ -26,8 +26,3 @@ class ProductionLine(models.Model):
name = fields.Char('生产线', size=20, required=True) name = fields.Char('生产线', size=20, required=True)
code = fields.Char('编码', default=_get_code, readonly=True) code = fields.Char('编码', default=_get_code, readonly=True)
remark = fields.Char('备注') remark = fields.Char('备注')

View File

@@ -97,12 +97,15 @@ class QualityPoint(models.Model):
component_ids = fields.One2many('product.product', compute='_compute_component_ids') component_ids = fields.One2many('product.product', compute='_compute_component_ids')
product_ids = fields.Many2many( product_ids = fields.Many2many(
default=_default_product_ids, default=_default_product_ids,
domain="operation_id and [('id', 'in', bom_product_ids)] or [('type', 'in', ('product', 'consu')), '|', ('company_id', '=', False), ('company_id', '=', company_id)]") domain="operation_id and [('id', 'in', bom_product_ids)] or"
" [('type', 'in', ('product', 'consu')),"
" '|', ('company_id', '=', False), ('company_id', '=', company_id)]")
bom_product_ids = fields.One2many('product.product', compute="_compute_bom_product_ids") bom_product_ids = fields.One2many('product.product', compute="_compute_bom_product_ids")
test_type_id = fields.Many2one( test_type_id = fields.Many2one(
'quality.point.test_type', 'quality.point.test_type',
domain="[('allow_registration', '=', operation_id and is_workorder_step)]") domain="[('allow_registration', '=', operation_id and is_workorder_step)]")
test_report_type = fields.Selection([('pdf', 'PDF'), ('zpl', 'ZPL')], string="Report Type", default="pdf", required=True) test_report_type = fields.Selection([('pdf', 'PDF'), ('zpl', 'ZPL')], string="Report Type",
default="pdf", required=True)
source_document = fields.Selection( source_document = fields.Selection(
selection=[('operation', 'Specific Page of Operation Worksheet'), ('step', 'Custom')], selection=[('operation', 'Specific Page of Operation Worksheet'), ('step', 'Custom')],
string="Step Document", string="Step Document",
@@ -125,20 +128,23 @@ class QualityPoint(models.Model):
points_for_workorder_step = self.filtered(lambda p: p.operation_id and p.bom_id) points_for_workorder_step = self.filtered(lambda p: p.operation_id and p.bom_id)
for point in points_for_workorder_step: for point in points_for_workorder_step:
bom_product_ids = point.bom_id.product_id or point.bom_id.product_tmpl_id.product_variant_ids bom_product_ids = point.bom_id.product_id or point.bom_id.product_tmpl_id.product_variant_ids
point.bom_product_ids = bom_product_ids.filtered(lambda p: not p.company_id or p.company_id == point.company_id._origin) point.bom_product_ids = bom_product_ids.filtered(lambda p: not p.company_id or
p.company_id == point.company_id._origin)
@api.depends('product_ids', 'test_type_id', 'is_workorder_step') @api.depends('product_ids', 'test_type_id', 'is_workorder_step')
def _compute_component_ids(self): def _compute_component_ids(self):
self.component_ids = False self.component_ids = False
for point in self: for point in self:
if not point.is_workorder_step or not self.bom_id or point.test_type not in ('register_consumed_materials', 'register_byproducts'): if not point.is_workorder_step or not self.bom_id or point.test_type not in ('register_consumed_materials',
'register_byproducts'):
point.component_id = None point.component_id = None
continue continue
if point.test_type == 'register_byproducts': if point.test_type == 'register_byproducts':
point.component_ids = point.bom_id.byproduct_ids.product_id point.component_ids = point.bom_id.byproduct_ids.product_id
else: else:
bom_products = point.bom_id.product_id or point.bom_id.product_tmpl_id.product_variant_ids bom_products = point.bom_id.product_id or point.bom_id.product_tmpl_id.product_variant_ids
# If product_ids is set the step will exist only for these product variant then we can filter out for the bom explode # If product_ids is set the step will exist only for these product variant then we can filter
# out for the bom explode
if point.product_ids: if point.product_ids:
bom_products &= point.product_ids._origin bom_products &= point.product_ids._origin
@@ -183,7 +189,8 @@ class QualityCheck(models.Model):
workorder_id = fields.Many2one( workorder_id = fields.Many2one(
'mrp.workorder', 'Operation', check_company=True) 'mrp.workorder', 'Operation', check_company=True)
workcenter_id = fields.Many2one('mrp.workcenter', related='workorder_id.workcenter_id', store=True, readonly=True) # TDE: necessary ? workcenter_id = fields.Many2one('mrp.workcenter', related='workorder_id.workcenter_id', store=True,
readonly=True) # TDE: necessary ?
production_id = fields.Many2one( production_id = fields.Many2one(
'mrp.production', 'Production Order', check_company=True) 'mrp.production', 'Production Order', check_company=True)
@@ -201,12 +208,14 @@ class QualityCheck(models.Model):
component_uom_id = fields.Many2one('uom.uom', related='move_id.product_uom', readonly=True) component_uom_id = fields.Many2one('uom.uom', related='move_id.product_uom', readonly=True)
qty_done = fields.Float('Done', digits='Product Unit of Measure') qty_done = fields.Float('Done', digits='Product Unit of Measure')
finished_lot_id = fields.Many2one('stock.lot', 'Finished Lot/Serial', related='production_id.lot_producing_id', store=True) finished_lot_id = fields.Many2one('stock.lot', 'Finished Lot/Serial', related='production_id.lot_producing_id',
store=True)
additional = fields.Boolean('Register additional product', compute='_compute_additional') additional = fields.Boolean('Register additional product', compute='_compute_additional')
component_tracking = fields.Selection(related='component_id.tracking', string="Is Component Tracked") component_tracking = fields.Selection(related='component_id.tracking', string="Is Component Tracked")
# Workorder specific fields # Workorder specific fields
component_remaining_qty = fields.Float('Remaining Quantity for Component', compute='_compute_component_data', digits='Product Unit of Measure') component_remaining_qty = fields.Float('Remaining Quantity for Component', compute='_compute_component_data',
digits='Product Unit of Measure')
component_qty_to_do = fields.Float(compute='_compute_component_qty_to_do') component_qty_to_do = fields.Float(compute='_compute_component_qty_to_do')
is_user_working = fields.Boolean(related="workorder_id.is_user_working") is_user_working = fields.Boolean(related="workorder_id.is_user_working")
consumption = fields.Selection(related="workorder_id.consumption") consumption = fields.Selection(related="workorder_id.consumption")
@@ -241,7 +250,8 @@ class QualityCheck(models.Model):
super()._compute_title() super()._compute_title()
for check in self: for check in self:
if not check.point_id or check.component_id: if not check.point_id or check.component_id:
check.title = '{} "{}"'.format(check.test_type_id.display_name, check.component_id.name or check.workorder_id.name) check.title = '{} "{}"'.format(check.test_type_id.display_name, check.component_id.name
or check.workorder_id.name)
@api.depends('point_id', 'quality_state', 'component_id', 'component_uom_id', 'lot_id', 'qty_done') @api.depends('point_id', 'quality_state', 'component_id', 'component_uom_id', 'lot_id', 'qty_done')
def _compute_result(self): def _compute_result(self):
@@ -266,7 +276,8 @@ class QualityCheck(models.Model):
def _get_check_result(self): def _get_check_result(self):
if self.test_type in ('register_consumed_materials', 'register_byproducts') and self.lot_id: if self.test_type in ('register_consumed_materials', 'register_byproducts') and self.lot_id:
return '{} - {}, {} {}'.format(self.component_id.name, self.lot_id.name, self.qty_done, self.component_uom_id.name) return '{} - {}, {} {}'.format(self.component_id.name, self.lot_id.name, self.qty_done,
self.component_uom_id.name)
elif self.test_type in ('register_consumed_materials', 'register_byproducts'): elif self.test_type in ('register_consumed_materials', 'register_byproducts'):
return '{}, {} {}'.format(self.component_id.name, self.qty_done, self.component_uom_id.name) return '{}, {} {}'.format(self.component_id.name, self.qty_done, self.component_uom_id.name)
else: else:
@@ -281,12 +292,14 @@ class QualityCheck(models.Model):
for check in self: for check in self:
if check.test_type in ('register_byproducts', 'register_consumed_materials'): if check.test_type in ('register_byproducts', 'register_consumed_materials'):
if check.quality_state == 'none': if check.quality_state == 'none':
completed_lines = check.workorder_id.move_line_ids.filtered(lambda l: l.lot_id) if check.component_id.tracking != 'none' else check.workorder_id.move_line_ids completed_lines = check.workorder_id.move_line_ids.filtered(lambda l: l.lot_id)\
if check.component_id.tracking != 'none' else check.workorder_id.move_line_ids
if check.move_id.additional: if check.move_id.additional:
qty = check.workorder_id.qty_remaining qty = check.workorder_id.qty_remaining
else: else:
qty = check.workorder_id.qty_producing qty = check.workorder_id.qty_producing
check.component_remaining_qty = self._prepare_component_quantity(check.move_id, qty) - sum(completed_lines.mapped('qty_done')) check.component_remaining_qty = self._prepare_component_quantity(check.move_id, qty) -\
sum(completed_lines.mapped('qty_done'))
check.component_uom_id = check.move_id.product_uom check.component_uom_id = check.move_id.product_uom
def action_print(self): def action_print(self):
@@ -369,7 +382,8 @@ class QualityCheck(models.Model):
vals_list = [] vals_list = []
# apply putaway # apply putaway
location_dest_id = self.move_id.location_dest_id._get_putaway_strategy(self.move_id.product_id) location_dest_id = self.move_id.location_dest_id._get_putaway_strategy(self.move_id.product_id)
quants = self.env['stock.quant']._gather(self.product_id, self.move_id.location_id, lot_id=self.lot_id, strict=False) quants = self.env['stock.quant']._gather(self.product_id, self.move_id.location_id, lot_id=self.lot_id,
strict=False)
# Search for a sub-locations where the product is available. # Search for a sub-locations where the product is available.
# Loop on the quants to get the locations. If there is not enough # Loop on the quants to get the locations. If there is not enough
# quantity into stock, we take the move location. Anyway, no # quantity into stock, we take the move location. Anyway, no
@@ -386,7 +400,8 @@ class QualityCheck(models.Model):
for quant in quants: for quant in quants:
vals = shared_vals.copy() vals = shared_vals.copy()
quantity = quant.quantity - quant.reserved_quantity quantity = quant.quantity - quant.reserved_quantity
quantity = self.product_id.uom_id._compute_quantity(quantity, self.product_uom_id, rounding_method='HALF-UP') quantity = self.product_id.uom_id._compute_quantity(quantity, self.product_uom_id,
rounding_method='HALF-UP')
rounding = quant.product_uom_id.rounding rounding = quant.product_uom_id.rounding
if (float_compare(quant.quantity, 0, precision_rounding=rounding) <= 0 or if (float_compare(quant.quantity, 0, precision_rounding=rounding) <= 0 or
float_compare(quantity, 0, precision_rounding=self.product_uom_id.rounding) <= 0): float_compare(quantity, 0, precision_rounding=self.product_uom_id.rounding) <= 0):
@@ -469,7 +484,8 @@ class QualityCheck(models.Model):
def _update_component_quantity(self): def _update_component_quantity(self):
if self.component_tracking == 'serial': if self.component_tracking == 'serial':
self._origin.qty_done = self.component_id.uom_id._compute_quantity(1, self.component_uom_id, rounding_method='HALF-UP') self._origin.qty_done = self.component_id.uom_id._compute_quantity(1, self.component_uom_id,
rounding_method='HALF-UP')
return return
move = self.move_id move = self.move_id
# Compute the new quantity for the current component # Compute the new quantity for the current component

View File

@@ -5,4 +5,4 @@ from odoo import fields, models
class Users(models.Model): class Users(models.Model):
_inherit = 'res.users' _inherit = 'res.users'
workcenter_ids = fields.Many2many("mrp.workcenter", 'users_workcenter') workcenter_ids = fields.Many2many("mrp.workcenter", 'users_workcenter')

View File

@@ -125,7 +125,8 @@ class StockRule(models.Model):
moves_values_by_company[procurement.company_id.id].append(move_values) moves_values_by_company[procurement.company_id.id].append(move_values)
for company_id, moves_values in moves_values_by_company.items(): for company_id, moves_values in moves_values_by_company.items():
# create the move as SUPERUSER because the current user may not have the rights to do it (mto product launched by a sale for example) # create the move as SUPERUSER because the current user may not have the rights to do it (mto product
# launched by a sale for example)
moves = self.env['stock.move'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create(moves_values) moves = self.env['stock.move'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create(moves_values)
# Since action_confirm launch following procurement_group we should activate it. # Since action_confirm launch following procurement_group we should activate it.
moves._action_confirm() moves._action_confirm()
@@ -148,7 +149,8 @@ class StockRule(models.Model):
raise ProcurementException(errors) raise ProcurementException(errors)
for company_id, productions_values in productions_values_by_company.items(): for company_id, productions_values in productions_values_by_company.items():
# create the MO as SUPERUSER because the current user may not have the rights to do it (mto product launched by a sale for example) # create the MO as SUPERUSER because the current user may not have the rights to do it (mto product
# launched by a sale for example)
'''创建制造订单''' '''创建制造订单'''
productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create( productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create(
productions_values) productions_values)
@@ -162,7 +164,8 @@ class StockRule(models.Model):
productions.filtered(lambda p: (not p.orderpoint_id and p.move_raw_ids) or \ productions.filtered(lambda p: (not p.orderpoint_id and p.move_raw_ids) or \
( (
p.move_dest_ids.procure_method != 'make_to_order' and not p.move_raw_ids and not p.workorder_ids)).action_confirm() p.move_dest_ids.procure_method != 'make_to_order' and not
p.move_raw_ids and not p.workorder_ids)).action_confirm()
for production in productions: for production in productions:
''' '''
@@ -404,8 +407,8 @@ class ReStockMove(models.Model):
'fixture_clamp_workpiece_diameter_max': item.product_id.fixture_clamp_workpiece_diameter_max, 'fixture_clamp_workpiece_diameter_max': item.product_id.fixture_clamp_workpiece_diameter_max,
'fixture_maximum_carrying_weight': item.product_id.fixture_maximum_carrying_weight, 'fixture_maximum_carrying_weight': item.product_id.fixture_maximum_carrying_weight,
'fixture_maximum_clamping_force': item.product_id.fixture_maximum_clamping_force, 'fixture_maximum_clamping_force': item.product_id.fixture_maximum_clamping_force,
'fixture_driving_way': '' if not item.product_id.fixture_driving_way else 'fixture_driving_way': '' if not item.product_id.fixture_driving_way
item.product_id.fixture_driving_way, else item.product_id.fixture_driving_way,
'fixture_apply_machine_tool_type_codes': self.env[ 'fixture_apply_machine_tool_type_codes': self.env[
'product.template']._json_apply_machine_tool_type_item_code(item), 'product.template']._json_apply_machine_tool_type_item_code(item),
'fixture_through_hole_size': item.product_id.fixture_through_hole_size, 'fixture_through_hole_size': item.product_id.fixture_through_hole_size,
@@ -464,14 +467,14 @@ class ReStockMove(models.Model):
'blade_tip_taper': item.product_id.cutting_tool_blade_tip_taper, 'blade_tip_taper': item.product_id.cutting_tool_blade_tip_taper,
'blade_helix_angle': item.product_id.cutting_tool_blade_helix_angle, 'blade_helix_angle': item.product_id.cutting_tool_blade_helix_angle,
'blade_type': item.product_id.cutting_tool_blade_type, 'blade_type': item.product_id.cutting_tool_blade_type,
'coarse_medium_fine': '' if item.product_id.cutting_tool_coarse_medium_fine is False else 'coarse_medium_fine': '' if item.product_id.cutting_tool_coarse_medium_fine is False
item.product_id.cutting_tool_coarse_medium_fine, else item.product_id.cutting_tool_coarse_medium_fine,
'run_out_accuracy_max': item.product_id.cutting_tool_run_out_accuracy_max, 'run_out_accuracy_max': item.product_id.cutting_tool_run_out_accuracy_max,
'run_out_accuracy_min': item.product_id.cutting_tool_run_out_accuracy_min, 'run_out_accuracy_min': item.product_id.cutting_tool_run_out_accuracy_min,
'head_diameter': item.product_id.cutting_tool_head_diameter, 'head_diameter': item.product_id.cutting_tool_head_diameter,
'diameter': item.product_id.cutting_tool_diameter, 'diameter': item.product_id.cutting_tool_diameter,
'blade_number': '' if item.product_id.cutting_tool_blade_number is False else 'blade_number': '' if item.product_id.cutting_tool_blade_number is False
item.product_id.cutting_tool_blade_number, else item.product_id.cutting_tool_blade_number,
'front_angle': item.product_id.cutting_tool_front_angle, 'front_angle': item.product_id.cutting_tool_front_angle,
'rear_angle': item.product_id.cutting_tool_rear_angle, 'rear_angle': item.product_id.cutting_tool_rear_angle,
'main_included_angle': item.product_id.cutting_tool_main_included_angle, 'main_included_angle': item.product_id.cutting_tool_main_included_angle,

View File

@@ -1,11 +1,26 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_sf_cnc_processing,sf_cnc_processing,model_sf_cnc_processing,base.group_user,1,1,1,1 access_sf_cnc_processing,sf_cnc_processing,model_sf_cnc_processing,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_model_type,sf_model_type,model_sf_model_type,base.group_user,1,1,1,1 access_sf_cnc_processing_manager,sf_cnc_processing,model_sf_cnc_processing,sf_base.group_sf_mrp_manager,1,1,1,1
access_sf_product_model_type_routing_sort,sf_product_model_type_routing_sort,model_sf_product_model_type_routing_sort,base.group_user,1,1,1,1 access_sf_model_type,sf_model_type,model_sf_model_type,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_embryo_model_type_routing_sort,sf_embryo_model_type_routing_sort,model_sf_embryo_model_type_routing_sort,base.group_user,1,1,1,1 access_sf_model_type_manager,sf_model_type,model_sf_model_type,sf_base.group_sf_mrp_manager,1,1,1,1
access_sf_surface_technics_model_type_routing_sort,sf_surface_technics_model_type_routing_sort,model_sf_surface_technics_model_type_routing_sort,base.group_user,1,1,1,1 access_sf_product_model_type_routing_sort,sf_product_model_type_routing_sort,model_sf_product_model_type_routing_sort,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_production_line,sf.production.line,model_sf_production_line,base.group_user,1,1,1,1 access_sf_product_model_type_routing_sort_manager,sf_product_model_type_routing_sort,model_sf_product_model_type_routing_sort,sf_base.group_sf_mrp_manager,1,1,1,1
access_maintenance_equipment_tool,maintenance_equipment_tool,model_maintenance_equipment_tool,base.group_user,1,1,1,1 access_sf_embryo_model_type_routing_sort,sf_embryo_model_type_routing_sort,model_sf_embryo_model_type_routing_sort,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_embryo_model_type_routing_sort_manager,sf_embryo_model_type_routing_sort,model_sf_embryo_model_type_routing_sort,sf_base.group_sf_mrp_manager,1,1,1,1
access_sf_surface_technics_model_type_routing_sort,sf_surface_technics_model_type_routing_sort,model_sf_surface_technics_model_type_routing_sort,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_surface_technics_model_type_routing_sort_manager,sf_surface_technics_model_type_routing_sort,model_sf_surface_technics_model_type_routing_sort,sf_base.group_sf_mrp_manager,1,1,1,1
access_sf_production_line,sf.production.line,model_sf_production_line,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_production_line_manager,sf.production.line,model_sf_production_line,sf_base.group_sf_mrp_manager,1,1,1,1
access_maintenance_equipment_tool,maintenance_equipment_tool,model_maintenance_equipment_tool,sf_base.group_sf_mrp_user,1,0,0,0
access_maintenance_equipment_tool_manager,maintenance_equipment_tool,model_maintenance_equipment_tool,sf_base.group_sf_mrp_manager,1,1,1,1
access_mrp_production,mrp_production,model_mrp_production,sf_base.group_sf_mrp_user,1,0,0,0
access_mrp_production_manager,mrp_production,model_mrp_production,sf_base.group_sf_mrp_manager,1,1,1,0
access_mrp_workorder,mrp_workorder,model_mrp_workorder,sf_base.group_sf_mrp_user,1,0,0,0
access_mrp_workorder_manager,mrp_workorder,model_mrp_workorder,sf_base.group_sf_mrp_manager,1,1,1,0
access_mrp_workcenter,mrp_workcenter,model_mrp_workcenter,sf_base.group_sf_mrp_user,1,0,0,0
access_mrp_workcenter_manager,mrp_workcenter,model_mrp_workcenter,sf_base.group_sf_mrp_manager,1,1,1,0
access_mrp_workcenter_productivity,mrp_workcenter_productivity,model_mrp_workcenter_productivity,sf_base.group_sf_mrp_user,1,0,0,0
access_mrp_workcenter_productivity_manager,mrp_workcenter_productivity,model_mrp_workcenter_productivity,sf_base.group_sf_mrp_manager,1,1,1,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_sf_cnc_processing sf_cnc_processing model_sf_cnc_processing base.group_user sf_base.group_sf_mrp_user 1 1 0 1 0 1 0
3 access_sf_model_type access_sf_cnc_processing_manager sf_model_type sf_cnc_processing model_sf_model_type model_sf_cnc_processing base.group_user sf_base.group_sf_mrp_manager 1 1 1 1
4 access_sf_product_model_type_routing_sort access_sf_model_type sf_product_model_type_routing_sort sf_model_type model_sf_product_model_type_routing_sort model_sf_model_type base.group_user sf_base.group_sf_mrp_user 1 1 0 1 0 1 0
5 access_sf_embryo_model_type_routing_sort access_sf_model_type_manager sf_embryo_model_type_routing_sort sf_model_type model_sf_embryo_model_type_routing_sort model_sf_model_type base.group_user sf_base.group_sf_mrp_manager 1 1 1 1
6 access_sf_surface_technics_model_type_routing_sort access_sf_product_model_type_routing_sort sf_surface_technics_model_type_routing_sort sf_product_model_type_routing_sort model_sf_surface_technics_model_type_routing_sort model_sf_product_model_type_routing_sort base.group_user sf_base.group_sf_mrp_user 1 1 0 1 0 1 0
7 access_sf_production_line access_sf_product_model_type_routing_sort_manager sf.production.line sf_product_model_type_routing_sort model_sf_production_line model_sf_product_model_type_routing_sort base.group_user sf_base.group_sf_mrp_manager 1 1 1 1
8 access_maintenance_equipment_tool access_sf_embryo_model_type_routing_sort maintenance_equipment_tool sf_embryo_model_type_routing_sort model_maintenance_equipment_tool model_sf_embryo_model_type_routing_sort base.group_user sf_base.group_sf_mrp_user 1 1 0 1 0 1 0
9 access_sf_embryo_model_type_routing_sort_manager sf_embryo_model_type_routing_sort model_sf_embryo_model_type_routing_sort sf_base.group_sf_mrp_manager 1 1 1 1
10 access_sf_surface_technics_model_type_routing_sort sf_surface_technics_model_type_routing_sort model_sf_surface_technics_model_type_routing_sort sf_base.group_sf_mrp_user 1 0 0 0
11 access_sf_surface_technics_model_type_routing_sort_manager sf_surface_technics_model_type_routing_sort model_sf_surface_technics_model_type_routing_sort sf_base.group_sf_mrp_manager 1 1 1 1
12 access_sf_production_line sf.production.line model_sf_production_line sf_base.group_sf_mrp_user 1 0 0 0
13 access_sf_production_line_manager sf.production.line model_sf_production_line sf_base.group_sf_mrp_manager 1 1 1 1
14 access_maintenance_equipment_tool maintenance_equipment_tool model_maintenance_equipment_tool sf_base.group_sf_mrp_user 1 0 0 0
15 access_maintenance_equipment_tool_manager maintenance_equipment_tool model_maintenance_equipment_tool sf_base.group_sf_mrp_manager 1 1 1 1
16 access_mrp_production mrp_production model_mrp_production sf_base.group_sf_mrp_user 1 0 0 0
17 access_mrp_production_manager mrp_production model_mrp_production sf_base.group_sf_mrp_manager 1 1 1 0
18 access_mrp_workorder mrp_workorder model_mrp_workorder sf_base.group_sf_mrp_user 1 0 0 0
19 access_mrp_workorder_manager mrp_workorder model_mrp_workorder sf_base.group_sf_mrp_manager 1 1 1 0
20 access_mrp_workcenter mrp_workcenter model_mrp_workcenter sf_base.group_sf_mrp_user 1 0 0 0
21 access_mrp_workcenter_manager mrp_workcenter model_mrp_workcenter sf_base.group_sf_mrp_manager 1 1 1 0
22 access_mrp_workcenter_productivity mrp_workcenter_productivity model_mrp_workcenter_productivity sf_base.group_sf_mrp_user 1 0 0 0
23 access_mrp_workcenter_productivity_manager mrp_workcenter_productivity model_mrp_workcenter_productivity sf_base.group_sf_mrp_manager 1 1 1 0
24
25
26

View File

@@ -13,9 +13,9 @@ class CustomKanbanController extends KanbanController {
async setup() { async setup() {
super.setup(); super.setup();
console.log('99999999111'); // console.log('99999999111');
this.workOrders = await this.getAllWorkOrders(); this.workOrders = await this.getAllWorkOrders();
this.workOrdersNew = this.workOrders; // this.workOrdersNew = this.workOrders;
// console.log('lines222222222', this.workOrders); // console.log('lines222222222', this.workOrders);
// //
// console.log(typeof this.workOrders); // console.log(typeof this.workOrders);
@@ -39,14 +39,14 @@ class CustomKanbanController extends KanbanController {
const id = button.getAttribute('data-id'); const id = button.getAttribute('data-id');
console.log('true_id', id); console.log('true_id', id);
const context = {production_line_show: 'shengchanxian1'} // const context = {production_line_show: 'shengchanxian1'}
this.env.services.rpc('/web/dataset/call_kw', { this.env.services.rpc('/web/dataset/call_kw', {
model: 'mrp.workcenter', model: 'mrp.workcenter',
method: 'search_read', method: 'search_read',
args: [[], ['id']], args: [[], ['id']],
kwargs: {} kwargs: {}
}).then((records) => { }).then((records) => {
console.log(records) // console.log(records)
const ids = records.map(record => record.id); const ids = records.map(record => record.id);
const context = {production_line_show: id}; const context = {production_line_show: id};
this.env.services.rpc('/web/dataset/call_kw', { this.env.services.rpc('/web/dataset/call_kw', {
@@ -55,7 +55,7 @@ class CustomKanbanController extends KanbanController {
args: [ids, context], args: [ids, context],
kwargs: {} kwargs: {}
}).then((response) => { }).then((response) => {
console.log('response', response); // console.log('response', response);
location.reload(); location.reload();
window.onload = function () { window.onload = function () {
button.classList.add('choose') button.classList.add('choose')
@@ -77,7 +77,7 @@ class CustomKanbanController extends KanbanController {
// args: [], // args: [],
// kwargs: {}, // kwargs: {},
// }); // });
console.log('response', response); // console.log('response', response);
// console.log('response1', response1); // console.log('response1', response1);
// 你可以在这里处理响应,例如将其存储在控制器的状态中 // 你可以在这里处理响应,例如将其存储在控制器的状态中
return response; return response;

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<menuitem id="mrp.menu_mrp_root"
name="Manufacturing"
groups="mrp.group_mrp_user,mrp.group_mrp_manager,sf_base.group_sf_mrp_user,sf_base.group_sf_mrp_manager"
web_icon="mrp,static/description/icon.svg"
sequence="145">
<menuitem id="mrp.menu_mrp_manufacturing"
name="Operations"
sequence="10"/>
<menuitem id="mrp.mrp_planning_menu_root"
name="Planning"
sequence="15"/>
<menuitem id="mrp.enu_mrp_bom"
name="Products"
sequence="20"/>
<menuitem id="mrp.menu_mrp_reporting"
name="Reporting"
sequence="25"/>
<menuitem id="mrp.menu_mrp_configuration"
name="Configuration"
groups="mrp.group_mrp_manager,sf_base.group_sf_mrp_manager"
sequence="100"/>
</menuitem>
</odoo>

View File

@@ -89,7 +89,7 @@
<field name="model">maintenance.equipment</field> <field name="model">maintenance.equipment</field>
<field name="inherit_id" ref="sf_maintenance.sf_hr_equipment_view_form"/> <field name="inherit_id" ref="sf_maintenance.sf_hr_equipment_view_form"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//field[@name='brand_id']" position="after"> <xpath expr="//field[@name='type_id']" position="after">
<field name="production_line_id"/> <field name="production_line_id"/>
</xpath> </xpath>
</field> </field>

View File

@@ -37,7 +37,7 @@ class Sf_Mrs_Connect(http.Controller):
download_state = request.env['sf.cnc.processing'].with_user( download_state = request.env['sf.cnc.processing'].with_user(
request.env.ref("base.user_admin")).download_file_tmp( request.env.ref("base.user_admin")).download_file_tmp(
ret['folder_name'], r) ret['folder_name'], r)
if download_state == False: if not download_state:
res['status'] = -2 res['status'] = -2
res['message'] = '制造订单号为%s的CNC程序文件从FTP拉取失败' % (cnc_workorder.production_id.name) res['message'] = '制造订单号为%s的CNC程序文件从FTP拉取失败' % (cnc_workorder.production_id.name)
return json.JSONEncoder().encode(res) return json.JSONEncoder().encode(res)

View File

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

View File

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

View File

@@ -44,7 +44,3 @@ class ProcedureEquipmentResourceSetting(models.Model):
record.working_shift_id = record.working_calendar_id.working_shift_ids record.working_shift_id = record.working_calendar_id.working_shift_ids
else: else:
record.working_shift_id = None record.working_shift_id = None

View File

@@ -1,6 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from datetime import timedelta
from odoo import fields, models, api from odoo import fields, models, api
from odoo import SUPERUSER_ID from odoo import SUPERUSER_ID
from odoo.exceptions import ValidationError
# class FunctionalCuttingToolEntity(models.Model): # class FunctionalCuttingToolEntity(models.Model):
@@ -13,12 +16,41 @@ class FunctionalCuttingToolEntity(models.Model):
_description = '功能刀具列表' _description = '功能刀具列表'
# code = fields.Char('序列号') # code = fields.Char('序列号')
name = fields.Char(related='functional_tool_name_id.name')
functional_tool_name_id = fields.Many2one('sf.functional.tool.assembly', string='功能刀具名称', readonly=True)
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', readonly=True) barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', readonly=True)
name = fields.Char(related='barcode_id.name') sf_cutting_tool_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀具型号')
functional_tool_name_id = fields.Many2one('product.product', string='功能刀具名称', readonly=True) sf_cutting_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型',
mrs_cutting_tool_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀具型号') group_expand='_read_group_mrs_cutting_tool_type_id', compute_sudo=True)
mrs_cutting_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型',
group_expand='_read_group_mrs_cutting_tool_type_id', compute_sudo=True) functional_tool_diameter = fields.Integer(string='刀具直径(mm)', readonly=True)
knife_tip_r_angle = fields.Float(string='刀尖R角(mm)', readonly=True)
coarse_middle_thin = fields.Selection([("1", ""), ('2', ''), ('3', '')], string='粗/中/精', readonly=True)
new_former = fields.Selection([('0', ''), ('1', '')], string='新/旧', readonly=True)
tool_loading_length = fields.Float(string='装刀长(mm)', readonly=True)
functional_tool_length = fields.Float(string='伸出长(mm)', readonly=True)
effective_length = fields.Float(string='有效长(mm)', readonly=True)
tool_room_num = fields.Integer(string='刀具房数量', readonly=True, )
line_edge_knife_library_num = fields.Integer(string='线边刀库数量', readonly=True)
machine_knife_library_num = fields.Integer(string='机内刀库数量', readonly=True)
max_lifetime_value = fields.Integer(string='最大寿命值(min)', readonly=True)
alarm_value = fields.Integer(string='报警值(min)', readonly=True)
used_value = fields.Integer(string='已使用值(min)', readonly=True)
functional_tool_status = fields.Selection([('正常', '正常'), ('报警', '报警'), ('已拆除', '已拆除')],
string='状态', store=True, default='正常')
current_location_id = fields.Many2one('stock.location', string='当前位置', readonly=True)
image = fields.Binary('图片', readonly=True)
@api.depends('current_location_id')
def _compute_location_num(self):
"""
计算库存位置数量
"""
for obj in self:
if obj.current_location_id.name in ('组装后', '刀具房'):
obj.tool_room_num = 1
obj.line_edge_knife_library_num = 0
obj.machine_knife_library_num = 0
@api.model @api.model
def _read_group_mrs_cutting_tool_type_id(self, categories, domain, order): def _read_group_mrs_cutting_tool_type_id(self, categories, domain, order):
@@ -28,64 +60,44 @@ class FunctionalCuttingToolEntity(models.Model):
# 整体式刀具型号 # 整体式刀具型号
cutting_tool_integral_model_id = fields.Many2one('product.product', string='整体式刀具型号', readonly=True, cutting_tool_integral_model_id = fields.Many2one('product.product', string='整体式刀具型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '整体式刀具')]) domain=[('cutting_tool_material_id', '=', '整体式刀具')])
# 刀片型号 # 刀片型号
cutting_tool_blade_model_id = fields.Many2one('product.product', string='刀片型号', readonly=True, cutting_tool_blade_model_id = fields.Many2one('product.product', string='刀片型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '刀片')]) domain=[('cutting_tool_material_id', '=', '刀片')])
# 刀杆型号 # 刀杆型号
cutting_tool_cutterbar_model_id = fields.Many2one('product.product', string='刀杆型号', readonly=True, cutting_tool_cutterbar_model_id = fields.Many2one('product.product', string='刀杆型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '刀杆')]) domain=[('cutting_tool_material_id', '=', '刀杆')])
# 刀盘型号 # 刀盘型号
cutting_tool_cutterpad_model_id = fields.Many2one('product.product', string='刀盘型号', readonly=True, cutting_tool_cutterpad_model_id = fields.Many2one('product.product', string='刀盘型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '刀盘')]) domain=[('cutting_tool_material_id', '=', '刀盘')])
# 刀柄型号 # 刀柄型号
cutting_tool_cutterhandle_model_id = fields.Many2one('product.product', string='刀柄型号', readonly=True, cutting_tool_cutterhandle_model_id = fields.Many2one('product.product', string='刀柄型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '刀柄')]) domain=[('cutting_tool_material_id', '=', '刀柄')])
# 夹头型号 # 夹头型号
cutting_tool_cutterhead_model_id = fields.Many2one('product.product', string='夹头型号', readonly=True, cutting_tool_cutterhead_model_id = fields.Many2one('product.product', string='夹头型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '夹头')]) domain=[('cutting_tool_material_id', '=', '夹头')])
diameter = fields.Float('直径(mm)') whether_standard_knife = fields.Boolean(string='是否标准刀', default=True, readonly=True)
tool_grade = fields.Selection([('1', 'P1'), ('2', 'P2'), ('3', 'P3'), ('4', 'P4'), ('5', 'P5'), ('6', 'P6')], L_D_number = fields.Float(string='L/D值(mm)', readonly=True)
string='刀具等级') hiding_length = fields.Float(string='避空长(mm)', readonly=True)
machining_accuracy = fields.Float('加工精度(mm)') cut_time = fields.Integer(string='已切削时间(min)', readonly=True)
tool_length = fields.Float('装刀长(mm)') cut_length = fields.Float(string='已切削长度(mm)', readonly=True)
blade_number = fields.Integer('刃数') cut_number = fields.Integer(string='已切削次数', readonly=True)
integral_blade_length = fields.Float('整体刃长(mm)')
effective_blade_length = fields.Float('有效刃长(mm)')
max_life = fields.Float('最大寿命值')
is_standard = fields.Selection([('1', ''), ('0', '')], '是否标准刀')
applicable_range = fields.Char('适用范围')
image = fields.Binary('图片')
suitable_machining_method_ids = fields.Many2many('maintenance.equipment.image', suitable_machining_method_ids = fields.Many2many(
'rel_machining_product_template_tool_entity', '适合加工方式', 'maintenance.equipment.image', 'rel_machining_product_template_tool_entity', '适合加工方式',
domain=[('type', '=', '加工能力')], domain=[('type', '=', '加工能力')], related='cutting_tool_integral_model_id.suitable_machining_method_ids')
related='cutting_tool_integral_model_id.suitable_machining_method_ids') blade_tip_characteristics_id = fields.Many2many(
'maintenance.equipment.image', 'rel_blade_tip_product_template_tool_entity', '刀尖特征',
blade_tip_characteristics_id = fields.Many2many('maintenance.equipment.image', domain=[('type', '=', '刀尖特征')], related='cutting_tool_integral_model_id.blade_tip_characteristics_id')
'rel_blade_tip_product_template_tool_entity', '刀尖特征', handle_type_ids = fields.Many2many(
domain=[('type', '=', '刀尖特征')], 'maintenance.equipment.image', 'rel_handle_product_template_tool_entity', '柄部类型',
related='cutting_tool_integral_model_id.blade_tip_characteristics_id') domain=[('type', '=', '柄部类型')], related='cutting_tool_integral_model_id.handle_type_ids')
cutting_direction_ids = fields.Many2many(
handle_type_ids = fields.Many2many('maintenance.equipment.image', 'maintenance.equipment.image', 'rel_cutting_product_template_tool_entity', '走刀方向',
'rel_handle_product_template_tool_entity', '柄部类型', domain=[('type', '=', '走刀方向')], related='cutting_tool_integral_model_id.cutting_direction_ids')
domain=[('type', '=', '柄部类型')], suitable_coolant_ids = fields.Many2many(
related='cutting_tool_integral_model_id.handle_type_ids') 'maintenance.equipment.image', 'rel_coolant_product_template_tool_entity', '适合冷却液',
domain=[('type', '=', '冷却液')], related='cutting_tool_integral_model_id.suitable_coolant_ids')
cutting_direction_ids = fields.Many2many('maintenance.equipment.image',
'rel_cutting_product_template_tool_entity', '走刀方向',
domain=[('type', '=', '走刀方向')],
related='cutting_tool_integral_model_id.cutting_direction_ids')
suitable_coolant_ids = fields.Many2many('maintenance.equipment.image',
'rel_coolant_product_template_tool_entity', '适合冷却液',
domain=[('type', '=', '冷却液')],
related='cutting_tool_integral_model_id.suitable_coolant_ids')
def _get_functional_tool_model_ids(self, functional_tool_model_code): def _get_functional_tool_model_ids(self, functional_tool_model_code):
functional_tool_model_ids = [] functional_tool_model_ids = []
@@ -94,114 +106,77 @@ class FunctionalCuttingToolEntity(models.Model):
functional_tool_model_ids.append(functional_tool_model.id) functional_tool_model_ids.append(functional_tool_model.id)
return [(6, 0, functional_tool_model_ids)] return [(6, 0, functional_tool_model_ids)]
def open_functional_tool_warning(self):
action = self.env.ref('sf_tool_management.action_sf_functional_tool_warning')
result = action.read()[0]
result['domain'] = [('functional_tool_name_id', '=', self.functional_tool_name_id.id)]
return result
def open_stock_move_line(self):
action = self.env.ref('sf_tool_management.sf_inbound_and_outbound_records_of_functional_tools_view_act')
result = action.read()[0]
result['domain'] = [('lot_id', '=', self.barcode_id.id), ('qty_done', '>', 0)]
return result
class FunctionalToolWarning(models.Model): class FunctionalToolWarning(models.Model):
_name = 'sf.functional.tool.warning' _name = 'sf.functional.tool.warning'
_description = '功能刀具预警' _description = '功能刀具预警'
functional_cutting_tool_id = fields.Many2one('sf.functional.cutting.tool.entity', '功能刀具', readonly=True) name = fields.Char('名称', invisible=True, readonly=True, related='functional_tool_name_id.name')
functional_tool_assembly_id = fields.Many2one('sf.functional.tool.assembly', '功能刀具组装', readonly=True) # 机床信息
production_line_id = fields.Many2one('sf.production.line', string='生产线',
# code = fields.Char('编码', readonly=True, related='functional_cutting_tool_id.code') group_expand='_read_group_machine_table_name_ids')
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', readonly=True, maintenance_equipment_id = fields.Many2one('maintenance.equipment', string='CNC机床')
related='functional_cutting_tool_id.barcode_id') machine_tool_code = fields.Char(string='机台号')
name = fields.Char('名称', invisible=True, readonly=True, related='functional_cutting_tool_id.name') machine_table_type_id = fields.Many2one('maintenance.equipment.category', string='机床类型')
functional_tool_name_id = fields.Many2one('product.product', string='功能刀具名称', readonly=True, cutter_spacing_code_id = fields.Many2one('maintenance.equipment.tool', string='刀位号',
related='functional_cutting_tool_id.functional_tool_name_id') domain="[('equipment_id', '=', maintenance_equipment_id)]")
mrs_cutting_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', readonly=True, # 功能刀具信息
related='functional_cutting_tool_id.mrs_cutting_tool_type_id') functional_tool_name_id = fields.Many2one('sf.functional.tool.assembly', string='功能刀具名称')
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', related='functional_tool_name_id.barcode_id')
# 整体式刀具型号 mrs_cutting_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型')
cutting_tool_integral_model_id = fields.Many2one('product.product', string='整体式刀具型号', readonly=True, diameter = fields.Integer(string='刀具直径(mm)')
domain=[('cutting_tool_material_id', '=', '整体式刀具')], knife_tip_r_angle = fields.Float(string='刀尖R角(mm)')
related='functional_cutting_tool_id.cutting_tool_integral_model_id') # 其他信息
install_tool_time = fields.Datetime("刀具组装时间")
# 刀片型号 on_board_time = fields.Datetime('上机装刀时间')
cutting_tool_blade_model_id = fields.Many2one('product.product', string='刀片型号', readonly=True, max_lifetime_value = fields.Integer(string='最大寿命值(min)')
domain=[('cutting_tool_material_id', '=', '刀片')], alarm_value = fields.Integer(string='报警值(min)')
related='functional_cutting_tool_id.cutting_tool_blade_model_id') used_value = fields.Integer(string='已使用值(min)')
functional_tool_status = fields.Selection([('正常', '正常'), ('报警', '报警'), ('已拆除', '已拆除')], string='状态')
# 刀杆型号 alarm_time = fields.Char('报警时间')
cutting_tool_cutterbar_model_id = fields.Many2one('product.product', string='刀杆型号', readonly=True, dispose_user = fields.Char('处理人')
domain=[('cutting_tool_material_id', '=', '刀杆')], dispose_time = fields.Char('处理时间')
related='functional_cutting_tool_id.cutting_tool_cutterbar_model_id') dispose_func = fields.Char('处理方法/措施', readonly=False)
# 刀盘型号
cutting_tool_cutterpad_model_id = fields.Many2one('product.product', string='刀盘型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '刀盘')],
related='functional_cutting_tool_id.cutting_tool_cutterpad_model_id')
# 刀柄型号
cutting_tool_cutterhandle_model_id = fields.Many2one('product.product', string='刀柄型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '刀柄')],
related='functional_cutting_tool_id.cutting_tool_cutterhandle_model_id')
# 夹头型号
cutting_tool_cutterhead_model_id = fields.Many2one('product.product', string='夹头型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '夹头')],
related='functional_cutting_tool_id.cutting_tool_cutterhead_model_id')
diameter = fields.Float('直径(mm)', readonly=True, related='functional_cutting_tool_id.diameter')
tool_grade = fields.Selection([('1', 'P1'), ('2', 'P2'), ('3', 'P3'), ('4', 'P4'), ('5', 'P5'), ('6', 'P6')],
string='刀具等级', readonly=True, compute='_compute_functional_cutting_tool_id')
machining_accuracy = fields.Float('加工精度(mm)', readonly=True,
related='functional_cutting_tool_id.machining_accuracy')
# tool_length = fields.Float('装刀长', readonly=True, related='functional_cutting_tool_id.tool_length')
tool_length = fields.Float('装刀长(mm)', readonly=True, related='functional_cutting_tool_id.tool_length')
blade_number = fields.Integer('刃数', readonly=True, related='functional_cutting_tool_id.blade_number')
integral_blade_length = fields.Float('整体刃长(mm)', readonly=True,
related='functional_cutting_tool_id.integral_blade_length')
effective_blade_length = fields.Float('有效刃长(mm)', readonly=True,
related='functional_cutting_tool_id.effective_blade_length')
max_life = fields.Float('最大寿命值', readonly=True, related='functional_cutting_tool_id.max_life')
is_standard = fields.Selection([('1', ''), ('0', '')], '是否标准刀', readonly=True,
compute='_compute_functional_cutting_tool_id')
applicable_range = fields.Char('适用范围', readonly=True, related='functional_cutting_tool_id.applicable_range')
image = fields.Binary('图片', readonly=True, related='functional_cutting_tool_id.image')
install_tool_time = fields.Datetime("装刀时间", readonly=True,
related='functional_tool_assembly_id.tool_loading_time')
@api.depends('functional_cutting_tool_id')
def _compute_functional_cutting_tool_id(self):
if self.functional_cutting_tool_id:
self.tool_grade = self.functional_cutting_tool_id.tool_grade
self.is_standard = self.functional_cutting_tool_id.is_standard
# 功能刀具预警 特有字段
outbound_time = fields.Datetime('出库时间', readonly=True, related='functional_tool_assembly_id.receive_time')
on_board_time = fields.Datetime('上机时间', readonly=False)
machine_table_name_id = fields.Many2one('maintenance.equipment', string='机床名称', readonly=True,
group_expand='_read_group_machine_table_name_ids')
@api.model @api.model
def _read_group_machine_table_name_ids(self, categories, domain, order): def _read_group_machine_table_name_ids(self, categories, domain, order):
machine_table_name_ids = categories._search([], order=order, access_rights_uid=SUPERUSER_ID) machine_table_name_ids = categories._search([], order=order, access_rights_uid=SUPERUSER_ID)
return categories.browse(machine_table_name_ids) return categories.browse(machine_table_name_ids)
machine_tool_code = fields.Char('机台号', readonly=True, related='functional_tool_assembly_id.machine_tool_code')
cutting_tool_code = fields.Char('刀位号', readonly=True, related='functional_tool_assembly_id.cutter_spacing_code')
# idle_time = fields.Char('闲置时长', readonly=False)
idle_time = fields.Char('闲置时长(h)', readonly=False)
alarm_value = fields.Char('报警值', readonly=False)
used_value = fields.Char('已使用值', readonly=False)
alarm_type = fields.Char('报警类型', readonly=False)
dispose_user = fields.Char('处理人', readonly=False)
alarm_time = fields.Char('报警时间', readonly=False)
dispose_time = fields.Char('处理时间', readonly=False)
dispose_func = fields.Char('处理方法/措施', readonly=False)
remark = fields.Char('备注', readonly=False)
@api.onchange('functional_cutting_tool_id') class StockMoveLine(models.Model):
def onchange_functional_cutting_tool_id(self): _inherit = 'stock.move.line'
print(self.functional_cutting_tool_id.name) _description = '功能刀具出入库记录'
functional_tool_name_id = fields.Many2one('sf.functional.tool.assembly', string='功能刀具名称')
functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', store=True,
group_expand='_read_group_functional_tool_type_id',
related='functional_tool_name_id.functional_tool_type_id')
diameter = fields.Integer(string='刀具直径(mm)', related='functional_tool_name_id.functional_tool_diameter')
knife_tip_r_angle = fields.Float(string='刀尖R角(mm)', related='functional_tool_name_id.knife_tip_r_angle')
install_tool_time = fields.Datetime("刀具组装时间")
@api.model
def _read_group_functional_tool_type_id(self, categories, domain, order):
names = categories._search([], order=order, access_rights_uid=SUPERUSER_ID)
return categories.browse(names)
class RealTimeDistributionOfFunctionalTools(models.Model): class RealTimeDistributionOfFunctionalTools(models.Model):
_name = 'sf.real.time.distribution.of.functional.tools' _name = 'sf.real.time.distribution.of.functional.tools'
_description = '功能刀具实时分布' _description = '功能刀具安全库存'
functional_cutting_tool_id = fields.Many2one('sf.functional.cutting.tool.entity', '功能刀具', readonly=True) functional_cutting_tool_id = fields.Many2one('sf.functional.cutting.tool.entity', '功能刀具', readonly=True)
mrs_cutting_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', readonly=True, mrs_cutting_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', readonly=True,
@@ -220,61 +195,59 @@ class RealTimeDistributionOfFunctionalTools(models.Model):
if record: if record:
record.mrs_cutting_tool_type_id = record.functional_cutting_tool_id.mrs_cutting_tool_type_id.id record.mrs_cutting_tool_type_id = record.functional_cutting_tool_id.mrs_cutting_tool_type_id.id
# code = fields.Char('编码', readonly=True, related='functional_cutting_tool_id.code') barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', readonly=True)
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', readonly=True, name = fields.Char('名称', invisible=True, readonly=True)
related='functional_cutting_tool_id.barcode_id') functional_tool_name_id = fields.Many2one('product.product', string='功能刀具名称', readonly=True)
name = fields.Char('名称', invisible=True, readonly=True, related='functional_cutting_tool_id.name')
functional_tool_name_id = fields.Many2one('product.product', string='功能刀具名称', readonly=True,
related='functional_cutting_tool_id.functional_tool_name_id')
# mrs_cutting_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', readonly=True,
# related='functional_cutting_tool_id.mrs_cutting_tool_type_id')
# 整体式刀具型号 # 整体式刀具型号
cutting_tool_integral_model_id = fields.Many2one('product.product', string='整体式刀具型号', readonly=True, cutting_tool_integral_model_id = fields.Many2one(
domain=[('cutting_tool_material_id', '=', '整体式刀具')], 'product.product', string='整体式刀具型号', readonly=True,
related='functional_cutting_tool_id.cutting_tool_integral_model_id') domain=[('cutting_tool_material_id', '=', '整体式刀具')],
related='functional_cutting_tool_id.cutting_tool_integral_model_id')
# 刀片型号 # 刀片型号
cutting_tool_blade_model_id = fields.Many2one('product.product', string='刀片型号', readonly=True, cutting_tool_blade_model_id = fields.Many2one(
domain=[('cutting_tool_material_id', '=', '刀片')], 'product.product', string='刀片型号', readonly=True,
related='functional_cutting_tool_id.cutting_tool_blade_model_id') domain=[('cutting_tool_material_id', '=', '刀片')],
related='functional_cutting_tool_id.cutting_tool_blade_model_id')
# 刀杆型号 # 刀杆型号
cutting_tool_cutterbar_model_id = fields.Many2one('product.product', string='刀杆型号', readonly=True, cutting_tool_cutterbar_model_id = fields.Many2one(
domain=[('cutting_tool_material_id', '=', '刀杆')], 'product.product', string='刀杆型号', readonly=True,
related='functional_cutting_tool_id.cutting_tool_cutterbar_model_id') domain=[('cutting_tool_material_id', '=', '刀杆')],
related='functional_cutting_tool_id.cutting_tool_cutterbar_model_id')
# 刀盘型号 # 刀盘型号
cutting_tool_cutterpad_model_id = fields.Many2one('product.product', string='刀盘型号', readonly=True, cutting_tool_cutterpad_model_id = fields.Many2one(
domain=[('cutting_tool_material_id', '=', '刀盘')], 'product.product', string='刀盘型号', readonly=True,
related='functional_cutting_tool_id.cutting_tool_cutterpad_model_id') domain=[('cutting_tool_material_id', '=', '刀盘')],
related='functional_cutting_tool_id.cutting_tool_cutterpad_model_id')
# 刀柄型号 # 刀柄型号
cutting_tool_cutterhandle_model_id = fields.Many2one('product.product', string='刀柄型号', readonly=True, cutting_tool_cutterhandle_model_id = fields.Many2one(
domain=[('cutting_tool_material_id', '=', '刀柄')], 'product.product', string='刀柄型号', readonly=True,
related='functional_cutting_tool_id.cutting_tool_cutterhandle_model_id') domain=[('cutting_tool_material_id', '=', '刀柄')],
related='functional_cutting_tool_id.cutting_tool_cutterhandle_model_id')
# 夹头型号 # 夹头型号
cutting_tool_cutterhead_model_id = fields.Many2one('product.product', string='夹头型号', readonly=True, cutting_tool_cutterhead_model_id = fields.Many2one(
domain=[('cutting_tool_material_id', '=', '夹头')], 'product.product', string='夹头型号', readonly=True,
related='functional_cutting_tool_id.cutting_tool_cutterhead_model_id') domain=[('cutting_tool_material_id', '=', '夹头')],
related='functional_cutting_tool_id.cutting_tool_cutterhead_model_id')
diameter = fields.Float('直径(mm)', readonly=True, related='functional_cutting_tool_id.diameter') diameter = fields.Float('直径(mm)', readonly=True)
tool_grade = fields.Selection([('1', 'P1'), ('2', 'P2'), ('3', 'P3'), ('4', 'P4'), ('5', 'P5'), ('6', 'P6')], tool_grade = fields.Selection([('1', 'P1'), ('2', 'P2'), ('3', 'P3'), ('4', 'P4'), ('5', 'P5'), ('6', 'P6')],
string='刀具等级', readonly=True, compute='_compute_functional_cutting_tool_id') string='刀具等级', readonly=True)
machining_accuracy = fields.Float('加工精度(mm)', readonly=True, machining_accuracy = fields.Float('加工精度(mm)', readonly=True)
related='functional_cutting_tool_id.machining_accuracy') tool_length = fields.Float('装刀长(mm)', readonly=True)
tool_length = fields.Float('装刀长(mm)', readonly=True, related='functional_cutting_tool_id.tool_length') blade_number = fields.Integer('刃数', readonly=True)
blade_number = fields.Integer('刃数', readonly=True, related='functional_cutting_tool_id.blade_number') integral_blade_length = fields.Float('整体刃长(mm)', readonly=True)
integral_blade_length = fields.Float('整体刃长(mm)', readonly=True, effective_blade_length = fields.Float('有效刃长(mm)', readonly=True)
related='functional_cutting_tool_id.integral_blade_length') max_life = fields.Float('最大寿命值', readonly=True)
effective_blade_length = fields.Float('有效刃长(mm)', readonly=True,
related='functional_cutting_tool_id.effective_blade_length')
max_life = fields.Float('最大寿命值', readonly=True, related='functional_cutting_tool_id.max_life')
is_standard = fields.Selection([('1', ''), ('0', '')], '是否标准刀', readonly=True, is_standard = fields.Selection([('1', ''), ('0', '')], '是否标准刀', readonly=True,
compute='_compute_functional_cutting_tool_id') compute='_compute_functional_cutting_tool_id')
applicable_range = fields.Char('适用范围', readonly=True, related='functional_cutting_tool_id.applicable_range') applicable_range = fields.Char('适用范围', readonly=True)
image = fields.Binary('图片', readonly=True, related='functional_cutting_tool_id.image') image = fields.Binary('图片', readonly=True)
@api.depends('functional_cutting_tool_id') @api.depends('functional_cutting_tool_id')
def _compute_functional_cutting_tool_id(self): def _compute_functional_cutting_tool_id(self):
@@ -304,7 +277,8 @@ class RealTimeDistributionOfFunctionalTools(models.Model):
def _compute_return_total(self): def _compute_return_total(self):
for record in self: for record in self:
if record: if record:
self.return_total = record.return_reuse_num_re + record.return_reuse_num_co + record.return_processing_num self.return_total = (record.return_reuse_num_re + record.return_reuse_num_co +
record.return_processing_num)
@api.depends('tool_stock_total', 'return_total') @api.depends('tool_stock_total', 'return_total')
def _compute_total(self): def _compute_total(self):
@@ -313,233 +287,140 @@ class RealTimeDistributionOfFunctionalTools(models.Model):
self.total = record.tool_stock_total + record.return_total self.total = record.tool_stock_total + record.return_total
class InboundAndOutboundRecordsOfFunctionalTools(models.Model):
_name = 'sf.inbound.and.outbound.records.of.functional.tools'
_description = '功能刀具出入库记录'
functional_cutting_tool_id = fields.Many2one('sf.functional.cutting.tool.entity', '功能刀具', readonly=True)
mrs_cutting_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', readonly=True,
group_expand='_read_mrs_cutting_tool_type_ids',
store=True,
compute='_compute_functional_cutting_tool_ids')
@api.model
def _read_mrs_cutting_tool_type_ids(self, categories, domain, order):
mrs_cutting_tool_type_ids = categories._search([], order=order, access_rights_uid=SUPERUSER_ID)
return categories.browse(mrs_cutting_tool_type_ids)
@api.depends('functional_cutting_tool_id')
def _compute_functional_cutting_tool_ids(self):
for record in self:
if record:
record.mrs_cutting_tool_type_id = record.functional_cutting_tool_id.mrs_cutting_tool_type_id.id
# code = fields.Char('编码', readonly=True, related='functional_cutting_tool_id.code')
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', readonly=True,
related='functional_cutting_tool_id.barcode_id')
name = fields.Char('名称', invisible=True, readonly=True, related='functional_cutting_tool_id.name')
functional_tool_name_id = fields.Many2one('product.product', string='功能刀具名称', readonly=True,
related='functional_cutting_tool_id.functional_tool_name_id')
# 整体式刀具型号
cutting_tool_integral_model_id = fields.Many2one('product.product', string='整体式刀具型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '整体式刀具')],
related='functional_cutting_tool_id.cutting_tool_integral_model_id')
# 刀片型号
cutting_tool_blade_model_id = fields.Many2one('product.product', string='刀片型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '刀片')],
related='functional_cutting_tool_id.cutting_tool_blade_model_id')
# 刀杆型号
cutting_tool_cutterbar_model_id = fields.Many2one('product.product', string='刀杆型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '刀杆')],
related='functional_cutting_tool_id.cutting_tool_cutterbar_model_id')
# 刀盘型号
cutting_tool_cutterpad_model_id = fields.Many2one('product.product', string='刀盘型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '刀盘')],
related='functional_cutting_tool_id.cutting_tool_cutterpad_model_id')
# 刀柄型号
cutting_tool_cutterhandle_model_id = fields.Many2one('product.product', string='刀柄型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '刀柄')],
related='functional_cutting_tool_id.cutting_tool_cutterhandle_model_id')
# 夹头型号
cutting_tool_cutterhead_model_id = fields.Many2one('product.product', string='夹头型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '夹头')],
related='functional_cutting_tool_id.cutting_tool_cutterhead_model_id')
diameter = fields.Float('直径(mm)', readonly=True, related='functional_cutting_tool_id.diameter')
tool_grade = fields.Selection([('1', 'P1'), ('2', 'P2'), ('3', 'P3'), ('4', 'P4'), ('5', 'P5'), ('6', 'P6')],
string='刀具等级', readonly=True, compute='_compute_functional_cutting_tool_id')
machining_accuracy = fields.Float('加工精度(mm)', readonly=True,
related='functional_cutting_tool_id.machining_accuracy')
tool_length = fields.Float('装刀长(mm)', readonly=True, related='functional_cutting_tool_id.tool_length')
blade_number = fields.Integer('刃数', readonly=True, related='functional_cutting_tool_id.blade_number')
integral_blade_length = fields.Float('整体刃长(mm)', readonly=True,
related='functional_cutting_tool_id.integral_blade_length')
effective_blade_length = fields.Float('有效刃长(mm)', readonly=True,
related='functional_cutting_tool_id.effective_blade_length')
max_life = fields.Float('最大寿命值', readonly=True, related='functional_cutting_tool_id.max_life')
is_standard = fields.Selection([('1', ''), ('0', '')], '是否标准刀', readonly=True,
compute='_compute_functional_cutting_tool_id')
applicable_range = fields.Char('适用范围', readonly=True, related='functional_cutting_tool_id.applicable_range')
image = fields.Binary('图片', readonly=True, related='functional_cutting_tool_id.image')
@api.depends('functional_cutting_tool_id')
def _compute_functional_cutting_tool_id(self):
if self.functional_cutting_tool_id:
self.tool_grade = self.functional_cutting_tool_id.tool_grade
self.is_standard = self.functional_cutting_tool_id.is_standard
# 功能刀具出入库记录 特有字段
current_state = fields.Char(string='当前状态', readonly=False)
current_store_area = fields.Char(string='当前库区', readonly=False)
current_store_place = fields.Char(string='当前库位', readonly=False)
tool_install_staff = fields.Char(string='装刀人', readonly=False)
tool_install_time = fields.Datetime(string='装刀时间', readonly=False)
thickness = fields.Selection([('1', ''), ('2', ''), ('3', '')], string='粗/中/精', readonly=False)
# max_life_span = fields.Char(string='最大寿命值', readonly=False)
alarm_value = fields.Char(string='报警值', readonly=False)
used_value = fields.Char(string='已使用值', readonly=False)
reason_application = fields.Char(string='申请原因', readonly=False)
applicant = fields.Char(string='申请人', readonly=False)
inbound_and_outbound_records_ids = fields.One2many('sf.inbound.and.outbound.records',
'inbound_and_outbound_tools_id', string='出入库记录')
remark = fields.Char(string='备注/说明', readonly=False)
class InboundAndOutboundRecords(models.Model):
_name = 'sf.inbound.and.outbound.records'
_description = '出入库记录'
_order = 'id DESC'
inbound_and_outbound_tools_id = fields.Many2one('sf.inbound.and.outbound.records.of.functional.tools',
string='功能刀具出入库记录')
name = fields.Char(string='出入库记录')
tool_state = fields.Selection([('0', '领用出库'), ('1', '归还入库')], string="出入库类别", readonly=False)
receive_equipment = fields.Char(string='领用机台', readonly=False)
receive_staff = fields.Char(string='领用人', readonly=False)
receive_time = fields.Datetime(string='领用出库时间', readonly=False)
return_staff = fields.Char(string='归还人', readonly=False)
return_time = fields.Datetime(string='归还入库时间', readonly=False)
current_store_area = fields.Char(string='库区', readonly=False)
current_store_place = fields.Char(string='库位', readonly=False)
number = fields.Integer(string='数量', readonly=False)
class MachineTableToolChangingApply(models.Model): class MachineTableToolChangingApply(models.Model):
_name = 'sf.machine.table.tool.changing.apply' _name = 'sf.machine.table.tool.changing.apply'
_description = '机床换刀申请' _description = '机床换刀申请'
_order = 'cutter_spacing_code_id'
name = fields.Many2one('maintenance.equipment', string='CNC机床', required=True, readonly=False, name = fields.Char('名称', related='maintenance_equipment_id.name', store=True)
group_expand='_read_group_names') maintenance_equipment_id = fields.Many2one('maintenance.equipment', string='CNC机床', required=True, readonly=False,
domain=[('category_id.equipment_type', '=', '机床')])
production_line_id = fields.Many2one('sf.production.line', string='生产线', readonly=True,
group_expand='_read_group_names')
machine_table_type_id = fields.Many2one('maintenance.equipment.category', string='机床类型', readonly=True, machine_table_type_id = fields.Many2one('maintenance.equipment.category', string='机床类型', readonly=True,
compute='_compute_machine_table_type_id') compute='_compute_machine_table_type_id')
machine_tool_code = fields.Char(string='机台号', store=True, invisible=True, readonly=True) machine_tool_code = fields.Char(string='机台号', store=True, invisible=True, readonly=True)
cutter_spacing_code = fields.Char(string='刀位号', readonly=False, required=True) cutter_spacing_code_id = fields.Many2one('maintenance.equipment.tool', string='刀位号', readonly=False,
required=True, domain="[('equipment_id', '=', maintenance_equipment_id)]")
functional_tool_name = fields.Char(string='刀具名称', related='functional_tool_name_id.name', store=True)
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', store=True,
domain=[('product_id.name', '=', '功能刀具')],
related='functional_tool_name_id.barcode_id')
functional_tool_name_id = fields.Many2one('sf.functional.tool.assembly', string='功能刀具名称')
functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', store=True,
related='functional_tool_name_id.functional_tool_type_id')
@api.depends('name') tool_position_interface_type = fields.Selection(
def _compute_machine_table_type_id(self): [('BT刀柄式', 'BT刀柄式'), ('SK刀柄式', 'SK刀柄式'), ('HSK刀柄式', 'HSK刀柄式'),
for record in self: ('CAT刀柄式', 'CAT刀柄式'), ('ISO刀盘式', 'ISO刀盘式'), ('DIN刀盘式', 'DIN刀盘式'),
if record: ('直装固定式', '直装固定式')], string='刀位接口型号', required=True)
record.machine_table_type_id = record.name.category_id.id diameter = fields.Integer(string='刀具直径(mm)', )
record.machine_tool_code = record.name.code knife_tip_r_angle = fields.Float(string='刀尖R角(mm)')
else: max_lifetime_value = fields.Integer(string='最大寿命值(min)')
record.machine_table_type_id = None alarm_value = fields.Integer(string='报警值(min)')
record.machine_tool_code = None used_value = fields.Integer(string='已使用值(min)')
whether_standard_knife = fields.Boolean(string='是否标准刀', default=True)
extension_length = fields.Float(string='伸出长(mm)')
effective_length = fields.Float(string='有效长(mm)')
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', functional_tool_status = fields.Selection([('正常', '正常'), ('报警', '报警')], string='功能刀具状态', store=True,
domain=[('product_id.name', '=', '功能刀具')]) default='正常', compute='_compute_functional_tool_status')
functional_tool_name_id = fields.Many2one('product.product', string='功能刀具名称',
domain=[('name', '=', '功能刀具')])
functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型')
diameter = fields.Char(string='直径(mm)', readonly=False)
coarse_middle_thin = fields.Selection([("1", ""), ('2', ''), ('3', '')], string='粗/中/精', readonly=False)
hilt_name = fields.Char(string='刀柄名称', readonly=False)
hilt_code = fields.Char(string='刀柄编号', readonly=False)
max_lifetime_value = fields.Char(string='最大寿命值', readonly=False)
alarm_value = fields.Char(string='报警值', readonly=False)
used_value = fields.Char(string='已使用值', readonly=False)
functional_tool_status = fields.Selection([('正常', '正常'), ('异常', '异常')], string='功能刀具状态',
default='正常', readonly=False)
# replacement_tool_code = fields.Char(string='待换功能刀具编码', readonly=True)
assembly_order_code = fields.Char(string='组装单编码', readonly=True) assembly_order_code = fields.Char(string='组装单编码', readonly=True)
replacement_tool_name_id = fields.Many2one('product.product', string='待换功能刀具名称', readonly=True)
replacement_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='待换功能刀具类型',
readonly=True)
replacement_tool_coarse_middle_thin = fields.Selection([("1", ""), ('2', ''), ('3', '')],
string='粗/中/精(待换)', readonly=True)
new_former = fields.Selection([('0', ''), ('1', '')], string='新/旧', readonly=True)
applicant = fields.Char(string='申请人', readonly=True) applicant = fields.Char(string='申请人', readonly=True)
used_tool_time = fields.Datetime(string='用刀时间', readonly=True)
reason_for_applying = fields.Char(string='申请原因', readonly=True) reason_for_applying = fields.Char(string='申请原因', readonly=True)
remark = fields.Char(string='备注说明', readonly=False) remark = fields.Char(string='备注说明', readonly=False)
status = fields.Selection([('0', '未操作'), ('1', '已换刀申请'), ('2', '已转移'), ('3', '已组装')], string='操作状态', default='0') status = fields.Selection([('0', '未操作'), ('1', '已换刀申请'), ('2', '已转移'), ('3', '已组装')],
string='操作状态', default='0')
sf_functional_tool_assembly_id = fields.Many2one('sf.functional.tool.assembly', '功能刀具组装', readonly=True) sf_functional_tool_assembly_id = fields.Many2one('sf.functional.tool.assembly', '功能刀具组装', readonly=True)
@api.depends('alarm_value', 'used_value')
def _compute_functional_tool_status(self):
for record in self:
if record.alarm_value <= record.used_value:
record.functional_tool_status = '报警'
else:
record.functional_tool_status = '正常'
@api.depends('maintenance_equipment_id')
def _compute_machine_table_type_id(self):
for record in self:
if record:
record.production_line_id = record.maintenance_equipment_id.production_line_id.id
record.machine_table_type_id = record.maintenance_equipment_id.category_id.id
record.machine_tool_code = record.maintenance_equipment_id.code
else:
record.production_line_id = None
record.machine_table_type_id = None
record.machine_tool_code = None
@api.constrains("cutter_spacing_code_id")
def _check_cutter_spacing_code_id(self):
for obj in self:
records = self.env['sf.machine.table.tool.changing.apply'].search([
('maintenance_equipment_id', '=', obj.maintenance_equipment_id.id),
('cutter_spacing_code_id', '=', obj.cutter_spacing_code_id.id)])
if len(records) > 1:
raise ValidationError('该刀位号已存在,请重新选择!!!')
@api.model @api.model
def _read_group_names(self, categories, domain, order): def _read_group_names(self, categories, domain, order):
names = categories._search([], order=order, access_rights_uid=SUPERUSER_ID) names = categories._search([], order=order, access_rights_uid=SUPERUSER_ID)
return categories.browse(names) return categories.browse(names)
@api.onchange('functional_tool_status') @api.constrains('functional_tool_status')
def automation_apply_for_tool_change(self): def automation_apply_for_tool_change(self):
""" """
自动申请换刀 自动申请换刀
:return: :return:
""" """
# 更新数据到机台换刀申请界面 # 更新数据到机台换刀申请界面
# todo 自动换刀申请条件需补充完善 if self.functional_tool_status == '报警' and not self.sf_functional_tool_assembly_id:
if self.functional_tool_status == '异常': machine_table_tool_changing_apply = self.env['sf.machine.table.tool.changing.apply'].search(
self.env['sf.machine.table.tool.changing.apply'].search([ [('maintenance_equipment_id', '=', self.maintenance_equipment_id.id),
('name', '=', self.name.id)]).write({ ('cutter_spacing_code_id', '=', self.cutter_spacing_code_id.id)
'replacement_tool_name_id': self.functional_tool_name_id.id, ])
'replacement_tool_type_id': self.functional_tool_type_id.id,
'replacement_tool_coarse_middle_thin': self.coarse_middle_thin,
'new_former': '0',
'applicant': '自动申请',
'used_tool_time': fields.Datetime.now(),
'reason_for_applying': '功能刀具状态异常',
'remark': None,
'status': '1'
})
# 新建组装任务 # 新建组装任务
self.env['sf.functional.tool.assembly'].create({ sf_functional_tool_assembly = self.env['sf.functional.tool.assembly'].create({
'name': self.functional_tool_name_id, 'functional_tool_name': self.functional_tool_name,
'functional_tool_type_id': self.functional_tool_type_id.id, 'functional_tool_type_id': self.functional_tool_type_id.id,
'functional_tool_diameter': self.diameter, 'functional_tool_diameter': self.diameter,
'knife_tip_r_angle': self.knife_tip_r_angle,
'coarse_middle_thin': '3',
'new_former': '0',
'functional_tool_length': self.extension_length,
'effective_length': self.effective_length,
'loading_task_source': '1', 'loading_task_source': '1',
'applicant': '自动申请', 'use_tool_time': fields.Datetime.now() + timedelta(hours=4),
'reason_for_applying': '功能刀具状态异常', 'production_line_name_id': self.production_line_id.id,
'use_tool_time': self.used_tool_time, 'machine_tool_name_id': self.maintenance_equipment_id.id,
'machine_tool_name': self.CNC_machine_table, 'applicant': self.applicant,
'machine_tool_code': self.machine_tool_code, 'apply_time': fields.Datetime.now(),
'cutter_spacing_code': self.cutter_spacing_code, 'cutter_spacing_code_id': self.cutter_spacing_code_id.id,
'whether_standard_knife': self.whether_standard_knife,
'reason_for_applying': '机台报警自动换刀',
'sf_machine_table_tool_changing_apply_id': self.id
}) })
def new_assembly_task(self, vals): machine_table_tool_changing_apply.write(
""" {'status': '1',
新建组装任务 'sf_functional_tool_assembly_id': sf_functional_tool_assembly})
:param vals:
:return:
"""
# 增加设置直径的值
tool_changing_apply = self.env['sf.machine.table.tool.changing.apply'].search(
[('name', '=', vals['name'])])
vals['functional_tool_diameter'] = tool_changing_apply.diameter
self.env['sf.functional.tool.assembly'].create(vals) # def new_assembly_task(self, vals):
# """
# 新建组装任务
# :param vals:
# :return:
# """
# # 增加设置直径的值
# tool_changing_apply = self.env['sf.machine.table.tool.changing.apply'].search(
# [('name', '=', vals['name'])])
# vals['functional_tool_diameter'] = tool_changing_apply.diameter
#
# self.env['sf.functional.tool.assembly'].create(vals)
def revocation_1(self): def revocation_1(self):
""" """
@@ -548,22 +429,16 @@ class MachineTableToolChangingApply(models.Model):
""" """
# 撤回功能刀具组装创建的任务 # 撤回功能刀具组装创建的任务
self.env['sf.functional.tool.assembly'].search( self.env['sf.functional.tool.assembly'].search(
[('assembly_order_code', '=', self.assembly_order_code), [('id', '=', self.sf_functional_tool_assembly_id.id),
('loading_task_source', '=', '1')]).unlink() ('loading_task_source', '=', '1')]).unlink()
# 撤回数据更新 # 撤回数据更新
self.env['sf.machine.table.tool.changing.apply'].search([('name', '=', self.name.id)]).write({ self.env['sf.machine.table.tool.changing.apply'].search(
'replacement_tool_name_id': None, [('maintenance_equipment_id', '=', self.maintenance_equipment_id.id),
'replacement_tool_type_id': None, ('cutter_spacing_code_id', '=', self.cutter_spacing_code_id.id)]).write(
'replacement_tool_coarse_middle_thin': None, {'status': '0',
'new_former': None, 'sf_functional_tool_assembly_id': None
'applicant': None, })
'used_tool_time': None,
'reason_for_applying': None,
'remark': None,
'status': '0',
'sf_functional_tool_assembly_id': None,
})
def revocation_2(self): def revocation_2(self):
""" """
@@ -571,9 +446,7 @@ class MachineTableToolChangingApply(models.Model):
:return: :return:
""" """
self.env['sf.machine.table.tool.changing.apply'].search( self.env['sf.machine.table.tool.changing.apply'].search(
[('name', '=', self.name.id)]).write({ [('name', '=', self.name.id)]).write({'status': '0'})
'status': '0'
})
class CAMWorkOrderProgramKnifePlan(models.Model): class CAMWorkOrderProgramKnifePlan(models.Model):
@@ -642,9 +515,9 @@ class CAMWorkOrderProgramKnifePlan(models.Model):
# 将计划执行状态改为执行中 # 将计划执行状态改为执行中
self.env['sf.cam.work.order.program.knife.plan'].search( self.env['sf.cam.work.order.program.knife.plan'].search(
[('barcode_id', '=', self.barcode_id.id)]).write({ [('barcode_id', '=', self.barcode_id.id)]).write(
'plan_execute_status': '1', {'plan_execute_status': '1',
'applicant': self.env.user.name}) 'applicant': self.env.user.name})
def revocation(self): def revocation(self):
""" """
@@ -657,11 +530,10 @@ class CAMWorkOrderProgramKnifePlan(models.Model):
# 将计划执行状态改为待执行,同时清除申请人、功能刀具组装字段数据 # 将计划执行状态改为待执行,同时清除申请人、功能刀具组装字段数据
self.env['sf.cam.work.order.program.knife.plan'].search( self.env['sf.cam.work.order.program.knife.plan'].search(
[('barcode_id', '=', self.barcode_id.id)]).write({ [('barcode_id', '=', self.barcode_id.id)]).write(
'plan_execute_status': '0', {'plan_execute_status': '0',
'applicant': None, 'applicant': None,
'sf_functional_tool_assembly_id': None, 'sf_functional_tool_assembly_id': None})
})
class FunctionalToolAssembly(models.Model): class FunctionalToolAssembly(models.Model):
@@ -669,12 +541,41 @@ class FunctionalToolAssembly(models.Model):
_description = '功能刀具组装单' _description = '功能刀具组装单'
_order = 'use_tool_time asc' _order = 'use_tool_time asc'
@api.depends('functional_tool_name')
def _compute_name(self):
for obj in self:
obj.name = obj.after_assembly_functional_tool_name
name = fields.Char(string='名称', readonly=True, compute='_compute_name')
assembly_order_code = fields.Char(string='编码', readonly=True) assembly_order_code = fields.Char(string='编码', readonly=True)
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', readonly=True)
functional_tool_name_id = fields.Many2one('product.product', string='功能刀具名称', readonly=True) functional_tool_name_id = fields.Many2one('product.product', string='功能刀具', readonly=True)
name = fields.Char(string='名称', readonly=True) functional_tool_name = fields.Char(string='功能刀具名称', readonly=True)
functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', readonly=True, functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', readonly=True,
group_expand='_read_group_functional_tool_type_ids') group_expand='_read_group_functional_tool_type_ids')
functional_tool_diameter = fields.Integer(string='功能刀具直径(mm)', readonly=True)
knife_tip_r_angle = fields.Float(string='刀尖R角(mm)', readonly=True)
coarse_middle_thin = fields.Selection([("1", ""), ('2', ''), ('3', '')], string='粗/中/精', readonly=True)
new_former = fields.Selection([('0', ''), ('1', '')], string='新/旧', readonly=True)
tool_loading_length = fields.Float(string='装刀长(mm)', readonly=True)
functional_tool_length = fields.Float(string='伸出长(mm)', readonly=True)
effective_length = fields.Float(string='有效长(mm)', readonly=True)
loading_task_source = fields.Selection([('0', 'CAM装刀'), ('1', '机台换刀'), ('2', '按库存组装')],
string='装刀任务来源', readonly=True)
use_tool_time = fields.Datetime(string='用刀时间', readonly=True)
production_line_name_id = fields.Many2one('sf.production.line', string='申请产线', readonly=True)
machine_tool_name_id = fields.Many2one('maintenance.equipment', string='申请机台', readonly=True)
machine_tool_code = fields.Char(string='机台号', readonly=True)
applicant = fields.Char(string='申请人', readonly=True)
apply_time = fields.Datetime(string='申请时间', default=fields.Datetime.now(), readonly=True)
assemble_status = fields.Selection([('0', '待组装'), ('1', '已组装')], string='组装状态', default='0',
readonly=True)
cutter_spacing_code_id = fields.Many2one('maintenance.equipment.tool', string='刀位号', readonly=True)
whether_standard_knife = fields.Boolean(string='是否标准刀', default=True, readonly=True)
reason_for_applying = fields.Char(string='申请原因', readonly=True)
max_lifetime_value = fields.Integer(string='最大寿命值(min)', readonly=True)
alarm_value = fields.Integer(string='报警值(min)', readonly=True)
used_value = fields.Integer(string='已使用值(min)', readonly=True)
@api.model @api.model
def _read_group_functional_tool_type_ids(self, categories, domain, order): def _read_group_functional_tool_type_ids(self, categories, domain, order):
@@ -682,43 +583,40 @@ class FunctionalToolAssembly(models.Model):
functional_tool_type_ids = categories._search([], order=order, access_rights_uid=SUPERUSER_ID) functional_tool_type_ids = categories._search([], order=order, access_rights_uid=SUPERUSER_ID)
return categories.browse(functional_tool_type_ids) return categories.browse(functional_tool_type_ids)
functional_tool_diameter = fields.Char(string='功能刀具直径(mm)', readonly=True) # 刀具物料信息
functional_tool_length = fields.Char(string='功能刀具伸出长(mm)', readonly=True)
functional_tool_cutting_type = fields.Char(string='功能刀具切削类型', readonly=False)
# 整体式刀具型号 # 整体式刀具型号
integral_code_id = fields.Many2one('stock.lot', string='整体式刀具序列号', readonly=True) integral_code_id = fields.Many2one('stock.lot', string='整体式刀具序列号', readonly=True)
cutting_tool_integral_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='整体式刀具型号', readonly=True) cutting_tool_integral_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='整体式刀具型号',
readonly=True)
integral_name = fields.Char('整体式刀具名称', readonly=True, compute='_compute_auto_fill') integral_name = fields.Char('整体式刀具名称', readonly=True, compute='_compute_auto_fill')
sf_tool_brand_id_1 = fields.Many2one('sf.machine.brand', string='整体式刀具品牌', readonly=True) sf_tool_brand_id_1 = fields.Many2one('sf.machine.brand', string='整体式刀具品牌', readonly=True)
# 刀片型号 # 刀片型号
blade_code_id = fields.Many2one('stock.lot', '刀片序列号', readonly=True) blade_code_id = fields.Many2one('stock.lot', '刀片序列号', readonly=True)
cutting_tool_blade_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀片型号', readonly=True) cutting_tool_blade_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀片型号', readonly=True)
blade_name = fields.Char('刀片名称', readonly=True, compute='_compute_auto_fill') blade_name = fields.Char('刀片名称', readonly=True, compute='_compute_auto_fill')
sf_tool_brand_id_2 = fields.Many2one('sf.machine.brand', '刀片品牌', readonly=True) sf_tool_brand_id_2 = fields.Many2one('sf.machine.brand', '刀片品牌', readonly=True)
# 刀杆型号 # 刀杆型号
bar_code_id = fields.Many2one('stock.lot', '刀杆序列号', readonly=True) bar_code_id = fields.Many2one('stock.lot', '刀杆序列号', readonly=True)
cutting_tool_cutterbar_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀杆型号', readonly=True) cutting_tool_cutterbar_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀杆型号',
readonly=True)
bar_name = fields.Char('刀杆名称', readonly=True, compute='_compute_auto_fill') bar_name = fields.Char('刀杆名称', readonly=True, compute='_compute_auto_fill')
sf_tool_brand_id_3 = fields.Many2one('sf.machine.brand', '刀杆品牌', readonly=True) sf_tool_brand_id_3 = fields.Many2one('sf.machine.brand', '刀杆品牌', readonly=True)
# 刀盘型号 # 刀盘型号
pad_code_id = fields.Many2one('stock.lot', '刀盘序列号', readonly=True) pad_code_id = fields.Many2one('stock.lot', '刀盘序列号', readonly=True)
cutting_tool_cutterpad_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀盘型号', readonly=True) cutting_tool_cutterpad_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀盘型号',
readonly=True)
pad_name = fields.Char('刀盘名称', readonly=True, compute='_compute_auto_fill') pad_name = fields.Char('刀盘名称', readonly=True, compute='_compute_auto_fill')
sf_tool_brand_id_4 = fields.Many2one('sf.machine.brand', '刀盘品牌', readonly=True) sf_tool_brand_id_4 = fields.Many2one('sf.machine.brand', '刀盘品牌', readonly=True)
# 刀柄型号 # 刀柄型号
handle_code_id = fields.Many2one('stock.lot', '刀柄序列号', readonly=True) handle_code_id = fields.Many2one('stock.lot', '刀柄序列号', readonly=True)
cutting_tool_cutterhandle_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀柄型号', readonly=True) cutting_tool_cutterhandle_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀柄型号',
readonly=True)
handle_name = fields.Char('刀柄名称', readonly=True, compute='_compute_auto_fill') handle_name = fields.Char('刀柄名称', readonly=True, compute='_compute_auto_fill')
sf_tool_brand_id_5 = fields.Many2one('sf.machine.brand', '刀柄品牌', readonly=True) sf_tool_brand_id_5 = fields.Many2one('sf.machine.brand', '刀柄品牌', readonly=True)
# 夹头型号 # 夹头型号
chuck_code_id = fields.Many2one('stock.lot', '夹头序列号', readonly=True) chuck_code_id = fields.Many2one('stock.lot', '夹头序列号', readonly=True)
cutting_tool_cutterhead_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='夹头型号', readonly=True) cutting_tool_cutterhead_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='夹头型号',
readonly=True)
chuck_name = fields.Char('夹头名称', readonly=True, compute='_compute_auto_fill') chuck_name = fields.Char('夹头名称', readonly=True, compute='_compute_auto_fill')
sf_tool_brand_id_6 = fields.Many2one('sf.machine.brand', '夹头品牌', readonly=True) sf_tool_brand_id_6 = fields.Many2one('sf.machine.brand', '夹头品牌', readonly=True)
@@ -775,35 +673,38 @@ class FunctionalToolAssembly(models.Model):
record.chuck_name = None record.chuck_name = None
record.sf_tool_brand_id_6 = None record.sf_tool_brand_id_6 = None
coarse_middle_thin = fields.Selection([("1", ""), ('2', ''), ('3', '')], string='粗/中/精', readonly=True) # 组装功能刀具参数信息
tool_loading_length = fields.Char(string='装刀长(mm)', readonly=True) barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', readonly=True)
new_former = fields.Selection([('0', ''), ('1', '')], string='新/旧', readonly=True) after_assembly_functional_tool_name = fields.Char(string='组装后功能刀具名称', readonly=True)
reference_length = fields.Char(string='参考伸出长(mm)', readonly=True) after_assembly_functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model',
cut_time = fields.Char(string='已切削时间', readonly=True) string='组装后功能刀具类型', readonly=True)
cut_length = fields.Char(string='已切削长度(mm)', readonly=True) after_assembly_functional_tool_diameter = fields.Integer(string='组装后功能刀具直径(mm)', readonly=True)
cut_number = fields.Char(string='已切削次数', readonly=True) after_assembly_knife_tip_r_angle = fields.Float(string='组装后刀尖R角(mm)', readonly=True)
after_assembly_new_former = fields.Selection([('0', ''), ('1', '')], string='组装后新/旧', readonly=True)
cut_time = fields.Integer(string='已切削时间(min)', readonly=True)
cut_length = fields.Float(string='已切削长度(mm)', readonly=True)
cut_number = fields.Integer(string='已切削次数', readonly=True)
loading_task_source = fields.Selection([('0', 'CAM装'), ('1', '机台换刀'), ('2', '按库存组装')], after_assembly_whether_standard_knife = fields.Boolean(string='组装后是否标准', default=True, readonly=True)
string='装刀任务来源', readonly=True) after_assembly_coarse_middle_thin = fields.Selection([("1", ""), ('2', ''), ('3', '')],
applicant = fields.Char(string='申请人', readonly=True) string='组装后粗/中/精', readonly=True)
reason_for_applying = fields.Char(string='申请原因', readonly=True) after_assembly_max_lifetime_value = fields.Integer(string='组装后最大寿命值(min)', readonly=True)
apply_time = fields.Datetime(string='申请时间', default=fields.Datetime.now(), readonly=True) after_assembly_alarm_value = fields.Integer(string='组装后报警值(min)', readonly=True)
assemble_status = fields.Selection([('0', '待组装'), ('1', '已组装')], string='组装状态', after_assembly_used_value = fields.Integer(string='组装后已使用值(min)', readonly=True)
default='0', readonly=True) after_assembly_tool_loading_length = fields.Float(string='组装后装刀长(mm)', readonly=True)
use_tool_time = fields.Datetime(string='用刀时间', readonly=True) after_assembly_functional_tool_length = fields.Float(string='组装后伸出长(mm)', readonly=True)
production_line_name_id = fields.Many2one('sf.production.line', string='产线名称', readonly=False) after_assembly_effective_length = fields.Float(string='组装后有效长(mm)', readonly=True)
machine_tool_name_id = fields.Many2one('maintenance.equipment', string='机床名称', readonly=True) L_D_number = fields.Float(string='L/D值(mm)', readonly=True)
machine_tool_code = fields.Char(string='机台号', readonly=True) hiding_length = fields.Float(string='避空长(mm)', readonly=True)
cutter_spacing_code = fields.Char(string='刀位号', readonly=True)
functional_tool_cutting_type = fields.Char(string='功能刀具切削类型', readonly=False)
tool_loading_person = fields.Char(string='装刀人', readonly=True) tool_loading_person = fields.Char(string='装刀人', readonly=True)
tool_loading_time = fields.Datetime(string='装刀时间', readonly=True) tool_loading_time = fields.Datetime(string='装刀时间', readonly=True)
receive_person = fields.Char(string='领用人', readonly=True)
receive_time = fields.Datetime(string='领用出库时间', readonly=True)
remark = fields.Char(string='备注说明', readonly=True) remark = fields.Char(string='备注说明', readonly=True)
check_box_1 = fields.Boolean(string='复选框', default=False, readonly=False) check_box_1 = fields.Boolean(string='复选框', default=False, readonly=False)
sf_machine_table_tool_changing_apply_id = fields.Many2one('sf.machine.table.tool.changing.apply', '机床换刀申请', readonly=True) sf_machine_table_tool_changing_apply_id = fields.Many2one('sf.machine.table.tool.changing.apply', '机床换刀申请',
readonly=True)
sf_cam_work_order_program_knife_plan_id = fields.Many2one('sf.cam.work.order.program.knife.plan', sf_cam_work_order_program_knife_plan_id = fields.Many2one('sf.cam.work.order.program.knife.plan',
'CAM工单程序用刀计划', readonly=True, ) 'CAM工单程序用刀计划', readonly=True, )
@@ -855,5 +756,4 @@ class FunctionalToolAssembly(models.Model):
if obj.loading_task_source: if obj.loading_task_source:
code = self._get_code(obj.loading_task_source) code = self._get_code(obj.loading_task_source)
obj.assembly_order_code = code obj.assembly_order_code = code
obj.name = code return obj
return obj

View File

@@ -2,8 +2,6 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_sf_functional_cutting_tool_entity,sf.functional.cutting.tool.entity,model_sf_functional_cutting_tool_entity,base.group_user,1,1,1,1 access_sf_functional_cutting_tool_entity,sf.functional.cutting.tool.entity,model_sf_functional_cutting_tool_entity,base.group_user,1,1,1,1
access_sf_functional_tool_warning,sf.functional.tool.warning,model_sf_functional_tool_warning,base.group_user,1,1,1,1 access_sf_functional_tool_warning,sf.functional.tool.warning,model_sf_functional_tool_warning,base.group_user,1,1,1,1
access_sf_real_time_distribution_of_functional_tools,sf.real.time.distribution.of.functional.tools,model_sf_real_time_distribution_of_functional_tools,base.group_user,1,1,1,1 access_sf_real_time_distribution_of_functional_tools,sf.real.time.distribution.of.functional.tools,model_sf_real_time_distribution_of_functional_tools,base.group_user,1,1,1,1
access_sf_inbound_and_outbound_records_of_functional_tools,sf.inbound.and.outbound.records.of.functional.tools,model_sf_inbound_and_outbound_records_of_functional_tools,base.group_user,1,1,1,1
access_sf_inbound_and_outbound_records,sf.inbound.and.outbound.records,model_sf_inbound_and_outbound_records,base.group_user,1,1,1,1
access_sf_cam_work_order_program_knife_plan,sf.cam.work.order.program.knife.plan,model_sf_cam_work_order_program_knife_plan,base.group_user,1,1,1,1 access_sf_cam_work_order_program_knife_plan,sf.cam.work.order.program.knife.plan,model_sf_cam_work_order_program_knife_plan,base.group_user,1,1,1,1
access_sf_machine_table_tool_changing_apply,sf.machine.table.tool.changing.apply,model_sf_machine_table_tool_changing_apply,base.group_user,1,1,1,1 access_sf_machine_table_tool_changing_apply,sf.machine.table.tool.changing.apply,model_sf_machine_table_tool_changing_apply,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_functional_cutting_tool_entity sf.functional.cutting.tool.entity model_sf_functional_cutting_tool_entity base.group_user 1 1 1 1
3 access_sf_functional_tool_warning sf.functional.tool.warning model_sf_functional_tool_warning base.group_user 1 1 1 1
4 access_sf_real_time_distribution_of_functional_tools sf.real.time.distribution.of.functional.tools model_sf_real_time_distribution_of_functional_tools base.group_user 1 1 1 1
access_sf_inbound_and_outbound_records_of_functional_tools sf.inbound.and.outbound.records.of.functional.tools model_sf_inbound_and_outbound_records_of_functional_tools base.group_user 1 1 1 1
access_sf_inbound_and_outbound_records sf.inbound.and.outbound.records model_sf_inbound_and_outbound_records base.group_user 1 1 1 1
5 access_sf_cam_work_order_program_knife_plan sf.cam.work.order.program.knife.plan model_sf_cam_work_order_program_knife_plan base.group_user 1 1 1 1
6 access_sf_machine_table_tool_changing_apply sf.machine.table.tool.changing.apply model_sf_machine_table_tool_changing_apply base.group_user 1 1 1 1
7 access_sf_tool_change_requirement_information sf.tool.change.requirement.information model_sf_tool_change_requirement_information base.group_user 1 1 1 1

View File

@@ -13,7 +13,7 @@
name="功能刀具列表" name="功能刀具列表"
sequence="4" sequence="4"
action="sf_function_tool_entry_list_view_act" action="sf_function_tool_entry_list_view_act"
/> />
<menuitem <menuitem
@@ -22,30 +22,30 @@
name="功能刀具预警" name="功能刀具预警"
sequence="5" sequence="5"
action="action_sf_functional_tool_warning" action="action_sf_functional_tool_warning"
/> />
<menuitem
sequence="6"
name="功能刀具实时分布"
id="menu_sf_functional_tool_real_time_distribution"
action="sf_real_time_distribution_of_functional_tools_view_act"
parent="menu_sf_tool_manage"
/>
<menuitem <menuitem
sequence="10" sequence="10"
name="功能刀具安全库存"
id="menu_sf_functional_tool_real_time_distribution"
action="sf_real_time_distribution_of_functional_tools_view_act"
parent="menu_sf_tool_manage"
/>
<menuitem
sequence="6"
name="功能刀具出入库记录" name="功能刀具出入库记录"
id="menu_sf_function_tool_entry_exit_records" id="menu_sf_function_tool_entry_exit_records"
action="sf_inbound_and_outbound_records_of_functional_tools_view_act" action="sf_inbound_and_outbound_records_of_functional_tools_view_act"
parent="menu_sf_tool_manage" parent="menu_sf_tool_manage"
/> />
<menuitem <menuitem
sequence="0" sequence="0"
name="功能刀具计划" name="功能刀具计划"
id="menu_sf_function_tool_plan" id="menu_sf_function_tool_plan"
parent="menu_sf_tool_manage" parent="menu_sf_tool_manage"
/> />
<menuitem <menuitem
sequence="10" sequence="10"
@@ -53,7 +53,7 @@
id="menu_sf_cam_work_order_program_knife_plan" id="menu_sf_cam_work_order_program_knife_plan"
action="sf_cam_work_order_program_knife_plan_view_act" action="sf_cam_work_order_program_knife_plan_view_act"
parent="menu_sf_function_tool_plan" parent="menu_sf_function_tool_plan"
/> />
<menuitem <menuitem
sequence="0" sequence="0"
@@ -61,7 +61,7 @@
id="menu_sf_machine_table_tool_changing_apply" id="menu_sf_machine_table_tool_changing_apply"
action="sf_machine_table_tool_changing_apply_view_act" action="sf_machine_table_tool_changing_apply_view_act"
parent="menu_sf_function_tool_plan" parent="menu_sf_function_tool_plan"
/> />
<menuitem <menuitem
sequence="2" sequence="2"
@@ -69,8 +69,7 @@
id="menu_sf_functional_tool_assembly" id="menu_sf_functional_tool_assembly"
action="sf_functional_tool_assembly_view_act" action="sf_functional_tool_assembly_view_act"
parent="menu_sf_tool_manage" parent="menu_sf_tool_manage"
/> />
</data> </data>
</odoo> </odoo>

File diff suppressed because it is too large Load Diff

View File

@@ -1 +1 @@
from . import wizard from . import wizard

View File

@@ -1,3 +1,5 @@
from datetime import timedelta
from odoo import fields, models, api from odoo import fields, models, api
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
@@ -6,75 +8,90 @@ class ToolChangeRequirementInformation(models.TransientModel):
_name = 'sf.tool.change.requirement.information' _name = 'sf.tool.change.requirement.information'
_description = '换刀需求信息' _description = '换刀需求信息'
# tool_change_to_apply_id = fields.Many2one('sf.machine.table.tool.changing.apply', string='机床换刀申请') name = fields.Char('名称', related='maintenance_equipment_id.name', store=True, readonly=True)
maintenance_equipment_id = fields.Many2one('maintenance.equipment', string='CNC机床', readonly=True)
production_line_id = fields.Many2one('sf.production.line', string='生产线', readonly=True)
machine_table_type_id = fields.Many2one('maintenance.equipment.category', string='机床类型', readonly=True)
machine_tool_code = fields.Char(string='机台号', store=True, invisible=True, readonly=True)
cutter_spacing_code_id = fields.Many2one('maintenance.equipment.tool', string='刀位号', readonly=True)
name = fields.Many2one('maintenance.equipment', string='CNC机床', readonly=True)
machine_tool_code = fields.Char(string='机台号', readonly=True)
cutter_spacing_code = fields.Char(string='刀位号', readonly=True)
# functional_tool_code = fields.Char(string='功能刀具编码', readonly=True)
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', readonly=True) barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', readonly=True)
functional_tool_name_id = fields.Many2one('product.product', string='功能刀具名称', readonly=True) functional_tool_name = fields.Char(string='功能刀具名称', readonly=True)
functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', readonly=True) functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', readonly=True)
tool_position_interface_type = fields.Selection(
[('BT刀柄式', 'BT刀柄式'), ('SK刀柄式', 'SK刀柄式'), ('HSK刀柄式', 'HSK刀柄式'),
('CAT刀柄式', 'CAT刀柄式'), ('ISO刀盘式', 'ISO刀盘式'), ('DIN刀盘式', 'DIN刀盘式'),
('直装固定式', '直装固定式')], string='刀位接口型号', readonly=True)
diameter = fields.Integer(string='刀具直径(mm)', readonly=True)
knife_tip_r_angle = fields.Float(string='刀尖R角(mm)', readonly=True)
max_lifetime_value = fields.Integer(string='最大寿命值(min)', readonly=True)
alarm_value = fields.Integer(string='报警值(min)', readonly=True)
used_value = fields.Integer(string='已使用值(min)', readonly=True)
whether_standard_knife = fields.Boolean(string='是否标准刀', default=True, readonly=True)
extension_length = fields.Float(string='伸出长(mm)', readonly=True)
effective_length = fields.Float(string='有效长(mm)', readonly=True)
# replacement_tool_code = fields.Char(string='待换功能刀具编码', readonly=True) # 待换功能刀具信息
replacement_tool_name_id = fields.Many2one('product.product', string='待换功能刀具名称', replacement_tool_name = fields.Char(string='待换功能刀具名称', required=True)
domain=[('name', '=', '功能刀具')])
replacement_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='待换功能刀具类型') replacement_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='待换功能刀具类型')
replacement_diameter = fields.Integer(string='待换刀具直径(mm)')
replacement_knife_tip_r_angle = fields.Float(string='待换刀具刀尖R角(mm)')
replacement_tool_setting_length = fields.Float(string='待换刀具装刀长(mm)')
replacement_extension_length = fields.Float(string='待换刀具伸出长(mm)')
replacement_effective_length = fields.Float(string='待换刀具有效长(mm)')
replacement_tool_coarse_middle_thin = fields.Selection([("1", ""), ('2', ''), ('3', '')], replacement_tool_coarse_middle_thin = fields.Selection([("1", ""), ('2', ''), ('3', '')],
string='粗/中/精') string='待换刀具粗/中/精', default='3')
new_former = fields.Selection([('0', ''), ('1', '')], string='新/旧')
applicant = fields.Char(string='申请人', default=lambda self: self.env.user.name, readonly=True)
used_tool_time = fields.Datetime(string='用刀时间')
reason_for_applying = fields.Char(string='申请原因')
remark = fields.Char(string='备注说明')
replacement_max_lifetime_value = fields.Integer(string='待换刀具最大寿命值(min)')
replacement_alarm_value = fields.Integer(string='待换刀具报警值(min)')
replacement_used_value = fields.Integer(string='待换刀具已使用值(min)')
new_former = fields.Selection([('0', ''), ('1', '')], string='新/旧', default='0')
replacement_whether_standard_knife = fields.Boolean(string='待换刀具是否标准刀', default=True)
used_tool_time = fields.Datetime(string='用刀时间',
default=lambda self: fields.Datetime.now() + timedelta(hours=4))
applicant = fields.Char(string='申请人', default=lambda self: self.env.user.name, readonly=True)
reason_for_applying = fields.Char(string='申请原因')
def tool_changing_apply(self): def tool_changing_apply(self):
""" """
确认换刀申请(按键) 确认换刀申请(按键)
:return: :return:
""" """
# 将数据更新到机台换刀申请界面
print('已运行') print('已运行')
record = self.env['sf.machine.table.tool.changing.apply'].search( record = self.env['sf.machine.table.tool.changing.apply'].search(
[('name', '=', self.name.id), [('maintenance_equipment_id', '=', self.maintenance_equipment_id.id),
('machine_tool_code', '=', self.machine_tool_code), ('cutter_spacing_code_id', '=', self.cutter_spacing_code_id.id)
('cutter_spacing_code', '=', self.cutter_spacing_code),
]) ])
print('运行record_1') print('运行record_1')
# 功能刀具组装创建新任务(new_assembly_task) # 功能刀具组装创建新任务(new_assembly_task)
record_1 = self.env['sf.functional.tool.assembly'].sudo().create({ sf_functional_tool_assembly = self.env['sf.functional.tool.assembly'].sudo().create({
'functional_tool_name_id': self.replacement_tool_name_id.id, 'functional_tool_name': self.replacement_tool_name,
'functional_tool_type_id': self.replacement_tool_type_id.id, 'functional_tool_type_id': self.replacement_tool_type_id.id,
'loading_task_source': '1', 'functional_tool_diameter': self.replacement_diameter,
'applicant': self.applicant, 'knife_tip_r_angle': self.replacement_knife_tip_r_angle,
'reason_for_applying': self.reason_for_applying, 'coarse_middle_thin': self.replacement_tool_coarse_middle_thin,
'use_tool_time': self.used_tool_time,
'machine_tool_name_id': self.name.id,
'machine_tool_code': self.machine_tool_code,
'cutter_spacing_code': self.cutter_spacing_code,
'sf_machine_table_tool_changing_apply_id': record.id,
})
print('record_1:', record_1)
# 封装数据
desc = {
'name': self.name.id,
'assembly_order_code': record_1.assembly_order_code,
'machine_tool_code': self.machine_tool_code,
'cutter_spacing_code': self.cutter_spacing_code,
'replacement_tool_name_id': self.replacement_tool_name_id.id,
'replacement_tool_type_id': self.replacement_tool_type_id.id,
'replacement_tool_coarse_middle_thin': self.replacement_tool_coarse_middle_thin,
'new_former': self.new_former, 'new_former': self.new_former,
'tool_loading_length': self.replacement_tool_setting_length,
'functional_tool_length': self.replacement_extension_length,
'effective_length': self.replacement_effective_length,
'loading_task_source': '1',
'use_tool_time': self.used_tool_time,
'production_line_name_id': self.production_line_id.id,
'machine_tool_name_id': self.maintenance_equipment_id.id,
'applicant': self.applicant, 'applicant': self.applicant,
'used_tool_time': self.used_tool_time, 'apply_time': fields.Datetime.now(),
'cutter_spacing_code_id': self.cutter_spacing_code_id.id,
'whether_standard_knife': self.whether_standard_knife,
'reason_for_applying': self.reason_for_applying, 'reason_for_applying': self.reason_for_applying,
'remark': self.new_former, 'sf_machine_table_tool_changing_apply_id': record.id
})
print('sf_functional_tool_assembly:', sf_functional_tool_assembly)
# 修改机床换刀申请状态
record.write({
'status': '1', 'status': '1',
'sf_functional_tool_assembly_id': record_1.id, 'sf_functional_tool_assembly_id': sf_functional_tool_assembly
} })
print('运行record.write(desc)')
record.write(desc)
print('运行成功') print('运行成功')
# 关闭弹出窗口 # 关闭弹出窗口
@@ -85,18 +102,35 @@ class ToolTransferRequestInformation(models.TransientModel):
_name = 'sf.tool.transfer.request.information' _name = 'sf.tool.transfer.request.information'
_description = '刀具转移申请信息' _description = '刀具转移申请信息'
CNC_machine_table_id = fields.Many2one('sf.machine_tool', string='CNC机床', readonly=True) name = fields.Char('名称', related='maintenance_equipment_id.name', store=True, readonly=True)
machine_tool_code = fields.Char(string='机台号', readonly=True) maintenance_equipment_id = fields.Many2one('maintenance.equipment', string='CNC机床', readonly=True)
cutter_spacing_code = fields.Char(string='刀位号', readonly=True) production_line_id = fields.Many2one('sf.production.line', string='生产线', readonly=True)
# functional_tool_code = fields.Char(string='功能刀具编码', readonly=True) machine_table_type_id = fields.Many2one('maintenance.equipment.category', string='机床类型', readonly=True)
machine_tool_code = fields.Char(string='机台号', store=True, invisible=True, readonly=True)
cutter_spacing_code_id = fields.Many2one('maintenance.equipment.tool', string='刀位号', readonly=True)
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', readonly=True) barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', readonly=True)
functional_tool_name_id = fields.Many2one('product.product', string='功能刀具名称', readonly=True) functional_tool_name = fields.Char(string='功能刀具名称', readonly=True)
functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', readonly=True) functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', readonly=True)
tool_position_interface_type = fields.Selection(
[('BT刀柄式', 'BT刀柄式'), ('SK刀柄式', 'SK刀柄式'), ('HSK刀柄式', 'HSK刀柄式'),
('CAT刀柄式', 'CAT刀柄式'), ('ISO刀盘式', 'ISO刀盘式'), ('DIN刀盘式', 'DIN刀盘式'),
('直装固定式', '直装固定式')], string='刀位接口型号', readonly=True)
diameter = fields.Integer(string='刀具直径(mm)', readonly=True)
knife_tip_r_angle = fields.Float(string='刀尖R角(mm)', readonly=True)
max_lifetime_value = fields.Integer(string='最大寿命值(min)', readonly=True)
alarm_value = fields.Integer(string='报警值(min)', readonly=True)
used_value = fields.Integer(string='已使用值(min)', readonly=True)
whether_standard_knife = fields.Boolean(string='是否标准刀', default=True, readonly=True)
extension_length = fields.Float(string='伸出长(mm)', readonly=True)
effective_length = fields.Float(string='有效长(mm)', readonly=True)
# 转移刀具信息
transfer_target = fields.Selection([('机台', '机台'), transfer_target = fields.Selection([('机台', '机台'),
('线边刀库', '线边刀库'), ('线边刀库', '线边刀库'),
('刀具房', '刀具房')], string='转移到:', default='线边刀库') ('刀具房', '刀具房')], string='转移到:', default='线边刀库')
new_cnc_machine_table_id = fields.Many2one('sf.machine_tool', string='机床名称') new_cnc_machine_table_id = fields.Many2one('sf.machine_tool', string='机床名称')
new_production_line_id = fields.Many2one('sf.production.line', string='目标生产线')
new_machine_tool_code = fields.Char(string='机床号') new_machine_tool_code = fields.Char(string='机床号')
new_cutter_spacing_code = fields.Char(string='目标刀位号') new_cutter_spacing_code = fields.Char(string='目标刀位号')
@@ -120,27 +154,41 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
_inherit = ["barcodes.barcode_events_mixin"] _inherit = ["barcodes.barcode_events_mixin"]
_description = '功能刀具组装单' _description = '功能刀具组装单'
# 功能刀具申请信息 assembly_order_code = fields.Char(string='编码', readonly=True)
machine_tool_name_id = fields.Many2one('maintenance.equipment', string='机床名称', readonly=True) functional_tool_name_id = fields.Many2one('product.product', string='功能刀具', readonly=True)
functional_tool_name = fields.Char(string='功能刀具名称', readonly=True)
functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', readonly=True,
group_expand='_read_group_functional_tool_type_ids')
functional_tool_diameter = fields.Integer(string='功能刀具直径(mm)', readonly=True)
knife_tip_r_angle = fields.Float(string='刀尖R角(mm)', readonly=True)
coarse_middle_thin = fields.Selection([("1", ""), ('2', ''), ('3', '')], string='粗/中/精', readonly=True)
new_former = fields.Selection([('0', ''), ('1', '')], string='新/旧', readonly=True)
tool_loading_length = fields.Float(string='装刀长(mm)', readonly=True)
functional_tool_length = fields.Float(string='伸出长(mm)', readonly=True)
effective_length = fields.Float(string='有效长(mm)', readonly=True)
loading_task_source = fields.Selection([('0', 'CAM装刀'), ('1', '机台换刀'), ('2', '按库存组装')],
string='装刀任务来源', readonly=True)
use_tool_time = fields.Datetime(string='用刀时间', readonly=True)
production_line_name_id = fields.Many2one('sf.production.line', string='申请产线', readonly=True)
machine_tool_name_id = fields.Many2one('maintenance.equipment', string='申请机台', readonly=True)
machine_tool_code = fields.Char(string='机台号', readonly=True) machine_tool_code = fields.Char(string='机台号', readonly=True)
cutter_spacing_code = fields.Char(string='刀位号', readonly=True) applicant = fields.Char(string='申请人', readonly=True)
# code = fields.Char(string='功能刀具编码', readonly=True) apply_time = fields.Datetime(string='申请时间', default=fields.Datetime.now(), readonly=True)
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', readonly=True) assemble_status = fields.Selection([('0', '待组装'), ('1', '已组装')], string='组装状态', default='0',
functional_tool_name_id = fields.Many2one('product.product', string='功能刀具名称', readonly=True) readonly=True)
functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', readonly=True) cutter_spacing_code_id = fields.Many2one('maintenance.equipment.tool', string='刀位号', readonly=True)
functional_tool_length = fields.Char(string='功能刀具伸出长(mm)', readonly=True) whether_standard_knife = fields.Boolean(string='是否标准刀', default=True, readonly=True)
effective_length = fields.Char(string='有效长(mm)', readonly=True) reason_for_applying = fields.Char(string='申请原因', readonly=True)
functional_tool_diameter = fields.Char(string='功能刀具直径(mm)', readonly=True) max_lifetime_value = fields.Integer(string='最大寿命值(min)', readonly=True)
tool_included_angle = fields.Char(string='刀尖角R角', readonly=True) alarm_value = fields.Integer(string='报警值(min)', readonly=True)
functional_tool_cutting_type = fields.Char(string='功能刀具切削类型', readonly=True) used_value = fields.Integer(string='已使用值(min)', readonly=True)
required_cutting_time = fields.Char(string='需切削时长', readonly=True)
whether_standard_tool = fields.Boolean(string='是否标准刀', readonly=True)
# 功能刀具组装信息 # 功能刀具组装信息
# 整体式刀具型号 # 整体式刀具型号
integral_code_id = fields.Many2one('stock.lot', string='整体式刀具序列号', integral_code_id = fields.Many2one('stock.lot', string='整体式刀具序列号',
domain=[('product_id.cutting_tool_material_id.name', '=', '整体式刀具')]) domain=[('product_id.cutting_tool_material_id.name', '=', '整体式刀具')])
cutting_tool_integral_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='整体式刀具型号', readonly=True) cutting_tool_integral_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='整体式刀具型号',
readonly=True)
integral_name = fields.Char('整体式刀具名称', readonly=True) integral_name = fields.Char('整体式刀具名称', readonly=True)
sf_tool_brand_id_1 = fields.Many2one('sf.machine.brand', string='整体式刀具品牌', readonly=True) sf_tool_brand_id_1 = fields.Many2one('sf.machine.brand', string='整体式刀具品牌', readonly=True)
@@ -154,28 +202,32 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
# 刀杆型号 # 刀杆型号
bar_code_id = fields.Many2one('stock.lot', '刀杆序列号', bar_code_id = fields.Many2one('stock.lot', '刀杆序列号',
domain=[('product_id.cutting_tool_material_id.name', '=', '刀杆')]) domain=[('product_id.cutting_tool_material_id.name', '=', '刀杆')])
cutting_tool_cutterbar_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀杆型号', readonly=True) cutting_tool_cutterbar_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀杆型号',
readonly=True)
bar_name = fields.Char('刀杆名称', readonly=True) bar_name = fields.Char('刀杆名称', readonly=True)
sf_tool_brand_id_3 = fields.Many2one('sf.machine.brand', '刀杆品牌', readonly=True) sf_tool_brand_id_3 = fields.Many2one('sf.machine.brand', '刀杆品牌', readonly=True)
# 刀盘型号 # 刀盘型号
pad_code_id = fields.Many2one('stock.lot', '刀盘序列号', pad_code_id = fields.Many2one('stock.lot', '刀盘序列号',
domain=[('product_id.cutting_tool_material_id.name', '=', '刀盘')]) domain=[('product_id.cutting_tool_material_id.name', '=', '刀盘')])
cutting_tool_cutterpad_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀盘型号', readonly=True) cutting_tool_cutterpad_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀盘型号',
readonly=True)
pad_name = fields.Char('刀盘名称', readonly=True) pad_name = fields.Char('刀盘名称', readonly=True)
sf_tool_brand_id_4 = fields.Many2one('sf.machine.brand', '刀盘品牌', readonly=True) sf_tool_brand_id_4 = fields.Many2one('sf.machine.brand', '刀盘品牌', readonly=True)
# 刀柄型号 # 刀柄型号
handle_code_id = fields.Many2one('stock.lot', '刀柄序列号', handle_code_id = fields.Many2one('stock.lot', '刀柄序列号', required=True,
domain=[('product_id.cutting_tool_material_id.name', '=', '刀柄')]) domain=[('product_id.cutting_tool_material_id.name', '=', '刀柄')])
cutting_tool_cutterhandle_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀柄型号', readonly=True) cutting_tool_cutterhandle_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀柄型号',
readonly=True)
handle_name = fields.Char('刀柄名称', readonly=True) handle_name = fields.Char('刀柄名称', readonly=True)
sf_tool_brand_id_5 = fields.Many2one('sf.machine.brand', '刀柄品牌', readonly=True) sf_tool_brand_id_5 = fields.Many2one('sf.machine.brand', '刀柄品牌', readonly=True)
# 夹头型号 # 夹头型号
chuck_code_id = fields.Many2one('stock.lot', '夹头序列号', chuck_code_id = fields.Many2one('stock.lot', '夹头序列号', required=True,
domain=[('product_id.cutting_tool_material_id.name', '=', '夹头')]) domain=[('product_id.cutting_tool_material_id.name', '=', '夹头')])
cutting_tool_cutterhead_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='夹头型号', readonly=True) cutting_tool_cutterhead_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='夹头型号',
readonly=True)
chuck_name = fields.Char('夹头名称', readonly=True, compute='_compute_auto_fill') chuck_name = fields.Char('夹头名称', readonly=True, compute='_compute_auto_fill')
sf_tool_brand_id_6 = fields.Many2one('sf.machine.brand', '夹头品牌', readonly=True) sf_tool_brand_id_6 = fields.Many2one('sf.machine.brand', '夹头品牌', readonly=True)
@@ -256,86 +308,67 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
record.chuck_name = None record.chuck_name = None
record.sf_tool_brand_id_6 = None record.sf_tool_brand_id_6 = None
coarse_middle_thin = fields.Selection([("1", ""), ('2', ''), ('3', '')], string='粗/中/精', default='1') # 组装功能刀具参数信息
tool_loading_length = fields.Char(string='装刀长') barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号')
new_former = fields.Selection([('0', ''), ('1', '')], string='新/旧', required=True, default='0') after_assembly_functional_tool_name = fields.Char(string='组装后功能刀具名称', required=True)
reference_length = fields.Char(string='参考伸出长') after_assembly_functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model',
cut_time = fields.Char(string='已切削时间') string='组装后功能刀具类型')
cut_length = fields.Char(string='已切削长度') after_assembly_functional_tool_diameter = fields.Integer(string='组装后功能刀具直径(mm)')
cut_number = fields.Char(string='已切削次数') after_assembly_knife_tip_r_angle = fields.Float(string='组装后刀尖R角(mm)')
after_assembly_new_former = fields.Selection([('0', ''), ('1', '')], string='组装后新/旧')
cut_time = fields.Integer(string='已切削时间(min)')
cut_length = fields.Float(string='已切削长度(mm)')
cut_number = fields.Integer(string='已切削次数')
after_assembly_whether_standard_knife = fields.Boolean(string='组装后是否标准刀', default=True)
after_assembly_coarse_middle_thin = fields.Selection([("1", ""), ('2', ''), ('3', '')],
string='组装后粗/中/精')
after_assembly_max_lifetime_value = fields.Integer(string='组装后最大寿命值(min)')
after_assembly_alarm_value = fields.Integer(string='组装后报警值(min)')
after_assembly_used_value = fields.Integer(string='组装后已使用值(min)')
after_assembly_tool_loading_length = fields.Float(string='组装后装刀长(mm)')
after_assembly_functional_tool_length = fields.Float(string='组装后伸出长(mm)')
after_assembly_effective_length = fields.Float(string='组装后有效长(mm)')
L_D_number = fields.Float(string='L/D值(mm)')
hiding_length = fields.Float(string='避空长(mm)')
functional_tool_cutting_type = fields.Char(string='功能刀具切削类型', readonly=False)
def functional_tool_assembly(self): def functional_tool_assembly(self):
""" """
功能刀具组装 功能刀具组装
:return: :return:
""" """
# 创建组装入库单
# 创建功能刀具批次/序列号记录
stock_lot = self.create_assemble_warehouse_receipt()
# 创建刀具组装入库单
self.create_stocking_picking(stock_lot)
desc_1 = {
'barcode_id': stock_lot.id,
'integral_code_id': self.integral_code_id.id,
'blade_code_id': self.blade_code_id.id,
'bar_code_id': self.bar_code_id.id,
'pad_code_id': self.pad_code_id.id,
'handle_code_id': self.handle_code_id.id,
'chuck_code_id': self.chuck_code_id.id,
'coarse_middle_thin': self.coarse_middle_thin,
'tool_loading_length': self.tool_loading_length,
'new_former': self.new_former,
'reference_length': self.reference_length,
'cut_time': self.cut_time,
'cut_length': self.cut_length,
'cut_number': self.cut_number,
'assemble_status': '1',
'tool_loading_person': self.env.user.name,
'tool_loading_time': fields.Datetime.now()
}
functional_tool_assembly = self.env['sf.functional.tool.assembly'].search([ functional_tool_assembly = self.env['sf.functional.tool.assembly'].search([
('assembly_order_code', '=', self.assembly_order_code),
('machine_tool_name_id', '=', self.machine_tool_name_id.id), ('machine_tool_name_id', '=', self.machine_tool_name_id.id),
('cutter_spacing_code', '=', self.cutter_spacing_code), ('cutter_spacing_code_id', '=', self.cutter_spacing_code_id.id),
('assemble_status', '=', '0'), ('assemble_status', '=', '0'),
]) ])
# 对物料做必填判断
self.materials_must_be_judged()
# 创建组装入库单
# 创建功能刀具批次/序列号记录
stock_lot = self.create_assemble_warehouse_receipt(functional_tool_assembly)
# 创建刀具组装入库单
self.create_stocking_picking(stock_lot)
# 封装功能刀具数据 # 封装功能刀具数据
desc_2 = { desc_1 = self.get_desc_1(stock_lot)
'barcode_id': stock_lot.id,
'functional_tool_name_id': self.functional_tool_name_id.id, # 创建功能刀具列表记录
'mrs_cutting_tool_type_id': self.functional_tool_type_id.id, # 封装功能刀具数据
'cutting_tool_integral_model_id': self.integral_code_id.product_id.id, desc_2 = self.get_desc_2(stock_lot, functional_tool_assembly)
'cutting_tool_blade_model_id': self.blade_code_id.product_id.id,
'cutting_tool_cutterbar_model_id': self.bar_code_id.product_id.id,
'cutting_tool_cutterpad_model_id': self.pad_code_id.product_id.id,
'cutting_tool_cutterhandle_model_id': self.handle_code_id.product_id.id,
'cutting_tool_cutterhead_model_id': self.chuck_code_id.product_id.id,
'diameter': self.functional_tool_diameter,
'tool_grade': None,
'machining_accuracy': None,
'tool_length': self.tool_loading_length,
'blade_number': None,
'integral_blade_length': None,
'effective_blade_length': self.effective_length,
'max_life': None,
'is_standard': self.whether_standard_tool,
'applicable_range': None,
'image': None,
}
# 创建功能刀具列表、功能刀具预警、功能刀具实时分布、功能刀具出入库记录 # 创建功能刀具列表、功能刀具预警、功能刀具实时分布、功能刀具出入库记录
record_1 = self.env['sf.functional.cutting.tool.entity'].create(desc_2) record_1 = self.env['sf.functional.cutting.tool.entity'].create(desc_2)
self.env['sf.functional.tool.warning'].create({ # self.env['sf.real.time.distribution.of.functional.tools'].create({
'functional_cutting_tool_id': record_1.id, # 'functional_cutting_tool_id': record_1.id
'functional_tool_assembly_id': functional_tool_assembly.id, # })
'machine_table_name_id': self.machine_tool_name_id.id, # self.env['sf.inbound.and.outbound.records.of.functional.tools'].create({
}) # 'functional_cutting_tool_id': record_1.id
self.env['sf.real.time.distribution.of.functional.tools'].create({ # })
'functional_cutting_tool_id': record_1.id
})
self.env['sf.inbound.and.outbound.records.of.functional.tools'].create({
'functional_cutting_tool_id': record_1.id
})
# 修改功能刀具组装信息 # 修改功能刀具组装信息
functional_tool_assembly.write(desc_1) functional_tool_assembly.write(desc_1)
if functional_tool_assembly.sf_machine_table_tool_changing_apply_id: if functional_tool_assembly.sf_machine_table_tool_changing_apply_id:
@@ -352,6 +385,16 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
# 关闭弹出窗口 # 关闭弹出窗口
return {'type': 'ir.actions.act_window_close'} return {'type': 'ir.actions.act_window_close'}
def materials_must_be_judged(self):
"""
功能刀具组装物料必填判断
"""
if not self.integral_code_id and not self.blade_code_id:
raise ValidationError('【整体式刀具】和【刀片】必须填写一个!')
if self.blade_code_id:
if not self.bar_code_id and not self.pad_code_id:
raise ValidationError('【刀盘】和【刀杆】必须填写一个!')
def create_stocking_picking(self, stock_lot): def create_stocking_picking(self, stock_lot):
""" """
创建刀具组装入库单 创建刀具组装入库单
@@ -371,7 +414,7 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
# 将刀具组装入库单的状态更改为就绪 # 将刀具组装入库单的状态更改为就绪
picking_id.action_confirm() picking_id.action_confirm()
def create_assemble_warehouse_receipt(self): def create_assemble_warehouse_receipt(self, functional_tool_assembly):
""" """
创建功能刀具批次/序列号记录 创建功能刀具批次/序列号记录
""" """
@@ -383,11 +426,11 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
'company_id': self.env.company.id 'company_id': self.env.company.id
}) })
# 创建功能刀具该批次/序列号 库存移动和移动历史 # 创建功能刀具该批次/序列号 库存移动和移动历史
self.create_stock_quant(product_id, stock_lot) self.create_stock_quant(product_id, stock_lot, functional_tool_assembly)
return stock_lot return stock_lot
def create_stock_quant(self, product_id, stock_lot): def create_stock_quant(self, product_id, stock_lot, functional_tool_assembly):
""" """
创建功能刀具该批次/序列号 库存移动和移动历史 创建功能刀具该批次/序列号 库存移动和移动历史
""" """
@@ -397,7 +440,7 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
# 创建库存移动 # 创建库存移动
stock_move_id = self.env['stock.move'].create({ stock_move_id = self.env['stock.move'].create({
'name': '更新的产品数量', 'name': '功能刀具组装出库',
'product_id': product_id.id, 'product_id': product_id.id,
'location_id': location_inventory_id.id, 'location_id': location_inventory_id.id,
'location_dest_id': stock_location_id.id, 'location_dest_id': stock_location_id.id,
@@ -408,12 +451,13 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
# 创建移动历史 # 创建移动历史
stock_move_line_id = self.env['stock.move.line'].create({ stock_move_line_id = self.env['stock.move.line'].create({
'product_id': product_id.id, 'product_id': product_id.id,
'functional_tool_name_id': functional_tool_assembly.id,
'lot_id': stock_lot.id, 'lot_id': stock_lot.id,
'move_id': stock_move_id.id, 'move_id': stock_move_id.id,
'install_tool_time': fields.Datetime.now(),
'qty_done': 1.0, 'qty_done': 1.0,
'state': 'done' 'state': 'done'
}) })
return stock_move_id, stock_move_line_id return stock_move_id, stock_move_line_id
def get_stock_lot_name(self): def get_stock_lot_name(self):
@@ -433,4 +477,69 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
else: else:
m = int(stock_lot_id.name[-3:]) + 1 m = int(stock_lot_id.name[-3:]) + 1
num = "%03d" % m num = "%03d" % m
return code + str(num) return code + str(num)
def get_desc_1(self, stock_lot):
return {
'barcode_id': stock_lot.id,
'integral_code_id': self.integral_code_id.id,
'blade_code_id': self.blade_code_id.id,
'bar_code_id': self.bar_code_id.id,
'pad_code_id': self.pad_code_id.id,
'handle_code_id': self.handle_code_id.id,
'chuck_code_id': self.chuck_code_id.id,
'after_assembly_functional_tool_name': self.after_assembly_functional_tool_name,
'after_assembly_functional_tool_type_id': self.after_assembly_functional_tool_type_id.id,
'after_assembly_functional_tool_diameter': self.after_assembly_functional_tool_diameter,
'after_assembly_knife_tip_r_angle': self.after_assembly_knife_tip_r_angle,
'after_assembly_new_former': self.after_assembly_new_former,
'cut_time': self.cut_time,
'cut_length': self.cut_length,
'cut_number': self.cut_number,
'after_assembly_whether_standard_knife': self.after_assembly_whether_standard_knife,
'after_assembly_coarse_middle_thin': self.after_assembly_coarse_middle_thin,
'after_assembly_max_lifetime_value': self.after_assembly_max_lifetime_value,
'after_assembly_alarm_value': self.after_assembly_alarm_value,
'after_assembly_used_value': self.after_assembly_used_value,
'after_assembly_tool_loading_length': self.after_assembly_tool_loading_length,
'after_assembly_functional_tool_length': self.after_assembly_functional_tool_length,
'after_assembly_effective_length': self.after_assembly_effective_length,
'L_D_number': self.L_D_number,
'hiding_length': self.hiding_length,
'assemble_status': '1',
'tool_loading_person': self.env.user.name,
'tool_loading_time': fields.Datetime.now()
}
def get_desc_2(self, stock_lot, functional_tool_assembly_id):
return {
'barcode_id': stock_lot.id,
'functional_tool_name_id': functional_tool_assembly_id.id,
'sf_cutting_tool_type_id': self.after_assembly_functional_tool_type_id.id,
'cutting_tool_integral_model_id': self.integral_code_id.product_id.id,
'cutting_tool_blade_model_id': self.blade_code_id.product_id.id,
'cutting_tool_cutterbar_model_id': self.bar_code_id.product_id.id,
'cutting_tool_cutterpad_model_id': self.pad_code_id.product_id.id,
'cutting_tool_cutterhandle_model_id': self.handle_code_id.product_id.id,
'cutting_tool_cutterhead_model_id': self.chuck_code_id.product_id.id,
'functional_tool_diameter': self.after_assembly_functional_tool_diameter,
'knife_tip_r_angle': self.after_assembly_knife_tip_r_angle,
'coarse_middle_thin': self.after_assembly_coarse_middle_thin,
'new_former': self.after_assembly_new_former,
'tool_loading_length': self.after_assembly_tool_loading_length,
'functional_tool_length': self.after_assembly_functional_tool_length,
'effective_length': self.after_assembly_effective_length,
'max_lifetime_value': self.after_assembly_max_lifetime_value,
'alarm_value': self.after_assembly_alarm_value,
'used_value': self.after_assembly_used_value,
'whether_standard_knife': self.after_assembly_whether_standard_knife,
'L_D_number': self.L_D_number,
'hiding_length': self.hiding_length,
'cut_time': self.cut_time,
'cut_length': self.cut_length,
'cut_number': self.cut_number,
'current_location_id': stock_lot.quant_ids.location_id.ids[-1],
}

View File

@@ -1,46 +1,68 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<odoo> <odoo>
<!--================================================换刀需求信息================================================--> <!--================================================换刀需求信息================================================-->
<record id="sf_tool_change_requirement_information_form" model="ir.ui.view"> <record id="sf_tool_change_requirement_information_form" model="ir.ui.view">
<field name="name">换刀需求信息</field> <field name="name">换刀需求信息</field>
<field name="model">sf.tool.change.requirement.information</field> <field name="model">sf.tool.change.requirement.information</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="换刀需求信息"> <form string="换刀需求信息">
<sheet> <sheet>
<group string="机床信息" col="3"> <div class="oe_title">
<group> <h1>
<field name="name"/> <field name="maintenance_equipment_id"/>
<field name="barcode_id"/> </h1>
</group> </div>
<group> <group>
<field name="machine_tool_code"/> <group>
<field name="functional_tool_name_id"/> <field name="production_line_id"/>
</group> <field name="machine_table_type_id"/>
<group> <field name="cutter_spacing_code_id"/>
<field name="cutter_spacing_code"/> <field name="tool_position_interface_type"/>
<field name="functional_tool_type_id"/> <field name="max_lifetime_value"/>
</group> <field name="alarm_value"/>
<field name="used_value"/>
<field name="whether_standard_knife"/>
</group> </group>
<group string="功能刀具信息"> <group>
<group> <field name="barcode_id"/>
<field name="replacement_tool_name_id" placeholder="请选择"/> <field name="functional_tool_name"/>
<field name="replacement_tool_type_id"/> <field name="functional_tool_type_id"/>
<field name="replacement_tool_coarse_middle_thin" placeholder="请选择"/> <field name="diameter"/>
<field name="applicant"/> <field name="knife_tip_r_angle"/>
</group> <field name="extension_length"/>
<group> <field name="effective_length"/>
<field name="used_tool_time" placeholder="请选择"/>
<field name="new_former" placeholder="请选择"/>
<field name="reason_for_applying"/>
</group>
</group> </group>
</sheet> </group>
<footer> <group string="待换功能刀具信息">
<button string="确定" name="tool_changing_apply" type="object" class="btn-primary" confirm="是否确认申请换刀"/> <group>
<button string="取消" class="btn-secondary" special="cancel"/> <field name="replacement_tool_name" string="功能刀具名称"/>
</footer> <field name="replacement_tool_type_id" string="功能刀具类型"/>
</form> <field name="replacement_diameter" string="刀具直径(mm)"/>
</field> <field name="replacement_knife_tip_r_angle" string="刀尖R角(mm)"/>
<field name="replacement_tool_setting_length" string="装刀长(mm)"/>
<field name="replacement_extension_length" string="伸出长(mm)"/>
<field name="replacement_effective_length" string="有效长(mm)"/>
<field name="replacement_tool_coarse_middle_thin" string="粗/中/精"/>
</group>
<group>
<field name="replacement_max_lifetime_value" string="最大寿命值(min)"/>
<field name="replacement_alarm_value" string="报警值(min)"/>
<field name="replacement_used_value" string="已使用值(min)"/>
<field name="new_former"/>
<field name="replacement_whether_standard_knife" string="是否标准刀"/>
<field name="used_tool_time"/>
<field name="applicant"/>
<field name="reason_for_applying"/>
</group>
</group>
</sheet>
<footer>
<button string="确定" name="tool_changing_apply" type="object" class="btn-primary"
confirm="是否确认申请换刀"/>
<button string="取消" class="btn-secondary" special="cancel"/>
</footer>
</form>
</field>
</record> </record>
<record id="sf_tool_change_requirement_information_act" model="ir.actions.act_window"> <record id="sf_tool_change_requirement_information_act" model="ir.actions.act_window">
@@ -53,54 +75,71 @@
</record> </record>
<!--================================================刀具转移申请信息================================================--> <!--================================================刀具转移申请信息================================================-->
<record id="sf_tool_transfer_request_information_form" model="ir.ui.view"> <record id="sf_tool_transfer_request_information_form" model="ir.ui.view">
<field name="name">刀具转移申请信息</field> <field name="name">刀具转移申请信息</field>
<field name="model">sf.tool.transfer.request.information</field> <field name="model">sf.tool.transfer.request.information</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="刀具转移申请信息"> <form string="刀具转移申请信息">
<sheet> <sheet>
<group string="机床信息"> <div class="oe_title">
<group> <h1>
<field name="CNC_machine_table_id"/> <field name="maintenance_equipment_id"/>
<field name="cutter_spacing_code"/> </h1>
</group> </div>
<group> <group>
<field name="machine_tool_code"/> <group>
</group> <field name="production_line_id"/>
</group> <field name="machine_table_type_id"/>
<group string="功能刀具信息"> <field name="cutter_spacing_code_id"/>
<group> <field name="tool_position_interface_type"/>
<field name="functional_tool_name_id" string="功能刀具名称"/> <field name="max_lifetime_value"/>
<field name="functional_tool_type_id" string="功能刀具类型"/> <field name="alarm_value"/>
</group> <field name="alarm_value"/>
<group> <field name="whether_standard_knife"/>
<field name="barcode_id" string="功能刀具编码"/>
</group>
</group>
<group string="刀具转移">
<group>
<field name="transfer_target" widget="radio" options="{'horizontal': true}"/>
</group>
</group> </group>
<group> <group>
<group> <field name="barcode_id"/>
<field name="new_cnc_machine_table_id" attrs="{'invisible': [('transfer_target', '!=', '机台')]}"/> <field name="functional_tool_name"/>
<field name="new_machine_tool_code" attrs="{'invisible': [('transfer_target', '!=', '机台')]}"/> <field name="functional_tool_type_id"/>
<field name="new_cutter_spacing_code" string="刀位号" attrs="{'invisible': [('transfer_target', '!=', '机台')]}"/> <field name="diameter"/>
<field name="magazine_tool_warehouse_district" attrs="{'invisible': [('transfer_target', '!=', '线边刀库')]}"/> <field name="knife_tip_r_angle"/>
<field name="magazine_tool_warehouse_position" attrs="{'invisible': [('transfer_target', '!=', '线边刀库')]}"/> <field name="effective_length"/>
<field name="tool_room_warehouse_district" attrs="{'invisible': [('transfer_target', '!=', '刀具房')]}"/> <field name="effective_length"/>
<field name="tool_room_warehouse_position" attrs="{'invisible': [('transfer_target', '!=', '刀具房')]}"/>
</group>
</group> </group>
</sheet> </group>
<footer> <group string="刀具转移">
<button string="确定" name="tool_transfer_apply" type="object" class="btn-primary" confirm="是否确认刀具转移申请"/> <group>
<button string="取消" class="btn-secondary" special="cancel"/> <field name="transfer_target" widget="radio" options="{'horizontal': true}"/>
</footer> </group>
</form> </group>
</field> <group>
<group>
<!-- <field name="new_cnc_machine_table_id" attrs="{'invisible': [('transfer_target', '!=', '机台')]}"/>-->
<field name="new_production_line_id"
attrs="{'invisible': [('transfer_target', '!=', '机台')]}"/>
<field name="new_machine_tool_code"
attrs="{'invisible': [('transfer_target', '!=', '机台')]}"/>
<field name="new_cutter_spacing_code" string="刀位号"
attrs="{'invisible': [('transfer_target', '!=', '机台')]}"/>
<field name="magazine_tool_warehouse_district"
attrs="{'invisible': [('transfer_target', '!=', '线边刀库')]}"/>
<field name="magazine_tool_warehouse_position"
attrs="{'invisible': [('transfer_target', '!=', '线边刀库')]}"/>
<field name="tool_room_warehouse_district"
attrs="{'invisible': [('transfer_target', '!=', '刀具房')]}"/>
<field name="tool_room_warehouse_position"
attrs="{'invisible': [('transfer_target', '!=', '刀具房')]}"/>
</group>
</group>
</sheet>
<footer>
<button string="确定" name="tool_transfer_apply" type="object" class="btn-primary"
confirm="是否确认刀具转移申请"/>
<button string="取消" class="btn-secondary" special="cancel"/>
</footer>
</form>
</field>
</record> </record>
<record id="sf_tool_transfer_request_information_act" model="ir.actions.act_window"> <record id="sf_tool_transfer_request_information_act" model="ir.actions.act_window">
@@ -113,187 +152,215 @@
</record> </record>
<!--================================================功能刀具组装单================================================--> <!--================================================功能刀具组装单================================================-->
<record id="sf_functional_tool_assembly_order_form" model="ir.ui.view"> <record id="sf_functional_tool_assembly_order_form" model="ir.ui.view">
<field name="name">功能刀具组装单</field> <field name="name">功能刀具组装单</field>
<field name="model">sf.functional.tool.assembly.order</field> <field name="model">sf.functional.tool.assembly.order</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="功能刀具组装单"> <form string="功能刀具组装单">
<sheet> <sheet>
<group string="功能刀具申请信息"> <div class="oe_title">
<h1>
<field name="production_line_name_id"/>
</h1>
</div>
<group>
<group>
<field name="machine_tool_name_id"/>
<field name="cutter_spacing_code_id"/>
</group>
</group>
<group string="功能刀具申请信息">
<group>
<field name="functional_tool_name"/>
<field name="functional_tool_type_id"/>
<field name="functional_tool_diameter" string="刀具直径(mm)"/>
<field name="knife_tip_r_angle"/>
<field name="tool_loading_length"/>
<field name="functional_tool_length"/>
<field name="effective_length"/>
</group>
<group>
<field name="whether_standard_knife"/>
<field name="coarse_middle_thin"/>
<field name="new_former"/>
<field name="use_tool_time"/>
<field name="reason_for_applying"/>
<field name="functional_tool_cutting_type"/>
</group>
</group>
<group string="组装物料信息" col="1">
<field name="_barcode_scanned" widget="barcode_handler"/>
<group col="1"
attrs="{'invisible': ['|','|',('blade_code_id', '!=', False),('bar_code_id', '!=', False),('pad_code_id', '!=', False)]}">
<div>
<separator string="整体式刀具:" style="font-size: 13px;"/>
</div>
<group> <group>
<field name="machine_tool_name_id"/> <group>
<field name="barcode_id"/> <field name="integral_code_id" placeholder="请选择" string="序列号"
<field name="functional_tool_name_id"/> options="{'no_create': True, 'no_quick_create': True}"/>
<field name="functional_tool_length"/> </group>
<field name="effective_length"/>
<field name="functional_tool_cutting_type"/>
</group> </group>
<group> <group col="3">
<field name="cutter_spacing_code"/> <group>
<field name="functional_tool_type_id"/> <field name="integral_name" string="名称"/>
<field name="functional_tool_diameter"/> </group>
<field name="tool_included_angle"/> <group>
<field name="whether_standard_tool"/> <field name="cutting_tool_integral_model_id" string="型号"/>
<field name="required_cutting_time"/> </group>
<group>
<field name="sf_tool_brand_id_1" string="品牌"/>
</group>
</group> </group>
</group> </group>
<group string="组装物料信息" col="1"> <group col="1" attrs="{'invisible': [('integral_code_id', '!=', False)]}">
<field name="_barcode_scanned" widget="barcode_handler"/> <div>
<group col="1" attrs="{'invisible': ['|','|',('blade_code_id', '!=', False),('bar_code_id', '!=', False),('pad_code_id', '!=', False)]}"> <separator string="刀片:" style="font-size: 13px;"/>
<div> </div>
<separator string="整体式刀具:" style="font-size: 13px;"/> <group>
</div>
<group> <group>
<group> <field name="blade_code_id" placeholder="请选择" string="序列号"
<field name="integral_code_id" placeholder="请选择" string="序列号" options="{'no_create': True, 'no_quick_create': True}"/>
options="{'no_create': True, 'no_quick_create': True}"/>
</group>
</group>
<group col="3">
<group>
<field name="integral_name" string="名称"/>
</group>
<group>
<field name="cutting_tool_integral_model_id" string="型号"/>
</group>
<group>
<field name="sf_tool_brand_id_1" string="品牌"/>
</group>
</group> </group>
</group> </group>
<group col="1" attrs="{'invisible': [('integral_code_id', '!=', False)]}"> <group col="3">
<div>
<separator string="刀片:" style="font-size: 13px;"/>
</div>
<group> <group>
<group> <field name="blade_name" string="名称"/>
<field name="blade_code_id" placeholder="请选择" string="序列号"
options="{'no_create': True, 'no_quick_create': True}"/>
</group>
</group> </group>
<group col="3"> <group>
<group> <field name="cutting_tool_blade_model_id" string="型号"/>
<field name="blade_name" string="名称"/> </group>
</group> <group>
<group> <field name="sf_tool_brand_id_2" string="品牌"/>
<field name="cutting_tool_blade_model_id" string="型号"/>
</group>
<group>
<field name="sf_tool_brand_id_2" string="品牌"/>
</group>
</group> </group>
</group> </group>
<group col="1" attrs="{'invisible': ['|',('integral_code_id', '!=', False),('pad_code_id', '!=', False)]}"> </group>
<div> <group col="1"
<separator string="刀杆:" style="font-size: 13px;"/> attrs="{'invisible': ['|',('integral_code_id', '!=', False),('pad_code_id', '!=', False)]}">
</div> <div>
<separator string="刀杆:" style="font-size: 13px;"/>
</div>
<group>
<group> <group>
<group> <field name="bar_code_id" placeholder="请选择" string="序列号"
<field name="bar_code_id" placeholder="请选择" string="序列号" options="{'no_create': True, 'no_quick_create': True}"/>
options="{'no_create': True, 'no_quick_create': True}"/>
</group>
</group>
<group col="3">
<group>
<field name="bar_name" string="名称"/>
</group>
<group>
<field name="cutting_tool_cutterbar_model_id" string="型号"/>
</group>
<group>
<field name="sf_tool_brand_id_3" string="品牌"/>
</group>
</group> </group>
</group> </group>
<group col="1" attrs="{'invisible': ['|',('integral_code_id', '!=', False),('bar_code_id', '!=', False)]}"> <group col="3">
<div>
<separator string="刀盘:" style="font-size: 13px;"/>
</div>
<group> <group>
<group> <field name="bar_name" string="名称"/>
<field name="pad_code_id" placeholder="请选择" string="序列号"
options="{'no_create': True, 'no_quick_create': True}"/>
</group>
</group> </group>
<group col="3"> <group>
<group> <field name="cutting_tool_cutterbar_model_id" string="型号"/>
<field name="pad_name" string="名称"/> </group>
</group> <group>
<group> <field name="sf_tool_brand_id_3" string="品牌"/>
<field name="cutting_tool_cutterpad_model_id" string="型号"/>
</group>
<group>
<field name="sf_tool_brand_id_4" string="品牌"/>
</group>
</group> </group>
</group> </group>
<group col="1"> </group>
<div> <group col="1"
<separator string="刀柄:" style="font-size: 13px;"/> attrs="{'invisible': ['|',('integral_code_id', '!=', False),('bar_code_id', '!=', False)]}">
</div> <div>
<separator string="刀盘:" style="font-size: 13px;"/>
</div>
<group>
<group> <group>
<group> <field name="pad_code_id" placeholder="请选择" string="序列号"
<field name="handle_code_id" string="序列号" placeholder="请选择" options="{'no_create': True, 'no_quick_create': True}"/>
options="{'no_create': True, 'no_quick_create': True}"/>
</group>
</group>
<group col="3">
<group>
<field name="handle_name" string="名称"/>
</group>
<group>
<field name="cutting_tool_cutterhandle_model_id" string="型号"/>
</group>
<group>
<field name="sf_tool_brand_id_5" string="品牌"/>
</group>
</group> </group>
</group> </group>
<group col="1"> <group col="3">
<div>
<separator string="夹头:" style="font-size: 13px;"/>
</div>
<group> <group>
<group> <field name="pad_name" string="名称"/>
<field name="chuck_code_id" string="序列号" placeholder="请选择"
options="{'no_create': True, 'no_quick_create': True}"/>
</group>
</group> </group>
<group col="3"> <group>
<group> <field name="cutting_tool_cutterpad_model_id" string="型号"/>
<field name="chuck_name" string="名称"/> </group>
</group> <group>
<group> <field name="sf_tool_brand_id_4" string="品牌"/>
<field name="cutting_tool_cutterhead_model_id" string="型号"/>
</group>
<group>
<field name="sf_tool_brand_id_6" string="品牌"/>
</group>
</group> </group>
</group> </group>
</group> </group>
<group col="1">
<div>
<separator string="刀柄:" style="font-size: 13px;"/>
</div>
<group>
<group>
<field name="handle_code_id" string="序列号" placeholder="请选择"
options="{'no_create': True, 'no_quick_create': True}"/>
</group>
</group>
<group col="3">
<group>
<field name="handle_name" string="名称"/>
</group>
<group>
<field name="cutting_tool_cutterhandle_model_id" string="型号"/>
</group>
<group>
<field name="sf_tool_brand_id_5" string="品牌"/>
</group>
</group>
</group>
<group col="1">
<div>
<separator string="夹头:" style="font-size: 13px;"/>
</div>
<group>
<group>
<field name="chuck_code_id" string="序列号" placeholder="请选择"
options="{'no_create': True, 'no_quick_create': True}"/>
</group>
</group>
<group col="3">
<group>
<field name="chuck_name" string="名称"/>
</group>
<group>
<field name="cutting_tool_cutterhead_model_id" string="型号"/>
</group>
<group>
<field name="sf_tool_brand_id_6" string="品牌"/>
</group>
</group>
</group>
</group>
<group string="组装参数信息"> <group string="组装参数信息">
<group> <group>
<field name="coarse_middle_thin"/> <field name="barcode_id" readonly="True"/>
<field name="new_former"/> <field name="after_assembly_functional_tool_name" string="功能刀具名称"/>
<field name="tool_loading_length"/> <field name="after_assembly_functional_tool_type_id" string="功能刀具类型"/>
<field name="reference_length"/> <field name="after_assembly_functional_tool_diameter" string="刀具直径(mm)"/>
</group> <field name="after_assembly_knife_tip_r_angle" string="刀尖R角(mm)"/>
<group> <field name="after_assembly_new_former" string="新/旧"/>
<field name="cut_time"/> <field name="cut_time"/>
<field name="cut_length"/> <field name="cut_length"/>
<field name="cut_number"/> <field name="cut_number"/>
</group>
</group> </group>
</sheet> <group>
<footer> <field name="after_assembly_whether_standard_knife" string="是否标准刀"/>
<button string="确定" name="functional_tool_assembly" type="object" class="btn-primary" confirm="是否确认申请组装"/> <field name="after_assembly_coarse_middle_thin" string="粗/中/精"/>
<button string="取消" class="btn-secondary" special="cancel"/> <field name="after_assembly_max_lifetime_value" string="最大寿命值(min)"/>
</footer> <field name="after_assembly_alarm_value" string="报警值(min)"/>
</form> <field name="after_assembly_used_value" string="已使用值(min)"/>
</field> <field name="after_assembly_tool_loading_length" string="装刀长(mm)"/>
<field name="after_assembly_functional_tool_length" string="伸出长(mm)"/>
<field name="after_assembly_effective_length" string="有效长(mm)"/>
<field name="L_D_number"/>
<field name="hiding_length"/>
</group>
</group>
</sheet>
<footer>
<button string="确定" name="functional_tool_assembly" type="object" class="btn-primary"
confirm="是否确认申请组装"/>
<button string="取消" class="btn-secondary" special="cancel"/>
</footer>
</form>
</field>
</record> </record>
<record id="sf_functional_tool_assembly_order_act" model="ir.actions.act_window"> <record id="sf_functional_tool_assembly_order_act" model="ir.actions.act_window">

View File

@@ -16,7 +16,7 @@ class CustomChar extends CharField {
onMounted() { onMounted() {
super.onMounted(); super.onMounted();
console.log('CustomChar.onMounted1'); // console.log('CustomChar.onMounted1');
// 当光标聚焦于输入框时,选中输入框内容 // 当光标聚焦于输入框时,选中输入框内容
this.input.el.addEventListener('focus', function () { this.input.el.addEventListener('focus', function () {
this.select(); this.select();

View File

@@ -14,11 +14,11 @@ class CustomMany2One extends Many2OneField {
* @returns {Promise} * @returns {Promise}
*/ */
setup() { setup() {
console.log('CustomMany2One.setup11111111111111'); // console.log('CustomMany2One.setup11111111111111');
super.setup(); super.setup();
} }
onMounted() { onMounted() {
console.log('CustomMany2One.onMounted1'); // console.log('CustomMany2One.onMounted1');
// 当光标聚焦于输入框时,选中输入框内容 // 当光标聚焦于输入框时,选中输入框内容
this.input.el.addEventListener('focus', function () { this.input.el.addEventListener('focus', function () {
this.select(); this.select();

View File

@@ -5,10 +5,10 @@ import {_lt} from "@web/core/l10n/translation";
import {standardFieldProps} from "@web/views/fields/standard_field_props"; import {standardFieldProps} from "@web/views/fields/standard_field_props";
import {session} from "@web/session"; import {session} from "@web/session";
import core from 'web.core'; // import core from 'web.core';
var QWeb = core.qweb; // var QWeb = core.qweb;
import {Component} from "@odoo/owl"; import {Component} from "@odoo/owl";
@@ -42,8 +42,8 @@ export class StepViewer extends Component {
// url = "web_widget_model_viewer/static/src/images/not_model.png"; // url = "web_widget_model_viewer/static/src/images/not_model.png";
} }
} else { } else {
var oImg = document.getElementsByClassName('test')[0] // var oImg = document.getElementsByClassName('test')[0]
console.log(oImg) // console.log(oImg)
} }
} }
} }

View File

@@ -25,4 +25,3 @@
'application': True, 'application': True,
'images': ['static/description/banner.png'], 'images': ['static/description/banner.png'],
} }

View File

@@ -5,8 +5,10 @@ from odoo import api, fields, models, modules
class ResConfigSettings(models.TransientModel): class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings' _inherit = 'res.config.settings'
style = fields.Selection([('default', 'Default'), ('left', 'Left'), ('right', 'Right'), ('middle', 'Middle')], help='Select Background Theme') style = fields.Selection([('default', 'Default'), ('left', 'Left'), ('right', 'Right'), ('middle', 'Middle')],
background = fields.Selection([('image', 'Image'), ('color', 'Color')], default='color', help='Select Background Theme') help='Select Background Theme')
background = fields.Selection([('image', 'Image'), ('color', 'Color')], default='color',
help='Select Background Theme')
background_image = fields.Many2one('login.image', string="Image", help='Select Background Image For Login Page') background_image = fields.Many2one('login.image', string="Image", help='Select Background Image For Login Page')
color = fields.Char(string="Color", help="Choose your Background color") color = fields.Char(string="Color", help="Choose your Background color")

View File

@@ -1,2 +1,2 @@
# -*-coding:utf-8-*- # -*-coding:utf-8-*-
from .import report from . import report

View File

@@ -1,2 +1,2 @@
# -*-coding:utf-8-*- # -*-coding:utf-8-*-
from .import common from . import common

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from odoo import models
import ctypes import ctypes
from odoo import models
class Common(models.Model): class Common(models.Model):
@@ -19,6 +19,3 @@ class Common(models.Model):
tsclibrary.closeport(); tsclibrary.closeport();
except Exception as e: except Exception as e:
raise UserWarning("错误警告") raise UserWarning("错误警告")