Merge branch refs/heads/develop into refs/heads/feature/修改机床参数bug

This commit is contained in:
龚启豪
2023-11-23 16:37:53 +08:00
47 changed files with 1633 additions and 1549 deletions

View File

@@ -11,7 +11,7 @@ var Dialog = require('web.Dialog');
patch(FormStatusIndicator.prototype, 'jikimo_frontend.FormStatusIndicator', {
// 你可以重写或者添加一些方法和属性
async _onDiscardChanges() {
var self = this;
// var self = this;
Dialog.confirm(this, _t("Are you sure you want to 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?")) {
// await this.props.discard();
// }
const result = await this._confirmDiscardChange();
// const result = await this._confirmDiscardChange();
await this._confirmDiscardChange();
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
// render + patch which would occur on the next frame and cause flickering.
freezeColumnWidths() {
console.log('ccccccccccccccccccccccccccc')
// console.log('ccccccccccccccccccccccccccc')
if (!this.keepColumnWidths) {
this.columnWidths = null;
}
@@ -45,7 +45,8 @@ patch(ListRenderer.prototype, 'jikimo_frontend.ListRenderer', {
setDefaultColumnWidths(column_num) {
// const bbb = this.state.columns[0].name
const widths = this.state.columns.map((col) => this.calculateColumnWidth(col));
const widths = this.state.columns.map((col) =>
this.calculateColumnWidth(col));
// const sumOfRelativeWidths = (widths
// .filter(({ type }) => type === "relative")
// .reduce((sum, { value }) => sum + value, 0));
@@ -65,16 +66,19 @@ patch(ListRenderer.prototype, 'jikimo_frontend.ListRenderer', {
// }
// 判断 this.state.columns 是否存在且长度大于零
if (this.state.columns && this.state.columns.length > 0 && this.state.columns[0].name === "sequence") {
if (this.state.columns && this.state.columns.length > 0 &&
this.state.columns[0].name === "sequence") {
widths[1] = { type: "relative", value: 0.1 };
}
// 1 because nth-child selectors are 1-indexed, 2 when the first column contains
// 1 because nth-child selectors are 1-indexed,
// 2 when the first column contains
// the checkboxes to select records.
const columnOffset = this.hasSelectors ? 2 : 1;
widths.forEach(({ type, value }, i) => {
const headerEl = this.tableRef.el.querySelector(`th:nth-child(${i + columnOffset})`);
widths.forEach(({ type, value }, width) => {
const headerEl = this.tableRef.el.querySelector(
`th:nth-child(${width + columnOffset})`);
if (type === "absolute") {
if (this.isEmpty) {
headerEl.style.width = value;
@@ -82,7 +86,8 @@ patch(ListRenderer.prototype, 'jikimo_frontend.ListRenderer', {
headerEl.style.minWidth = value;
}
} else if (type === "relative" && this.isEmpty) {
headerEl.style.width = `${((value / column_num) * 100).toFixed(2)}%`;
headerEl.style.width = `${((value / column_num) * 100
).toFixed(2)}%`;
}
});
},

View File

@@ -1,8 +1,8 @@
import requests
import json
from odoo import models, fields, api
from odoo.addons.sf_base.commons.common import Common
from odoo.exceptions import ValidationError
import requests
import json
class FunctionalFixtureType(models.Model):
@@ -62,7 +62,8 @@ class FunctionalFixture(models.Model):
def _get_name(self):
for record in self:
if record.type:
if not record.transfer_tray_model_ids and not record.pneumatic_tray_model_ids and not record.magnetic_tray_model_ids and not record.vice_tray_model_ids:
if not record.transfer_tray_model_ids and not record.pneumatic_tray_model_ids and \
not record.magnetic_tray_model_ids and not record.vice_tray_model_ids:
record.name = ''
if record.transfer_tray_model_ids:
for i in record.transfer_tray_model_ids:

View File

@@ -2,11 +2,6 @@
from odoo import fields, models, api
# from datetime import datetime
# from odoo.exceptions import ValidationError
# 刀具物料
class CuttingToolMaterial(models.Model):
_name = 'sf.cutting.tool.material'
_description = '刀具物料'
@@ -28,57 +23,6 @@ class FunctionalCuttingTool(models.Model):
mrs_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='刀具型号')
# # 整体式刀具型号
# mrs_cutting_tool_integral_model_ids = fields.Many2many('sf.cutting.tool.model', 'rel_integral_model_functional_sf',
# string='整体式刀具型号', domain=
# [('cutting_tool_type', '=', '整体式刀具')])
# # 刀片型号
# mrs_cutting_tool_blade_model_ids = fields.Many2many('sf.cutting.tool.model', 'rel_blade_model_functional_sf',
# string='刀片型号', domain=
# [('cutting_tool_type', '=', '刀片')])
# # 刀杆型号
# mrs_cutting_tool_cutterbar_model_ids = fields.Many2many('sf.cutting.tool.model',
# 'rel_cutterbar_model_functional_sf',
# string='刀杆型号', domain=
# [('cutting_tool_type', '=', '刀杆')])
# # 刀盘型号
# mrs_cutting_tool_cutterpad_model_ids = fields.Many2many('sf.cutting.tool.model',
# 'rel_cutterpad_model_functional_sf',
# string='刀盘型号', domain=
# [('cutting_tool_type', '=', '刀盘')])
# # 刀柄型号
# mrs_cutting_tool_cutterhandle_model_ids = fields.Many2many('sf.cutting.tool.model',
# 'rel_cutterhandle_model_functional_sf',
# string='刀柄型号',
# domain=
# [('cutting_tool_type', '=', '刀柄')])
# # 夹头型号
# mrs_cutting_tool_cutterhead_model_ids = fields.Many2many('sf.cutting.tool.model',
# 'rel_cutterhead_model_functional_sf',
# string='夹头型号', domain=
# [('cutting_tool_type', '=', '夹头')])
#
# diameter = fields.Float('直径(mm)')
# tool_grade = fields.Selection([('1', 'P1'), ('2', 'P2'), ('3', 'P3'), ('4', 'P4'), ('5', 'P5'), ('6', 'P6')],
# string='刀具等级')
# machining_accuracy = fields.Float('加工精度(mm)')
# tool_length = fields.Float('装刀长')
# blade_number = fields.Integer('刃数')
# integral_blade_length = fields.Float('整体刃长(mm)')
# effective_blade_length = fields.Float('有效刃长(mm)')
# max_life = fields.Float('最大寿命值')
# is_standard = fields.Boolean('是否标准刀')
# applicable_range = fields.Char('适用范围')
# image = fields.Binary('图片')
# active = fields.Boolean('有效', default=True)
#
# def _get_functional_tool_model_ids(self, functional_tool_model_code):
# functional_tool_model_ids = []
# for item in functional_tool_model_code:
# functional_tool_model = self.env['sf.cutting.tool.model'].search([('code', '=', item)])
# functional_tool_model_ids.append(functional_tool_model.id)
# return [(6, 0, functional_tool_model_ids)]
# 功能刀具类型
class FunctionalCuttingToolModel(models.Model):

View File

@@ -53,7 +53,8 @@ class ToolMaterialsBasicParameters(models.Model):
top_angle = fields.Integer('顶角(°)')
blade_tip_dip_angle = fields.Integer('刀尖倾角(°)')
side_cutting_edge_angle = fields.Integer('侧切削角(°)')
thread_model = fields.Selection([('', ''), ('外螺纹', '外螺纹'), ('内螺纹', '内螺纹')], string='螺纹类型', default='')
thread_model = fields.Selection([('', ''), ('外螺纹', '外螺纹'), ('内螺纹', '内螺纹')], string='螺纹类型',
default='')
thread_num = fields.Float('每英寸螺纹数(tpi)')
blade_tip_height_tolerance = fields.Char('刀尖高度公差(mm)', size=20)
inscribed_circle_tolerance = fields.Char('内接圆公差(mm)', size=20)
@@ -199,8 +200,8 @@ class ToolMaterialsBasicParameters(models.Model):
'is_cooling_hole': obj['is_cooling_hole'],
'locating_slot_code': obj['locating_slot_code'],
'installing_structure': obj['installing_structure'],
'blade_ids': [(6, 0, [])] if not obj.get('blade_codes') else self.evn['sf.cutting_tool.standard.library']._get_ids(
obj['blade_codes']),
'blade_ids': [(6, 0, [])] if not obj.get('blade_codes') else
self.evn['sf.cutting_tool.standard.library']._get_ids(obj['blade_codes']),
'tool_shim': obj['tool_shim'],
'cotter_pin': obj['cotter_pin'],
'pressing_plate': obj['pressing_plate'],
@@ -222,8 +223,8 @@ class ToolMaterialsBasicParameters(models.Model):
'cutting_depth': obj['cutting_depth'],
'main_included_angle': obj['main_included_angle'],
'installing_structure': obj['installing_structure'],
'blade_ids': [(6, 0, [])] if not obj.get('blade_codes') else self.evn['sf.cutting_tool.standard.library']._get_ids(
obj['blade_codes']),
'blade_ids': [(6, 0, [])] if not obj.get('blade_codes') else
self.evn['sf.cutting_tool.standard.library']._get_ids(obj['blade_codes']),
'screw': obj['screw'],
'spanner': obj['spanner'],
'cutting_blade_model': obj['cutting_blade_model'],

View File

@@ -38,5 +38,33 @@
</record>
<record model="ir.module.category" id="module_category_plan">
<field name="name">计划</field>
<field name="sequence">20</field>
</record>
<record id="sales_team.group_sale_manager" model="res.groups">
<field name="name">销售经理</field>
<field name="category_id" ref="base.module_category_sales_sales"/>
<!-- <field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>-->
</record>
<!-- <record id="group_sale_director" model="res.groups">-->
<!-- <field name="name">销售总监</field>-->
<!-- <field name="category_id" ref="base.module_category_sales_sales"/>-->
<!-- <field name="implied_ids" eval="[(4, ref('sf_base.group_sale_manager'))]"/>-->
<!-- </record>-->
<record id="group_plan_dispatch" model="res.groups">
<field name="name">计划调度岗</field>
<field name="category_id" ref="module_category_plan"/>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
</record>
<record id="group_plan_director" model="res.groups">
<field name="name">计划总监</field>
<field name="category_id" ref="module_category_plan"/>
<field name="implied_ids" eval="[(4, ref('sf_base.group_plan_dispatch'))]"/>
</record>
</data>
</odoo>

View File

@@ -1,2 +1,3 @@
from .import controllers

View File

@@ -59,7 +59,7 @@ class Sf_Bf_Connect(http.Controller):
self_machining_bom_line = self_machining_bom.with_user(
request.env.ref("base.user_admin")).bom_create_line(
self_machining_embryo)
if self_machining_bom_line == False:
if not self_machining_bom_line:
res['status'] = 2
res['message'] = '该订单模型的材料型号在您分配的工厂里暂未有原材料,请先配置再进行分配'
request.cr.rollback()
@@ -84,7 +84,7 @@ class Sf_Bf_Connect(http.Controller):
# 创建坯料的bom的组件
outsource_bom_line = outsource_bom.with_user(
request.env.ref("base.user_admin")).bom_create_line(outsource_embryo)
if outsource_bom_line == False:
if not outsource_bom_line:
res['status'] = 2
res['message'] = '该订单模型的材料型号在您分配的工厂里暂未有原材料,请先配置再进行分配'
request.cr.rollback()

View File

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

View File

@@ -1,10 +1,8 @@
from datetime import datetime
import logging
import requests
from odoo import api, fields, models, SUPERUSER_ID, _
from odoo.exceptions import UserError
from odoo.exceptions import ValidationError
from collections import defaultdict, namedtuple
from odoo import fields, models
_logger = logging.getLogger(__name__)
@@ -197,7 +195,8 @@ class FinishStatusChange(models.Model):
if self.user_has_groups('stock.group_reception_report') \
and self.picking_type_id.auto_show_reception_report:
lines = self.move_ids.filtered(lambda
m: m.product_id.type == 'product' and m.state != 'cancel' and m.quantity_done and not m.move_dest_ids)
m: m.product_id.type == 'product' and m.state != 'cancel'
and m.quantity_done and not m.move_dest_ids)
if lines:
# don't show reception report if all already assigned/nothing to assign
wh_location_ids = self.env['stock.location']._search(

View File

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

View File

@@ -22,10 +22,11 @@
'views/ftp_button.xml',
'views/compensation.xml',
# 只有它被屏蔽了
# 'views/SfWorkOrderBarcodes.xml',
'views/WorkCenterBarcodes.xml',
'views/Stock_picking_Barcodes.xml',
# 'views/machine_monitor.xml',
'views/machine_monitor.xml',
'views/machine_info_present.xml',
'views/delivery_record.xml',
'views/res_config_settings_views.xml',
@@ -39,7 +40,7 @@
],
},
'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,
'application': True,

View File

@@ -60,11 +60,11 @@ class FtpButton(models.Model):
raise UserError("补偿值写入执行超时,请检查机床状态或者写入状态")
# host="192.168.2.158", port=8080, username="MITSUBISHI", password="CNC"
host = self.workorder_id.workcenter_id.machine_tool_id.ftp_host
port = self.workorder_id.workcenter_id.machine_tool_id.ftp_port
username = self.workorder_id.workcenter_id.machine_tool_id.ftp_num
pwd = self.workorder_id.workcenter_id.machine_tool_id.ftp_pwd
remote_path = self.workorder_id.workcenter_id.machine_tool_id.ftp_remote_path
host = self.workorder_id.equipment_id.ftp_host
port = self.workorder_id.equipment_id.ftp_port
username = self.workorder_id.equipment_id.ftp_num
pwd = self.workorder_id.equipment_id.ftp_pwd
remote_path = self.workorder_id.equipment_id.ftp_remote_path
print(host, port, username, pwd, remote_path)
ftp = ftp_operate.FtpController(host, port, username, pwd)
# ftp.delAllfile('C://Users//马广威//Desktop//ftp')
@@ -107,8 +107,8 @@ class FtpButton(models.Model):
下发NC代码前自动补偿三元检测偏差值
:return:
"""
hongbianliang550 = self.workorder_id.workcenter_id.machine_tool_id.x_compensation_node
hongbianliang551 = self.workorder_id.workcenter_id.machine_tool_id.y_compensation_node
hongbianliang550 = self.workorder_id.equipment_id.x_compensation_node
hongbianliang551 = self.workorder_id.equipment_id.y_compensation_node
try:
temp_dict = {}
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相关
@@ -263,7 +263,7 @@ class WorkCenterBarcode(models.Model):
compensation_value_y = fields.Float(string='Y轴补偿值')
button_compensation_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_type_id = fields.Char(string='机床型号', default='未知型号', 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)
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):
# self.machine_tool_name = '1号机床'
self.machine_tool_name = self.workcenter_id.machine_tool_id.name
self.machine_tool_type_id = self.workcenter_id.machine_tool_id.type_id.name
self.machine_tool_status = self.workcenter_id.machine_tool_id.status
self.machine_tool_run_status = self.workcenter_id.machine_tool_id.run_status
self.machine_tool_timestamp = self.workcenter_id.machine_tool_id.timestamp
self.machine_tool_time_on = self.workcenter_id.machine_tool_id.time_on
self.machine_tool_time_on_now = self.workcenter_id.machine_tool_id.time_on_now
self.machine_tool_tool_num = self.workcenter_id.machine_tool_id.tool_num
self.machine_tool_program = self.workcenter_id.machine_tool_id.program
self.machine_tool_machine_ip = self.workcenter_id.machine_tool_id.machine_ip
self.machine_tool_cut_status = self.workcenter_id.machine_tool_id.cut_status
self.machine_tool_name = self.equipment_id.name
self.machine_tool_type_id = self.equipment_id.type_id.name
self.machine_tool_status = self.equipment_id.status
self.machine_tool_run_status = self.equipment_id.run_status
self.machine_tool_timestamp = self.equipment_id.timestamp
self.machine_tool_time_on = self.equipment_id.time_on
self.machine_tool_time_on_now = self.equipment_id.time_on_now
self.machine_tool_tool_num = self.equipment_id.tool_num
self.machine_tool_program = self.equipment_id.program
self.machine_tool_machine_ip = self.equipment_id.machine_ip
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_y = self.compensation_value_y
def compensation(self):
hongbianliang550 = self.workcenter_id.machine_tool_id.x_compensation_node
hongbianliang551 = self.workcenter_id.machine_tool_id.y_compensation_node
hongbianliang550 = self.equipment_id.x_compensation_node
hongbianliang551 = self.equipment_id.y_compensation_node
try:
temp_dict = {}
temp_dict[hongbianliang550] = self.compensation_value_x
@@ -339,11 +339,11 @@ class WorkCenterBarcode(models.Model):
except Exception:
raise UserError("补偿值写入执行超时,请检查机床状态或者写入状态")
sequence_collect = []
host = self.workcenter_id.machine_tool_id.ftp_host
port = self.workcenter_id.machine_tool_id.ftp_port
username = self.workcenter_id.machine_tool_id.ftp_num
pwd = self.workcenter_id.machine_tool_id.ftp_pwd
remote_path = self.workcenter_id.machine_tool_id.ftp_remote_path
host = self.equipment_id.ftp_host
port = self.equipment_id.ftp_port
username = self.equipment_id.ftp_num
pwd = self.equipment_id.ftp_pwd
remote_path = self.equipment_id.ftp_remote_path
_logger.info("=====================1666666661111================%s,%s,%s,%s" % (host, port, username, pwd))
ftp = ftp_operate.FtpController(host, port, username, pwd)
_logger.info("=====================1777777777111================")
@@ -403,11 +403,11 @@ class WorkCenterBarcode(models.Model):
except Exception:
raise UserError("补偿值写入执行超时,请检查机床状态或者写入状态")
sequence_collect = []
host = self.workcenter_id.machine_tool_id.ftp_host
port = self.workcenter_id.machine_tool_id.ftp_port
username = self.workcenter_id.machine_tool_id.ftp_num
pwd = self.workcenter_id.machine_tool_id.ftp_pwd
remote_path = self.workcenter_id.machine_tool_id.ftp_remote_path
host = self.equipment_id.ftp_host
port = self.equipment_id.ftp_port
username = self.equipment_id.ftp_num
pwd = self.equipment_id.ftp_pwd
remote_path = self.equipment_id.ftp_remote_path
_logger.info("=====================1666666661111================%s,%s,%s,%s" % (host, port, username, pwd))
ftp = ftp_operate.FtpController(host, port, username, pwd)
_logger.info("=====================1777777777111================")

View File

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

View File

@@ -10,7 +10,7 @@ class ResBFMConfigSettings(models.TransientModel):
bfm_url = fields.Selection(
[("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", "正式环境(https://bfm.jikimo.com)")], string='bfm环境', store=True)

View File

@@ -1,7 +1,7 @@
/** @odoo-module **/
import { browser } from "@web/core/browser/browser";
import * as BarcodeScanner from "@web/webclient/barcode/barcode_scanner";
// import { browser } from "@web/core/browser/browser";
// import * as BarcodeScanner from "@web/webclient/barcode/barcode_scanner";
const { Component } = owl;
import { standardFieldProps } from "@web/views/fields/standard_field_props";
import {registry} from "@web/core/registry";
@@ -23,19 +23,19 @@ export class CodeField extends Component {
this.record = this.props.record;
}
async onBarcodeBtnClick() {
const barcode = await BarcodeScanner.scanBarcode();
if (barcode) {
await this.onBarcodeScanned(barcode);
if ("vibrate" in browser.navigator) {
browser.navigator.vibrate(100);
}
} else {
this.notification.add(this.env._t("Please, scan again !"), {
type: "warning",
});
}
}
// async onBarcodeBtnClick() {
// const barcode = await BarcodeScanner.scanBarcode();
// if (barcode) {
// await this.onBarcodeScanned(barcode);
// if ("vibrate" in browser.navigator) {
// browser.navigator.vibrate(100);
// }
// } else {
// this.notification.add(this.env._t("Please, scan again !"), {
// type: "warning",
// });
// }
// }
async search(barcode) {
// alert('我是search')
const domain = [["code", "=", barcode]];
@@ -65,33 +65,33 @@ export class CodeField extends Component {
// console.log('currentModel',this)
// console.log('this.record.data',this.record.data)
// console.log('this.record.data.id', this.record.data.id)
const workorder = await this.orm.call('mrp.workorder', 'read', [this.record.data.id]);
// const workorder = await this.orm.call('mrp.workorder', 'read', [this.record.data.id]);
// console.log('workorder', workorder[0])
const updatedRecord = await this.orm.call("sf.tray", "write", [
[records[0].id],
{
state: "占用",
workorder_id: workorder[0].id,
production_id: workorder[0].product_id[0],
// workorder_id: workorder.id,
}]);
// const updatedRecord = await this.orm.call("sf.tray", "write", [
// [records[0].id],
// {
// state: "占用",
// workorder_id: workorder[0].id,
// production_id: workorder[0].product_id[0],
// // workorder_id: workorder.id,
// }]);
// console.log(workorder[0].routing_type);
// console.log(workorder[0].production_id);
// const productionIDS = await this.orm.call('mrp.production', 'search', [[['id', '=', workorder[0].production_id[0]]]]);
const productionIDS = await this.orm.call('mrp.workorder', 'search', [[["production_id", "=", workorder[0].production_id[0]]]]);
// const productionIDS = await this.orm.call('mrp.workorder', 'search', [[["production_id", "=", workorder[0].production_id[0]]]]);
// console.log('prooooooo', productionIDS);
// console.log('values', records[0].values[0]);
productionIDS.forEach(async (data) => {
// 处理每一个数据
// console.log(data);
const updatetrayRecord = await this.orm.call("mrp.workorder", "write", [
[data],
{
tray_id: records[0].values[0].id,
// tray_id: false,
}]);
// console.log(updatetrayRecord)
});
// productionIDS.forEach(async (data) => {
// // 处理每一个数据
// // console.log(data);
// const updatetrayRecord = await this.orm.call("mrp.workorder", "write", [
// [data],
// {
// tray_id: records[0].values[0].id,
// // tray_id: false,
// }]);
// // console.log(updatetrayRecord)
// });
this.props.update(records[0].code);
$('.o_form_button_save').click();
} else {

View File

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

View File

@@ -56,7 +56,7 @@ export class BarcodeHandlerField extends Component {
// });
await this.actionService.doAction(response.result);
} 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>
<record id="view_tree_mrs_machine_tool_inherited" model="ir.ui.view">
<field name="name">sf_base_extension</field>
<field name="model">sf.machine_tool</field>
<field name="inherit_id" ref="sf_base.sf_machine_tool_form"/>
<field name="model">maintenance.equipment</field>
<field name="inherit_id" ref="sf_maintenance.sf_hr_equipment_view_form"/>
<field eval="20" name="priority"/>
<field name="arch" type="xml">
<!-- <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">-->
<notebook>
<!-- <notebook> -->
<page string="机床监控">
<group string='状态监控'>
<group>
@@ -256,49 +256,51 @@
</group>
</group>
</page>
</notebook>
<!-- </notebook> -->
</xpath>
</field>
</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>
<field name="predict_life_time"/>
<!-- 刀具寿命 -->
<!-- <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_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>
<field name='is_connect_tool_position' invisible='1'/>
<button string="绑定刀位" name="tool_connect_machine" type="object" confirm="是否确认绑定此刀位"
class="btn-primary"/>
<!-- <div> -->
<!-- <div> -->
<!-- <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","!=", -->
<!-- "False")]}' -->
<span>&#32;</span>
<button string="解绑刀位" name="tool_unconnect_machine" type="object" confirm="是否解绑此刀位"
class="btn-primary"/>
<!-- <span>&#32;</span> -->
<!-- <button string="解绑刀位" name="tool_unconnect_machine" type="object" confirm="是否解绑此刀位" -->
<!-- class="btn-primary"/> -->
<!-- attrs='{"invisible": [("is_connect_tool_position","!=", -->
<!-- "False")]}' -->
</div>
<!-- </div> -->
</div>
</group>
</xpath>
</field>
</record>
<!-- </div> -->
<!-- </group> -->
<!-- </xpath> -->
<!-- </field> -->
<!-- </record> -->
</odoo>

View File

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

View File

@@ -17,7 +17,6 @@
'security/ir.model.access.csv',
'views/mrp_views_menus.xml',
'views/mrp_production_addional_change.xml',
# 'views/mrp_maintenance_views.xml',
'views/mrp_routing_workcenter_view.xml',
'views/production_line_view.xml',
'views/mrp_workcenter_views.xml',
@@ -25,7 +24,6 @@
'views/model_type_view.xml',
'views/sf_maintenance_equipment.xml',
],
'assets': {

View File

@@ -120,7 +120,7 @@ class MrpProduction(models.Model):
if i == 1 and route.routing_type == '获取CNC加工程序':
workorders_values.append(
self.env['mrp.workorder'].json_workorder_str('', production, route))
if route.is_repeat == True:
if route.is_repeat is True:
workorders_values.append(
self.env['mrp.workorder'].json_workorder_str(k, production, route))
if i == processing_panel_len and route.routing_type == '解除装夹':

View File

@@ -1,5 +1,5 @@
from odoo import fields, models
import logging
from odoo import fields, models
class ResMrpRoutingWorkcenter(models.Model):

View File

@@ -1,6 +1,6 @@
from odoo import api, fields, models
from datetime import datetime
import datetime
from collections import defaultdict
from odoo import fields, models
from odoo.addons.resource.models.resource import Intervals

View File

@@ -1,9 +1,8 @@
import os
import json
import base64
import math
import requests
import logging
import base64
# import subprocess
from datetime import datetime
from dateutil.relativedelta import relativedelta
@@ -304,7 +303,7 @@ class ResMrpWorkOrder(models.Model):
# 验证坯料序列号是否正确
def pro_code_is_ok(self, barcode):
if barcode != False:
if barcode is not False:
if barcode != self.pro_code:
raise UserError('坯料序列号错误')
return False
@@ -623,7 +622,7 @@ class CNCprocessing(models.Model):
if os.path.splitext(f)[1] == ".pdf":
full_path = os.path.join(serverdir, root, f)
logging.info('pdf:%s' % full_path)
if full_path != False:
if full_path is not False:
if not cnc_processing.workorder_id.cnc_worksheet:
cnc_processing.workorder_id.cnc_worksheet = base64.b64encode(
open(full_path, 'rb').read())

View File

@@ -1,16 +1,13 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
from odoo.modules import get_resource_path
from odoo.addons.sf_base.commons.common import Common
from OCC.Extend.DataExchange import read_step_file
from OCC.Extend.DataExchange import write_stl_file
import logging
import base64
import hashlib
import os
import requests
import json
from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
from odoo.modules import get_resource_path
from OCC.Extend.DataExchange import read_step_file
from OCC.Extend.DataExchange import write_stl_file
class ResProductMo(models.Model):
@@ -204,16 +201,6 @@ class ResProductMo(models.Model):
self.cutting_tool_blade_depth = self.specification_id.blade_depth
self.cutting_tool_cut_depth = self.specification_id.cutting_depth
self.cutting_speed_ids = self.cutting_tool_model_id.cutting_speed_ids
# # self.feed_per_tooth_ids = self.cutting_tool_model_id.feed_per_tooth_ids.
# for tooth in self.cutting_tool_model_id.feed_per_tooth_ids:
# print(int(tooth.blade_diameter))
# print(int(self.specification_id.blade_diameter))
# if int(tooth.blade_diameter) == int(self.specification_id.blade_diameter):
# self.feed_per_tooth_ids = [(0, 0, {
# 'cutting_speed': tooth.cutting_speed,
# 'machining_method': tooth.machining_method,
# 'blade_diameter': tooth.blade_diameter,
# 'materials_type_id': tooth.materials_type_id.id})]
self.feed_per_tooth_ids = self.cutting_tool_model_id.feed_per_tooth_ids.filtered(
lambda r: int(r.blade_diameter) == int(self.specification_id.blade_diameter))
elif self.cutting_tool_type == '夹头':
@@ -298,12 +285,12 @@ class ResProductMo(models.Model):
self.cutting_tool_flange_length = self.specification_id.flange_shank_length
self.cutting_tool_shank_outer_diameter = self.specification_id.handle_external_diameter
self.cutting_tool_shank_inner_diameter = self.specification_id.handle_inside_diameter
self.suitable_machining_method_ids = [(6, 0,
[])] if not self.cutting_tool_model_id.suitable_machining_method_ids else [
(6, 0, self.cutting_tool_model_id.suitable_machining_method_ids.ids)]
self.blade_tip_characteristics_id = [(6, 0,
[])] if not self.cutting_tool_model_id.blade_tip_characteristics_id else [
(6, 0, self.cutting_tool_model_id.blade_tip_characteristics_id.ids)]
self.suitable_machining_method_ids = [(6, 0, [])] if not \
self.cutting_tool_model_id.suitable_machining_method_ids \
else [(6, 0, self.cutting_tool_model_id.suitable_machining_method_ids.ids)]
self.blade_tip_characteristics_id = [(6, 0, [])] if not \
self.cutting_tool_model_id.blade_tip_characteristics_id \
else [(6, 0, self.cutting_tool_model_id.blade_tip_characteristics_id.ids)]
self.handle_type_ids = [(6, 0,
[])] if not self.cutting_tool_model_id.handle_type_ids else [
@@ -358,89 +345,33 @@ class ResProductMo(models.Model):
self.cutting_speed_ids = False
self.feed_per_tooth_ids = False
# @api.constrains('suitable_machining_method_ids')
# def _check_suitable_machining_method_ids(self):
# for record in self:
# if len(record.suitable_machining_method_ids) == 0 and self.cutting_tool_type == '整体式刀具':
# raise ValidationError("适合加工方式不能为空!")
#
# @api.constrains('blade_tip_characteristics_ids')
# def _check_blade_tip_characteristics_ids(self):
# for record in self:
# if len(record.blade_tip_characteristics_ids) == 0 and self.cutting_tool_type == '整体式刀具':
# raise ValidationError("刀尖特征不能为空!")
# if len(record.blade_tip_characteristics_ids) > 1 and self.cutting_tool_type == '整体式刀具':
# raise ValidationError("刀尖特征只能单选!")
#
# @api.constrains('handle_type_ids')
# def _check_handle_type_ids(self):
# for record in self:
# if len(record.handle_type_ids) == 0 and self.cutting_tool_type == '整体式刀具':
# raise ValidationError("柄部类型不能为空!")
# if len(record.handle_type_ids) > 1 and self.cutting_tool_type == '整体式刀具':
# raise ValidationError("柄部类型只能单选!")
#
# @api.constrains('cutting_direction_ids')
# def _check_cutting_direction_ids(self):
# for record in self:
# if len(record.cutting_direction_ids) == 0 and self.cutting_tool_type == '整体式刀具':
# raise ValidationError("走刀方向不能为空!")
#
# @api.constrains('suitable_coolant_ids')
# def _check_suitable_coolant_ids(self):
# for record in self:
# if not record.suitable_coolant_ids and self.cutting_tool_type == '整体式刀具':
# raise ValidationError("适合冷却液不能为空!")
#
# @api.constrains('cutting_tool_total_length')
# def _check_cutting_tool_total_length(self):
# if self.cutting_tool_total_length <= 0 and self.cutting_tool_type == '整体式刀具':
# raise ValidationError("总长度不能为0")
#
# @api.constrains('cutting_tool_shank_length')
# def _check_cutting_tool_shank_length(self):
# if self.cutting_tool_shank_length <= 0 and self.cutting_tool_type == '整体式刀具':
# raise ValidationError("柄部长度不能为0")
#
# @api.constrains('cutting_tool_blade_length')
# def _check_cutting_tool_blade_length(self):
# if self.cutting_tool_blade_length <= 0 and self.cutting_tool_type == '整体式刀具':
# raise ValidationError("刃部长度不能为0")
#
# @api.constrains('cutting_tool_blade_number')
# def _check_cutting_tool_blade_number(self):
# if self.cutting_tool_blade_number <= 0 and self.cutting_tool_type == '整体式刀具':
# raise ValidationError("刃数不能为0")
#
# @api.constrains('integral_shank_diameter')
# def _check_integral_shank_diameter(self):
# if self.integral_shank_diameter <= 0 and self.cutting_tool_type == '整体式刀具':
# raise ValidationError("柄部直径不能为0")
#
# @api.constrains('integral_blade_diameter')
# def _check_integral_blade_diameter(self):
# if self.integral_blade_diameter <= 0 and self.cutting_tool_type == '整体式刀具':
# raise ValidationError("刃部直径不能为0")
#
# @api.constrains('integral_run_out_accuracy_min')
# def _check_integral_blade_diameter(self):
# if self.integral_run_out_accuracy_min <= 0 and self.cutting_tool_type == '整体式刀具':
# raise ValidationError("端跳精度最小(min)不能为0")
@api.constrains('fit_blade_shape_id', 'suitable_machining_method_ids', 'blade_tip_characteristics_id',
'handle_type_ids', 'cutting_direction_ids', 'suitable_coolant_ids', 'compaction_way_ids')
def _check_cutting_tool_ability(self):
if self.cutting_tool_type in ['整体式刀具', '刀片', '刀杆', '刀盘']:
if self.cutting_tool_type in ['刀片', '刀杆', '刀盘']:
if not self.fit_blade_shape_id:
raise ValidationError("请选择适配刀片形状")
if self.cutting_tool_type in ['刀杆', '刀盘']:
if not self.compaction_way_ids:
raise ValidationError("请选择压紧方式")
if self.cutting_tool_type == '刀片':
if not self.suitable_coolant_ids:
raise ValidationError("请选择适合冷却液")
elif self.cutting_tool_type == '整体式刀具':
if not self.handle_type_ids:
raise ValidationError("请选择柄部类型")
if not self.suitable_coolant_ids:
raise ValidationError("请选择适合冷却液")
if not self.suitable_machining_method_ids:
raise ValidationError("请选择适合加工方式")
if not self.blade_tip_characteristics_id:
raise ValidationError("请选择刀尖特征")
if not self.cutting_direction_ids:
raise ValidationError("请选择走刀方向")
cutting_speed_ids = fields.One2many('sf.cutting.speed', 'product_template_id', string='切削速度Vc')
feed_per_tooth_ids = fields.One2many('sf.feed.per.tooth', 'product_template_id', string='每齿走刀量fz')
# @api.constrains('suitable_machining_method_ids')
# def _check_suitable_machining_method_ids(self):
# for record in self:
# if len(record.suitable_machining_method_ids) == 0 and self.cutting_tool_type == '整体式刀具':
# raise ValidationError("适合加工方式不能为空!")
# @api.constrains('integral_run_out_accuracy_max')
# def _check_integral_run_out_accuracy_max(self):
# if self.integral_run_out_accuracy_max <= 0 and self.cutting_tool_type == '整体式刀具':
# raise ValidationError("端跳精度最大(max)不能为0")
cutting_tool_diameter = fields.Float('直径(mm)')
cutting_tool_rear_angle = fields.Integer('后角(°)')
cutting_tool_main_included_angle = fields.Integer('主偏角(°)')
@@ -758,26 +689,19 @@ class ResProductMo(models.Model):
'model_file': '' if not item['model_file'] else base64.b64decode(item['model_file']),
'model_name': attachment.name,
'upload_model_file': [(6, 0, [attachment.id])],
# 'tag_ids': [(6, 0, [t.id for t in account_template.tag_ids])],
# 'single_manufacturing': True,
# 'tracking': 'serial',
'list_price': item['price'],
# 'categ_id': self.env.ref('sf_dlm.product_category_finished_sf').id,
'materials_id': self.env['sf.production.materials'].search(
[('materials_no', '=', item['texture_code'])]).id,
'materials_type_id': self.env['sf.materials.model'].search(
[('materials_no', '=', item['texture_type_code'])]).id,
# 'model_surface_process_ids': self.get_production_process_id(item['surface_process_code']),
'model_process_parameters_ids': [(6, 0, [])] if not item.get(
'process_parameters_code') else self.get_process_parameters_id(item['process_parameters_code']),
'model_remark': item['remark'],
'default_code': '%s-%s' % (order_number, i),
# 'barcode': item['barcode'],
'active': True,
# 'route_ids': self._get_routes('')
}
copy_product_id.sudo().write(vals)
# product_id.product_tmpl_id.active = False
product_id.product_tmpl_id.active = False
return copy_product_id
def _get_ids(self, param):
@@ -833,12 +757,6 @@ class ResProductMo(models.Model):
'materials_id': materials_id.id,
'materials_type_id': materials_type_id.id,
'is_bfm': True,
# 'route_ids': self._get_routes(route_type),
# 'categ_id': self.env.ref('sf_dlm.product_category_embryo_sf').id,
# 'model_surface_process_id': self.env['sf.production.process'].search(
# [('process_encode', '=', item['surface_process_code'])]).id,
# 'model_process_parameters_id': self.env['sf.processing.technology'].search(
# [('process_encode', '=', item['process_parameters_code'])]).id,
'active': True
}
# 外协和采购生成的坯料需要根据材料型号绑定供应商
@@ -850,8 +768,6 @@ class ResProductMo(models.Model):
partner = self.env['res.partner'].search([('id', '=', supplier.partner_id.id)])
partner.is_subcontractor = True
no_bom_copy_product_id.write(vals)
logging.info('no_bom_copy_product_id-vals:%s' % vals)
# product_id.product_tmpl_id.active = False
return no_bom_copy_product_id
@api.model_create_multi
@@ -956,3 +872,11 @@ class SfMaintenanceEquipmentTool(models.Model):
alarm_value = fields.Char('报警值')
used_value = 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,13 +1,14 @@
# -*- coding: utf-8 -*-
import base64
from collections import defaultdict, namedtuple
import logging
import json
from re import split as regex_split
from re import findall as regex_findall
from datetime import datetime, timedelta
from re import split as regex_split
import requests
from odoo import SUPERUSER_ID, _, api, fields, models
from odoo.tools import float_compare
from collections import defaultdict, namedtuple
from odoo.addons.stock.models.stock_rule import ProcurementException
from odoo.addons.sf_base.commons.common import Common
from odoo.exceptions import UserError
@@ -517,8 +518,8 @@ class ReStockMove(models.Model):
'inner_diameter': item.product_id.cutting_tool_inner_diameter,
'cooling_suit_type_ids': item.product_id.cooling_suit_type_ids,
'er_size_model': item.product_id.cutting_tool_er_size_model,
'image': '' if not item.product_id.image_1920 else base64.b64encode(item.product_id.image_1920).decode(
'utf-8'),
'image': '' if not item.product_id.image_1920 else
base64.b64encode(item.product_id.image_1920).decode('utf-8'),
}
try:
if item.product_id.industry_code:

View File

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

View File

@@ -3,3 +3,4 @@ from . import res_config_setting
from . import sync_common

View File

@@ -18,7 +18,7 @@ class FtpController():
self.ftp.connect(host, port)
self.ftp.login(username, password)
logging.info("ftp连接成功")
except:
except Exception:
logging.info("ftp连接失败")
# 下载目录下的文件
@@ -35,7 +35,7 @@ class FtpController():
server = os.path.join(serverdir, file)
if file.find(".") != -1:
self.download_file(server, file)
except:
except Exception:
return False
# 下载指定目录下的指定文件

View File

@@ -1,16 +1,19 @@
from odoo import models, fields, api
from odoo.modules import get_resource_path
from OCC.Extend.DataExchange import read_step_file
from OCC.Extend.DataExchange import write_stl_file
from odoo.exceptions import ValidationError, UserError
from odoo.addons.sf_base.commons.common import Common
from datetime import datetime
import logging
import base64
import hashlib
import os
import json
from datetime import datetime
import requests
from OCC.Extend.DataExchange import read_step_file
from OCC.Extend.DataExchange import write_stl_file
from odoo import models, fields, api
from odoo.modules import get_resource_path
from odoo.exceptions import ValidationError, UserError
from odoo.addons.sf_base.commons.common import Common
class QuickEasyOrder(models.Model):
@@ -209,7 +212,7 @@ class QuickEasyOrder(models.Model):
self_machining_bom = self.env['mrp.bom'].bom_create(self_machining_embryo, 'normal', False)
# 创建坯料里bom的组件
self_machining_bom_line = self_machining_bom.bom_create_line(self_machining_embryo)
if self_machining_bom_line == False:
if self_machining_bom_line is False:
self.cr.rollback()
return UserError('该订单模型的材料型号在您分配的工厂里暂未有原材料,请先配置再进行分配')
# 产品配置bom
@@ -225,7 +228,7 @@ class QuickEasyOrder(models.Model):
# 创建坯料的bom的组件
outsource_bom_line = outsource_bom.with_user(
self.env.ref("base.user_admin")).bom_create_line(outsource_embryo)
if outsource_bom_line == False:
if outsource_bom_line is False:
self.cr.rollback()
return UserError('该订单模型的材料型号在您分配的工厂里暂未有原材料,请先配置再进行分配')
# 产品配置bom

View File

@@ -1,23 +1,28 @@
from odoo import models, fields
import datetime
import base64
import logging
from odoo import models, fields
class ReSaleOrder(models.Model):
_inherit = 'sale.order'
deadline_of_delivery = fields.Date('订单交期')
deadline_of_delivery = fields.Date('订单交期', tracking=True)
person_of_delivery = fields.Char('交货人')
telephone_of_delivery = fields.Char('交货人电话号码')
address_of_delivery = fields.Char('交货人地址')
payments_way = fields.Selection([('现结', '现结'), ('月结', '月结')], '结算方式', default='现结')
payments_way = fields.Selection([('现结', '现结'), ('月结', '月结')], '结算方式', default='现结', tracking=True)
pay_way = fields.Selection([('转账', '转账'), ('微信', '微信'), ('支付宝', '支付宝')], '支付方式')
payment_term_id = fields.Many2one(
comodel_name='account.payment.term',
string="交付条件",
compute='_compute_payment_term_id',
store=True, readonly=False, precompute=True, check_company=True, tracking=True,
domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]")
# 业务平台分配工厂后在智能工厂先创建销售订单
def sale_order_create(self, company_id, delivery_name, delivery_telephone, delivery_address,
deadline_of_delivery, payments_way, pay_way):
logging.info('---------sale_order_create------')
now_time = datetime.datetime.now()
partner = self.get_customer()
order_id = self.env['sale.order'].sudo().create({
@@ -63,4 +68,3 @@ class ResaleOrderLine(models.Model):
_inherit = 'sale.order.line'
model_glb_file = fields.Binary('模型的glb文件')

View File

@@ -1,6 +1,9 @@
# -*- coding: utf-8 -*-
from datetime import timedelta
from odoo import fields, models, api
from odoo import SUPERUSER_ID
from odoo.exceptions import ValidationError
# class FunctionalCuttingToolEntity(models.Model):
@@ -13,13 +16,42 @@ class FunctionalCuttingToolEntity(models.Model):
_description = '功能刀具列表'
# 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)
name = fields.Char(related='barcode_id.name')
functional_tool_name_id = fields.Many2one('product.product', string='功能刀具名称', readonly=True)
mrs_cutting_tool_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀具型号')
mrs_cutting_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型',
sf_cutting_tool_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀具型号')
sf_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
def _read_group_mrs_cutting_tool_type_id(self, categories, domain, order):
mrs_cutting_tool_type_ids = categories._search([], order=order, access_rights_uid=SUPERUSER_ID)
@@ -28,64 +60,44 @@ class FunctionalCuttingToolEntity(models.Model):
# 整体式刀具型号
cutting_tool_integral_model_id = fields.Many2one('product.product', string='整体式刀具型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '整体式刀具')])
# 刀片型号
cutting_tool_blade_model_id = fields.Many2one('product.product', string='刀片型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '刀片')])
# 刀杆型号
cutting_tool_cutterbar_model_id = fields.Many2one('product.product', string='刀杆型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '刀杆')])
# 刀盘型号
cutting_tool_cutterpad_model_id = fields.Many2one('product.product', string='刀盘型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '刀盘')])
# 刀柄型号
cutting_tool_cutterhandle_model_id = fields.Many2one('product.product', string='刀柄型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '刀柄')])
# 夹头型号
cutting_tool_cutterhead_model_id = fields.Many2one('product.product', string='夹头型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '夹头')])
diameter = fields.Float('直径(mm)')
tool_grade = fields.Selection([('1', 'P1'), ('2', 'P2'), ('3', 'P3'), ('4', 'P4'), ('5', 'P5'), ('6', 'P6')],
string='刀具等级')
machining_accuracy = fields.Float('加工精度(mm)')
tool_length = fields.Float('装刀长(mm)')
blade_number = fields.Integer('刃数')
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('图片')
whether_standard_knife = fields.Boolean(string='是否标准刀', default=True, readonly=True)
L_D_number = fields.Float(string='L/D值(mm)', readonly=True)
hiding_length = fields.Float(string='避空长(mm)', 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)
suitable_machining_method_ids = fields.Many2many('maintenance.equipment.image',
'rel_machining_product_template_tool_entity', '适合加工方式',
domain=[('type', '=', '加工能力')],
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', '刀尖特征',
domain=[('type', '=', '刀尖特征')],
related='cutting_tool_integral_model_id.blade_tip_characteristics_id')
handle_type_ids = fields.Many2many('maintenance.equipment.image',
'rel_handle_product_template_tool_entity', '柄部类型',
domain=[('type', '=', '柄部类型')],
related='cutting_tool_integral_model_id.handle_type_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')
suitable_machining_method_ids = fields.Many2many(
'maintenance.equipment.image', 'rel_machining_product_template_tool_entity', '适合加工方式',
domain=[('type', '=', '加工能力')], 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', '刀尖特征',
domain=[('type', '=', '刀尖特征')], related='cutting_tool_integral_model_id.blade_tip_characteristics_id')
handle_type_ids = fields.Many2many(
'maintenance.equipment.image', 'rel_handle_product_template_tool_entity', '柄部类型',
domain=[('type', '=', '柄部类型')], related='cutting_tool_integral_model_id.handle_type_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):
functional_tool_model_ids = []
@@ -94,110 +106,49 @@ class FunctionalCuttingToolEntity(models.Model):
functional_tool_model_ids.append(functional_tool_model.id)
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
class FunctionalToolWarning(models.Model):
_name = 'sf.functional.tool.warning'
_description = '功能刀具预警'
functional_cutting_tool_id = fields.Many2one('sf.functional.cutting.tool.entity', '功能刀具', readonly=True)
functional_tool_assembly_id = fields.Many2one('sf.functional.tool.assembly', '功能刀具组装', readonly=True)
# 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')
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,
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('装刀长', 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,
name = fields.Char('名称', invisible=True, readonly=True, related='functional_tool_name_id.name')
# 机床信息
production_line_id = fields.Many2one('sf.production.line', string='生产线',
group_expand='_read_group_machine_table_name_ids')
maintenance_equipment_id = fields.Many2one('maintenance.equipment', string='CNC机床')
machine_tool_code = fields.Char(string='机台号')
machine_table_type_id = fields.Many2one('maintenance.equipment.category', string='机床类型')
cutter_spacing_code_id = fields.Many2one('maintenance.equipment.tool', string='刀位号',
domain="[('equipment_id', '=', maintenance_equipment_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='功能刀具类型')
diameter = fields.Integer(string='刀具直径(mm)')
knife_tip_r_angle = fields.Float(string='刀尖R角(mm)')
# 其他信息
install_tool_time = fields.Datetime("刀具组装时间")
on_board_time = fields.Datetime('上机装刀时间')
max_lifetime_value = fields.Integer(string='最大寿命值(min)')
alarm_value = fields.Integer(string='报警值(min)')
used_value = fields.Integer(string='已使用值(min)')
functional_tool_status = fields.Selection([('正常', '正常'), ('报警', '报警'), ('已拆除', '已拆除')], string='状态')
alarm_time = fields.Char('报警时间')
dispose_user = fields.Char('处理人')
dispose_time = fields.Char('处理时间')
dispose_func = fields.Char('处理方法/措施', readonly=False)
@api.model
def _read_group_machine_table_name_ids(self, categories, domain, order):
machine_table_name_ids = categories._search([], order=order, access_rights_uid=SUPERUSER_ID)
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')
def onchange_functional_cutting_tool_id(self):
print(self.functional_cutting_tool_id.name)
class RealTimeDistributionOfFunctionalTools(models.Model):
_name = 'sf.real.time.distribution.of.functional.tools'
@@ -221,60 +172,61 @@ class RealTimeDistributionOfFunctionalTools(models.Model):
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')
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', readonly=True)
name = fields.Char('名称', invisible=True, readonly=True)
functional_tool_name_id = fields.Many2one('product.product', string='功能刀具名称', readonly=True)
# 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(
'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,
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,
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,
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,
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,
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')
diameter = fields.Float('直径(mm)', readonly=True)
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')
string='刀具等级', readonly=True)
machining_accuracy = fields.Float('加工精度(mm)', readonly=True)
tool_length = fields.Float('装刀长(mm)', readonly=True)
blade_number = fields.Integer('刃数', readonly=True)
integral_blade_length = fields.Float('整体刃长(mm)', readonly=True)
effective_blade_length = fields.Float('有效刃长(mm)', readonly=True)
max_life = fields.Float('最大寿命值', readonly=True)
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')
applicable_range = fields.Char('适用范围', readonly=True)
image = fields.Binary('图片', readonly=True)
@api.depends('functional_cutting_tool_id')
def _compute_functional_cutting_tool_id(self):
@@ -304,7 +256,8 @@ class RealTimeDistributionOfFunctionalTools(models.Model):
def _compute_return_total(self):
for record in self:
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')
def _compute_total(self):
@@ -335,58 +288,47 @@ class InboundAndOutboundRecordsOfFunctionalTools(models.Model):
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')
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', readonly=True)
name = fields.Char('名称', invisible=True, readonly=True)
functional_tool_name_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', '=', '整体式刀具')],
related='functional_cutting_tool_id.cutting_tool_integral_model_id')
domain=[('cutting_tool_material_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')
domain=[('cutting_tool_material_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')
domain=[('cutting_tool_material_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')
domain=[('cutting_tool_material_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')
domain=[('cutting_tool_material_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')
domain=[('cutting_tool_material_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')],
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')
machining_accuracy = fields.Float('加工精度(mm)', readonly=True)
tool_length = fields.Float('装刀长(mm)', readonly=True)
blade_number = fields.Integer('刃数', readonly=True)
integral_blade_length = fields.Float('整体刃长(mm)', readonly=True)
effective_blade_length = fields.Float('有效刃长(mm)', readonly=True)
max_life = fields.Float('最大寿命值', readonly=True)
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')
applicable_range = fields.Char('适用范围', readonly=True)
image = fields.Binary('图片', readonly=True)
@api.depends('functional_cutting_tool_id')
def _compute_functional_cutting_tool_id(self):
@@ -436,110 +378,135 @@ class InboundAndOutboundRecords(models.Model):
class MachineTableToolChangingApply(models.Model):
_name = 'sf.machine.table.tool.changing.apply'
_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)
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,
compute='_compute_machine_table_type_id')
machine_tool_code = fields.Char(string='机台号', store=True, invisible=True, readonly=True)
cutter_spacing_code = fields.Char(string='刀位号', readonly=False, required=True)
@api.depends('name')
def _compute_machine_table_type_id(self):
for record in self:
if record:
record.machine_table_type_id = record.name.category_id.id
record.machine_tool_code = record.name.code
else:
record.machine_table_type_id = None
record.machine_tool_code = None
cutter_spacing_code_id = fields.Many2one('maintenance.equipment.tool', string='刀位号', readonly=False,
required=True, domain="[('equipment_id', '=', maintenance_equipment_id)]")
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号',
domain=[('product_id.name', '=', '功能刀具')])
functional_tool_name_id = fields.Many2one('product.product', string='功能刀具名称',
domain=[('name', '=', '功能刀具')])
functional_tool_name = fields.Char(string='功能刀具名称')
functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型')
functional_tool_name_id = fields.Many2one('product.product', string='功能刀具',
domain=[('name', '=', '功能刀具')])
tool_position_interface_type = fields.Selection(
[('BT刀柄式', 'BT刀柄式'), ('SK刀柄式', 'SK刀柄式'), ('HSK刀柄式', 'HSK刀柄式'),
('CAT刀柄式', 'CAT刀柄式'), ('ISO刀盘式', 'ISO刀盘式'), ('DIN刀盘式', 'DIN刀盘式'),
('直装固定式', '直装固定式')], string='刀位接口型号', required=True)
diameter = fields.Integer(string='刀具直径(mm)', )
knife_tip_r_angle = fields.Float(string='刀尖R角(mm)')
max_lifetime_value = fields.Integer(string='最大寿命值(min)')
alarm_value = fields.Integer(string='报警值(min)')
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)')
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)
functional_tool_status = fields.Selection([('正常', '正常'), ('报警', '报警')], string='功能刀具状态', store=True,
default='正常', compute='_compute_functional_tool_status')
# replacement_tool_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)
used_tool_time = fields.Datetime(string='用刀时间', readonly=True)
reason_for_applying = fields.Char(string='申请原因', readonly=True)
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
def _read_group_names(self, categories, domain, order):
names = categories._search([], order=order, access_rights_uid=SUPERUSER_ID)
return categories.browse(names)
@api.onchange('functional_tool_status')
@api.constrains('functional_tool_status')
def automation_apply_for_tool_change(self):
"""
自动申请换刀
:return:
"""
# 更新数据到机台换刀申请界面
# todo 自动换刀申请条件需补充完善
if self.functional_tool_status == '异常':
self.env['sf.machine.table.tool.changing.apply'].search([
('name', '=', self.name.id)]).write({
'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'
})
if self.functional_tool_status == '报警' and self.sf_functional_tool_assembly_id == False:
machine_table_tool_changing_apply = self.env['sf.machine.table.tool.changing.apply'].search(
[('maintenance_equipment_id', '=', self.maintenance_equipment_id.id),
('cutter_spacing_code_id', '=', self.cutter_spacing_code_id.id)
])
# 新建组装任务
self.env['sf.functional.tool.assembly'].create({
'name': self.functional_tool_name_id,
sf_functional_tool_assembly = self.env['sf.functional.tool.assembly'].create({
'functional_tool_name': self.functional_tool_name,
'functional_tool_type_id': self.functional_tool_type_id.id,
'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',
'applicant': '自动申请',
'reason_for_applying': '功能刀具状态异常',
'use_tool_time': self.used_tool_time,
'machine_tool_name': self.CNC_machine_table,
'machine_tool_code': self.machine_tool_code,
'cutter_spacing_code': self.cutter_spacing_code,
'use_tool_time': fields.Datetime.now() + timedelta(hours=4),
'production_line_name_id': self.production_line_id.id,
'machine_tool_name_id': self.maintenance_equipment_id.id,
'applicant': self.applicant,
'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': '机台报警自动换刀',
'sf_machine_table_tool_changing_apply_id': self.id
})
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
machine_table_tool_changing_apply.write(
{'status': '1',
'sf_functional_tool_assembly_id': sf_functional_tool_assembly})
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):
"""
@@ -548,21 +515,15 @@ class MachineTableToolChangingApply(models.Model):
"""
# 撤回功能刀具组装创建的任务
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()
# 撤回数据更新
self.env['sf.machine.table.tool.changing.apply'].search([('name', '=', self.name.id)]).write({
'replacement_tool_name_id': None,
'replacement_tool_type_id': None,
'replacement_tool_coarse_middle_thin': None,
'new_former': None,
'applicant': None,
'used_tool_time': None,
'reason_for_applying': None,
'remark': None,
'status': '0',
'sf_functional_tool_assembly_id': None,
self.env['sf.machine.table.tool.changing.apply'].search(
[('maintenance_equipment_id', '=', self.maintenance_equipment_id.id),
('cutter_spacing_code_id', '=', self.cutter_spacing_code_id.id)]).write(
{'status': '0',
'sf_functional_tool_assembly_id': None
})
def revocation_2(self):
@@ -571,9 +532,7 @@ class MachineTableToolChangingApply(models.Model):
:return:
"""
self.env['sf.machine.table.tool.changing.apply'].search(
[('name', '=', self.name.id)]).write({
'status': '0'
})
[('name', '=', self.name.id)]).write({'status': '0'})
class CAMWorkOrderProgramKnifePlan(models.Model):
@@ -669,12 +628,41 @@ class FunctionalToolAssembly(models.Model):
_description = '功能刀具组装单'
_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)
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', readonly=True)
functional_tool_name_id = fields.Many2one('product.product', string='功能刀具名称', readonly=True)
name = fields.Char(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)
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
def _read_group_functional_tool_type_ids(self, categories, domain, order):
@@ -682,43 +670,40 @@ class FunctionalToolAssembly(models.Model):
functional_tool_type_ids = categories._search([], order=order, access_rights_uid=SUPERUSER_ID)
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)
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')
sf_tool_brand_id_1 = fields.Many2one('sf.machine.brand', string='整体式刀具品牌', 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)
blade_name = fields.Char('刀片名称', readonly=True, compute='_compute_auto_fill')
sf_tool_brand_id_2 = fields.Many2one('sf.machine.brand', '刀片品牌', 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')
sf_tool_brand_id_3 = fields.Many2one('sf.machine.brand', '刀杆品牌', 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')
sf_tool_brand_id_4 = fields.Many2one('sf.machine.brand', '刀盘品牌', 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')
sf_tool_brand_id_5 = fields.Many2one('sf.machine.brand', '刀柄品牌', 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')
sf_tool_brand_id_6 = fields.Many2one('sf.machine.brand', '夹头品牌', readonly=True)
@@ -775,35 +760,38 @@ class FunctionalToolAssembly(models.Model):
record.chuck_name = 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)
new_former = fields.Selection([('0', ''), ('1', '')], string='新/旧', readonly=True)
reference_length = fields.Char(string='参考伸出长(mm)', readonly=True)
cut_time = fields.Char(string='已切削时间', readonly=True)
cut_length = fields.Char(string='已切削长度(mm)', readonly=True)
cut_number = fields.Char(string='已切削次数', readonly=True)
# 组装功能刀具参数信息
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', readonly=True)
after_assembly_functional_tool_name = fields.Char(string='组装后功能刀具名称', readonly=True)
after_assembly_functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model',
string='组装后功能刀具类型', readonly=True)
after_assembly_functional_tool_diameter = fields.Integer(string='组装后功能刀具直径(mm)', 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', '按库存组装')],
string='装刀任务来源', readonly=True)
applicant = fields.Char(string='申请人', readonly=True)
reason_for_applying = 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)
use_tool_time = fields.Datetime(string='用刀时间', readonly=True)
production_line_name_id = fields.Many2one('sf.production.line', string='产线名称', readonly=False)
machine_tool_name_id = fields.Many2one('maintenance.equipment', string='机床名称', readonly=True)
machine_tool_code = fields.Char(string='机台号', readonly=True)
cutter_spacing_code = fields.Char(string='刀位号', readonly=True)
after_assembly_whether_standard_knife = fields.Boolean(string='组装后是否标准', default=True, readonly=True)
after_assembly_coarse_middle_thin = fields.Selection([("1", ""), ('2', ''), ('3', '')],
string='组装后粗/中/精', readonly=True)
after_assembly_max_lifetime_value = fields.Integer(string='组装后最大寿命值(min)', readonly=True)
after_assembly_alarm_value = fields.Integer(string='组装后报警值(min)', readonly=True)
after_assembly_used_value = fields.Integer(string='组装后已使用值(min)', readonly=True)
after_assembly_tool_loading_length = fields.Float(string='组装后装刀长(mm)', readonly=True)
after_assembly_functional_tool_length = fields.Float(string='组装后伸出长(mm)', readonly=True)
after_assembly_effective_length = fields.Float(string='组装后有效长(mm)', readonly=True)
L_D_number = fields.Float(string='L/D值(mm)', readonly=True)
hiding_length = fields.Float(string='避空长(mm)', readonly=True)
functional_tool_cutting_type = fields.Char(string='功能刀具切削类型', readonly=False)
tool_loading_person = fields.Char(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)
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',
'CAM工单程序用刀计划', readonly=True, )
@@ -855,5 +843,4 @@ class FunctionalToolAssembly(models.Model):
if obj.loading_task_source:
code = self._get_code(obj.loading_task_source)
obj.assembly_order_code = code
obj.name = code
return obj

View File

@@ -71,6 +71,5 @@
parent="menu_sf_tool_manage"
/>
</data>
</odoo>

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,5 @@
from datetime import timedelta
from odoo import fields, models, api
from odoo.exceptions import ValidationError
@@ -6,75 +8,90 @@ class ToolChangeRequirementInformation(models.TransientModel):
_name = 'sf.tool.change.requirement.information'
_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)
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)
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='待换功能刀具名称',
domain=[('name', '=', '功能刀具')])
# 待换功能刀具信息
replacement_tool_name = fields.Char(string='待换功能刀具名称', required=True)
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', '')],
string='粗/中/精')
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='备注说明')
string='待换刀具粗/中/精', default='3')
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):
"""
确认换刀申请(按键)
:return:
"""
# 将数据更新到机台换刀申请界面
print('已运行')
record = self.env['sf.machine.table.tool.changing.apply'].search(
[('name', '=', self.name.id),
('machine_tool_code', '=', self.machine_tool_code),
('cutter_spacing_code', '=', self.cutter_spacing_code),
[('maintenance_equipment_id', '=', self.maintenance_equipment_id.id),
('cutter_spacing_code_id', '=', self.cutter_spacing_code_id.id)
])
print('运行record_1')
# 功能刀具组装创建新任务(new_assembly_task)
record_1 = self.env['sf.functional.tool.assembly'].sudo().create({
'functional_tool_name_id': self.replacement_tool_name_id.id,
sf_functional_tool_assembly = self.env['sf.functional.tool.assembly'].sudo().create({
'functional_tool_name': self.replacement_tool_name,
'functional_tool_type_id': self.replacement_tool_type_id.id,
'loading_task_source': '1',
'applicant': self.applicant,
'reason_for_applying': self.reason_for_applying,
'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,
'functional_tool_diameter': self.replacement_diameter,
'knife_tip_r_angle': self.replacement_knife_tip_r_angle,
'coarse_middle_thin': self.replacement_tool_coarse_middle_thin,
'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,
'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,
'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',
'sf_functional_tool_assembly_id': record_1.id,
}
print('运行record.write(desc)')
record.write(desc)
'sf_functional_tool_assembly_id': sf_functional_tool_assembly
})
print('运行成功')
# 关闭弹出窗口
@@ -85,18 +102,35 @@ class ToolTransferRequestInformation(models.TransientModel):
_name = 'sf.tool.transfer.request.information'
_description = '刀具转移申请信息'
CNC_machine_table_id = fields.Many2one('sf.machine_tool', 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)
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)
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)
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([('机台', '机台'),
('线边刀库', '线边刀库'),
('刀具房', '刀具房')], string='转移到:', default='线边刀库')
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_cutter_spacing_code = fields.Char(string='目标刀位号')
@@ -120,27 +154,41 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
_inherit = ["barcodes.barcode_events_mixin"]
_description = '功能刀具组装单'
# 功能刀具申请信息
machine_tool_name_id = fields.Many2one('maintenance.equipment', string='机床名称', readonly=True)
assembly_order_code = fields.Char(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)
cutter_spacing_code = fields.Char(string='刀位号', readonly=True)
# 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_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', readonly=True)
functional_tool_length = fields.Char(string='功能刀具伸出长(mm)', readonly=True)
effective_length = fields.Char(string='有效长(mm)', readonly=True)
functional_tool_diameter = fields.Char(string='功能刀具直径(mm)', readonly=True)
tool_included_angle = fields.Char(string='刀尖角R角', readonly=True)
functional_tool_cutting_type = fields.Char(string='功能刀具切削类型', readonly=True)
required_cutting_time = fields.Char(string='需切削时长', readonly=True)
whether_standard_tool = fields.Boolean(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)
# 功能刀具组装信息
# 整体式刀具型号
integral_code_id = fields.Many2one('stock.lot', string='整体式刀具序列号',
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)
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', '刀杆序列号',
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)
sf_tool_brand_id_3 = fields.Many2one('sf.machine.brand', '刀杆品牌', readonly=True)
# 刀盘型号
pad_code_id = fields.Many2one('stock.lot', '刀盘序列号',
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)
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', '=', '刀柄')])
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)
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', '=', '夹头')])
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')
sf_tool_brand_id_6 = fields.Many2one('sf.machine.brand', '夹头品牌', readonly=True)
@@ -256,86 +308,72 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
record.chuck_name = 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='装刀长')
new_former = fields.Selection([('0', ''), ('1', '')], string='新/旧', required=True, default='0')
reference_length = fields.Char(string='参考伸出长')
cut_time = fields.Char(string='已切削时间')
cut_length = fields.Char(string='已切削长度')
cut_number = fields.Char(string='已切削次数')
# 组装功能刀具参数信息
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号')
after_assembly_functional_tool_name = fields.Char(string='组装后功能刀具名称', required=True)
after_assembly_functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model',
string='组装后功能刀具类型')
after_assembly_functional_tool_diameter = fields.Integer(string='组装后功能刀具直径(mm)')
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):
"""
功能刀具组装
:return:
"""
# 对物料做必填判断
self.materials_must_be_judged()
# 创建组装入库单
# 创建功能刀具批次/序列号记录
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()
}
# 封装功能刀具数据
desc_1 = self.get_desc_1(stock_lot)
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),
('cutter_spacing_code', '=', self.cutter_spacing_code),
('cutter_spacing_code_id', '=', self.cutter_spacing_code_id.id),
('assemble_status', '=', '0'),
])
# 创建功能刀具列表记录
# 封装功能刀具数据
desc_2 = {
'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,
'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,
}
desc_2 = self.get_desc_2(stock_lot, functional_tool_assembly)
# 创建功能刀具列表、功能刀具预警、功能刀具实时分布、功能刀具出入库记录
record_1 = self.env['sf.functional.cutting.tool.entity'].create(desc_2)
self.env['sf.functional.tool.warning'].create({
'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.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
})
# self.env['sf.functional.tool.warning'].create({
# '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.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)
if functional_tool_assembly.sf_machine_table_tool_changing_apply_id:
@@ -352,6 +390,16 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
# 关闭弹出窗口
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):
"""
创建刀具组装入库单
@@ -413,7 +461,6 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
'qty_done': 1.0,
'state': 'done'
})
return stock_move_id, stock_move_line_id
def get_stock_lot_name(self):
@@ -434,3 +481,68 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
m = int(stock_lot_id.name[-3:]) + 1
num = "%03d" % m
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,42 +1,64 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!--================================================换刀需求信息================================================-->
<!--================================================换刀需求信息================================================-->
<record id="sf_tool_change_requirement_information_form" model="ir.ui.view">
<field name="name">换刀需求信息</field>
<field name="model">sf.tool.change.requirement.information</field>
<field name="arch" type="xml">
<form string="换刀需求信息">
<sheet>
<group string="机床信息" col="3">
<div class="oe_title">
<h1>
<field name="maintenance_equipment_id"/>
</h1>
</div>
<group>
<group>
<field name="production_line_id"/>
<field name="machine_table_type_id"/>
<field name="cutter_spacing_code_id"/>
<field name="tool_position_interface_type"/>
<field name="max_lifetime_value"/>
<field name="alarm_value"/>
<field name="used_value"/>
<field name="whether_standard_knife"/>
</group>
<group>
<field name="name"/>
<field name="barcode_id"/>
</group>
<group>
<field name="machine_tool_code"/>
<field name="functional_tool_name_id"/>
</group>
<group>
<field name="cutter_spacing_code"/>
<field name="functional_tool_name"/>
<field name="functional_tool_type_id"/>
<field name="diameter"/>
<field name="knife_tip_r_angle"/>
<field name="extension_length"/>
<field name="effective_length"/>
</group>
</group>
<group string="功能刀具信息">
<group string="待换功能刀具信息">
<group>
<field name="replacement_tool_name_id" placeholder="请选择"/>
<field name="replacement_tool_type_id"/>
<field name="replacement_tool_coarse_middle_thin" placeholder="请选择"/>
<field name="replacement_tool_name" string="功能刀具名称"/>
<field name="replacement_tool_type_id" string="功能刀具类型"/>
<field name="replacement_diameter" string="刀具直径(mm)"/>
<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"/>
</group>
<group>
<field name="used_tool_time" placeholder="请选择"/>
<field name="new_former" placeholder="请选择"/>
<field name="reason_for_applying"/>
</group>
</group>
</sheet>
<footer>
<button string="确定" name="tool_changing_apply" type="object" class="btn-primary" confirm="是否确认申请换刀"/>
<button string="确定" name="tool_changing_apply" type="object" class="btn-primary"
confirm="是否确认申请换刀"/>
<button string="取消" class="btn-secondary" special="cancel"/>
</footer>
</form>
@@ -53,29 +75,37 @@
</record>
<!--================================================刀具转移申请信息================================================-->
<!--================================================刀具转移申请信息================================================-->
<record id="sf_tool_transfer_request_information_form" model="ir.ui.view">
<field name="name">刀具转移申请信息</field>
<field name="model">sf.tool.transfer.request.information</field>
<field name="arch" type="xml">
<form string="刀具转移申请信息">
<sheet>
<group string="机床信息">
<div class="oe_title">
<h1>
<field name="maintenance_equipment_id"/>
</h1>
</div>
<group>
<field name="CNC_machine_table_id"/>
<field name="cutter_spacing_code"/>
<group>
<field name="production_line_id"/>
<field name="machine_table_type_id"/>
<field name="cutter_spacing_code_id"/>
<field name="tool_position_interface_type"/>
<field name="max_lifetime_value"/>
<field name="alarm_value"/>
<field name="alarm_value"/>
<field name="whether_standard_knife"/>
</group>
<group>
<field name="machine_tool_code"/>
</group>
</group>
<group string="功能刀具信息">
<group>
<field name="functional_tool_name_id" string="功能刀具名称"/>
<field name="functional_tool_type_id" string="功能刀具类型"/>
</group>
<group>
<field name="barcode_id" string="功能刀具编码"/>
<field name="barcode_id"/>
<field name="functional_tool_name"/>
<field name="functional_tool_type_id"/>
<field name="diameter"/>
<field name="knife_tip_r_angle"/>
<field name="effective_length"/>
<field name="effective_length"/>
</group>
</group>
<group string="刀具转移">
@@ -85,18 +115,27 @@
</group>
<group>
<group>
<field name="new_cnc_machine_table_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', '!=', '刀具房')]}"/>
<!-- <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="确定" name="tool_transfer_apply" type="object" class="btn-primary"
confirm="是否确认刀具转移申请"/>
<button string="取消" class="btn-secondary" special="cancel"/>
</footer>
</form>
@@ -113,34 +152,47 @@
</record>
<!--================================================功能刀具组装单================================================-->
<!--================================================功能刀具组装单================================================-->
<record id="sf_functional_tool_assembly_order_form" model="ir.ui.view">
<field name="name">功能刀具组装单</field>
<field name="model">sf.functional.tool.assembly.order</field>
<field name="arch" type="xml">
<form string="功能刀具组装单">
<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="barcode_id"/>
<field name="functional_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"/>
<field name="functional_tool_cutting_type"/>
</group>
<group>
<field name="cutter_spacing_code"/>
<field name="functional_tool_type_id"/>
<field name="functional_tool_diameter"/>
<field name="tool_included_angle"/>
<field name="whether_standard_tool"/>
<field name="required_cutting_time"/>
<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)]}">
<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>
@@ -184,7 +236,8 @@
</group>
</group>
</group>
<group col="1" attrs="{'invisible': ['|',('integral_code_id', '!=', False),('pad_code_id', '!=', False)]}">
<group col="1"
attrs="{'invisible': ['|',('integral_code_id', '!=', False),('pad_code_id', '!=', False)]}">
<div>
<separator string="刀杆:" style="font-size: 13px;"/>
</div>
@@ -206,7 +259,8 @@
</group>
</group>
</group>
<group col="1" attrs="{'invisible': ['|',('integral_code_id', '!=', False),('bar_code_id', '!=', False)]}">
<group col="1"
attrs="{'invisible': ['|',('integral_code_id', '!=', False),('bar_code_id', '!=', False)]}">
<div>
<separator string="刀盘:" style="font-size: 13px;"/>
</div>
@@ -276,20 +330,33 @@
<group string="组装参数信息">
<group>
<field name="coarse_middle_thin"/>
<field name="new_former"/>
<field name="tool_loading_length"/>
<field name="reference_length"/>
</group>
<group>
<field name="barcode_id" readonly="True"/>
<field name="after_assembly_functional_tool_name" string="功能刀具名称"/>
<field name="after_assembly_functional_tool_type_id" string="功能刀具类型"/>
<field name="after_assembly_functional_tool_diameter" string="刀具直径(mm)"/>
<field name="after_assembly_knife_tip_r_angle" string="刀尖R角(mm)"/>
<field name="after_assembly_new_former" string="新/旧"/>
<field name="cut_time"/>
<field name="cut_length"/>
<field name="cut_number"/>
</group>
<group>
<field name="after_assembly_whether_standard_knife" string="是否标准刀"/>
<field name="after_assembly_coarse_middle_thin" string="粗/中/精"/>
<field name="after_assembly_max_lifetime_value" string="最大寿命值(min)"/>
<field name="after_assembly_alarm_value" string="报警值(min)"/>
<field name="after_assembly_used_value" string="已使用值(min)"/>
<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="确定" name="functional_tool_assembly" type="object" class="btn-primary"
confirm="是否确认申请组装"/>
<button string="取消" class="btn-secondary" special="cancel"/>
</footer>
</form>

View File

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

View File

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

View File

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

View File

@@ -1,25 +1,9 @@
# -*- coding: utf-8 -*-
import ast
import base64
import io
import json
import os
import random
import time
import re
from stl import mesh
from werkzeug import urls
import odoo
from odoo.exceptions import ValidationError
import logging
import requests
from odoo import http
from odoo.http import request, Response
from odoo.modules import get_resource_path
from odoo.tools.translate import _
import logging
from odoo.http import request
_logger = logging.getLogger(__name__)
@@ -52,7 +36,8 @@ class WechatAuthController(http.Controller):
if not user:
# 获取企业微信用户详细信息
user_detail_url = f'https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token={access_token}&userid={user_id}'
user_detail_url = \
f'https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token={access_token}&userid={user_id}'
user_detail_response = requests.get(user_detail_url).json()
# 创建 Odoo 用户

View File

@@ -6,6 +6,5 @@ from . import wxwork_settings
from . import wxwork_approval_template_summary
from . import we_approval_record
from . import wx_work_api
from . import wxwork_approval
# from . import res_config_setting

View File

@@ -1,17 +1,6 @@
# -*- coding: utf-8 -*-
import re
import logging
import time
import requests
from datetime import datetime
import base64
import hashlib
from odoo import fields, models, api
import json
import requests
from odoo.http import request
from odoo.exceptions import ValidationError
from odoo.exceptions import UserError
from odoo import fields, models
_logger = logging.getLogger(__name__)

View File

@@ -39,5 +39,3 @@ class WxWorkApprovalTemplate(models.Model):
def _compute_related_records_count(self):
for record in self:
record.related_records_count = len(record.summary_info_ids)

View File

@@ -3,20 +3,14 @@
import {registry} from "@web/core/registry";
import {_lt} from "@web/core/l10n/translation";
import {standardFieldProps} from "@web/views/fields/standard_field_props";
import {useInputField} from "@web/views/fields/input_field_hook";
import {FileUploader} from "@web/views/fields/file_handler";
import {session} from "@web/session";
import {useService} from "@web/core/utils/hooks";
import {isBinarySize} from "@web/core/utils/binary";
import {download} from "@web/core/network/download";
import utils from 'web.utils';
import core from 'web.core';
import rpc from 'web.rpc';
// import core from 'web.core';
var QWeb = core.qweb;
import {Component, onWillUpdateProps, useState, useRef, useEffect} from "@odoo/owl";
// var QWeb = core.qweb;
import {Component} from "@odoo/owl";
export class StepViewer extends Component {
setup() {
@@ -35,11 +29,11 @@ export class StepViewer extends Component {
}
url = url_props['base_url'].replace('http://', 'https://') + '/web/content/' + url_props['model'] + '/' + url_props['id'] + '/' + url_props['field'] + '?download=true'
// url = 'http://localhost:8069'+'/web/content/'+url_props['model']+'/'+url_props['id']+'/'+url_props['field']+'?download=true'
console.log('url111111', url)
// console.log('url111111', url)
return url
} else {
url = "data:model/gltf-binary;base64," + this.props.value;
console.log('url2', url)
// console.log('url2', url)
return url
// localStorage.setItem('url',url)
// let new_url = localStorage.getItem(('url'))
@@ -48,8 +42,8 @@ export class StepViewer extends Component {
// url = "web_widget_model_viewer/static/src/images/not_model.png";
}
} else {
var oImg = document.getElementsByClassName('test')[0]
console.log(oImg)
// var oImg = document.getElementsByClassName('test')[0]
// console.log(oImg)
}
}
}