Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/制造代码优化

# Conflicts:
#	sf_warehouse/models/model.py
This commit is contained in:
mgw
2024-04-09 20:42:15 +08:00
34 changed files with 1292 additions and 706 deletions

View File

@@ -4,6 +4,7 @@ import {patch} from '@web/core/utils/patch';
// import { Dialog } from "@web/core/dialog/dialog";
import {_t} from "@web/core/l10n/translation";
import {FormStatusIndicator} from "@web/views/form/form_status_indicator/form_status_indicator";
import {ListRenderer} from "@web/views/list/list_renderer";
import {Field} from "@web/views/fields/field";
@@ -45,6 +46,11 @@ const filedRequiredList = {
'date_planned_start': { multiple: false, noLabel: false },
'date_planned_finished': { multiple: false, noLabel: false },
}
const tableRequiredList = [
'product_template_id', 'product_uom_qty', 'price_unit','product_id','product_qty',
'name', 'fault_type', 'maintenance_standards', 'Period'
]
patch(FormStatusIndicator.prototype, 'jikimo_frontend.FormStatusIndicator', {
// 你可以重写或者添加一些方法和属性
async _onDiscardChanges() {
@@ -110,7 +116,24 @@ patch(Field.prototype, 'jikimo_frontend.Field', {
}
}
})
patch(ListRenderer.prototype, 'jikimo_frontend.ListRenderer', {
setup(){
owl.onMounted(() => {
this.activeElement = this.uiService.activeElement;
this.setRequired()
})
return this._super(...arguments);
},
setRequired() {
this.allColumns.forEach(_ => {
if( tableRequiredList.indexOf(_.name) >= 0 ) {
const dom = $(`th[data-name=${_.name}]`)
let t = dom.html()
dom.html('<i style="color: red;margin-left: -4px;position: absolute;left: 0">*</i>' + t)
}
})
}
})
$(function () {
document.addEventListener('click', function () {
@@ -160,45 +183,13 @@ $(function () {
}, 500)
}
function setRequired(dom = {label: [], table: []}) {
let domTimer = null
let timer_count = 0
clearInterval(domTimer)
domTimer = setInterval(() => {
timer_count++
const lint = $('.o_form_view_container')
if (lint.length) {
clearInterval(domTimer)
const { table} = dom
if (table.length) {
table.forEach(_ => {
const th = $(`th[data-name=${_}]`)
const t = th.find('span').eq(0).text().replace('*','')
th.find('span').eq(0).html('<i style="color: red">*</i>' + t)
})
}
}
if (timer_count == 20) {
clearInterval(domTimer)
}
}, 500)
}
var currentUrl = location.href
const customRequiredDom = {
table: ['product_template_id', 'product_uom_qty', 'price_unit','product_id','product_qty', 'name', 'fault_type', 'maintenance_standards', 'Period']
}
const listenerUrl = setInterval(() => {
const isChange = currentUrl != location.href
if (isChange) {
currentUrl = location.href
customRequired()
setRequired(customRequiredDom)
}
}, 500)
customRequired()
setRequired(customRequiredDom)
})

View File

@@ -467,3 +467,15 @@ div:has(.o_required_modifier) > label::before {
background: #71639e;
color: #fff
}
// 修改时间输入框宽度
.o_datepicker_input.o_input.datetimepicker-input {
width: 200px;
}
.o_form_view .o_form_editable .o_row > .o_field_widget, .o_form_view .o_form_editable .o_row > .o_field_widget.o_field_float_time {
width: auto !important;
flex: unset;
}

View File

@@ -308,3 +308,28 @@ class ToolGroups(models.Model):
# records = super(ToolGroups, self).create(vals_list)
# self._register_tool_groups(records)
# return records
class ToolInventory(models.Model):
_name = 'sf.tool.inventory'
_description = '功能刀具清单'
name = fields.Char('功能刀具名称', required=True)
type = fields.Char('类型')
functional_cutting_tool_model_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型')
prefix = fields.Char('前缀')
postfix = fields.Char('后缀')
diameter = fields.Float('直径(mm)')
angle = fields.Float('R角(mm)')
tool_length = fields.Float('刀具总长(mm)')
blade_length = fields.Float('避空长/刃长(mm)')
knife_head_name = fields.Char('刀头名称')
cutter_number = fields.Char('刀号')
blade_number = fields.Integer('刃数(个)')
extension = fields.Float('伸出长度(mm)')
work_material = fields.Selection([('', ''), ('', '')], string='加工材料')
life_span = fields.Float('寿命(h)')
tool_groups_id = fields.Many2one('sf.tool.groups', string='刀具组')
active = fields.Boolean('已归档', default=True)

View File

@@ -192,4 +192,11 @@ access_sf_machine_brand_tags_group_purchase_director,sf_machine_brand_tags_group
access_printer,printer,model_printer,base.group_user,1,1,1,1
access_printer_configuration,printer.configuration,model_printer_configuration,base.group_user,1,1,1,1
access_printer_configuration,printer.configuration,model_printer_configuration,base.group_user,1,1,1,1
access_group_sf_mrp_user,sf_tool_inventory,model_sf_tool_inventory,base.group_user,1,1,1,0
access_group_sf_mrp_user_admin,sf_tool_inventory_admin,model_sf_tool_inventory,base.group_system,1,1,1,0
access_group_sf_mrp_user_group_purchase_director,sf_tool_inventory_group_purchase_director,model_sf_tool_inventory,sf_base.group_purchase_director,1,0,1,0
access_group_sf_mrp_user_group_sale_director,sf_tool_inventory_group_sale_director,model_sf_tool_inventory,sf_base.group_sale_director,1,0,1,0
access_sf_cutting_tool_material_group_plan_director,sf_tool_inventory_group_plan_director,model_sf_tool_inventory,sf_base.group_plan_director,1,0,1,0
access_group_sf_mrp_user_group_sf_mrp_user,sf_tool_inventory_group_sf_mrp_user,model_sf_tool_inventory,sf_base.group_sf_mrp_user,1,1,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
192 access_group_sf_mrp_user_group_purchase_director sf_tool_inventory_group_purchase_director model_sf_tool_inventory sf_base.group_purchase_director 1 0 1 0
193 access_group_sf_mrp_user_group_sale_director sf_tool_inventory_group_sale_director model_sf_tool_inventory sf_base.group_sale_director 1 0 1 0
194 access_sf_cutting_tool_material_group_plan_director sf_tool_inventory_group_plan_director model_sf_tool_inventory sf_base.group_plan_director 1 0 1 0
195 access_group_sf_mrp_user_group_sf_mrp_user sf_tool_inventory_group_sf_mrp_user model_sf_tool_inventory sf_base.group_sf_mrp_user 1 1 0 0
196
197
198
199
200
201
202

View File

@@ -189,3 +189,6 @@ td.o_required_modifier {
flex-direction: row !important;
}
.supplier_ids_set_css thead th[data-name=partner_id]{
width: 500px!important;
}

View File

@@ -269,7 +269,7 @@
</group>
<notebook>
<page string="供应商">
<field name='supplier_ids'>
<field name='supplier_ids' class="supplier_ids_set_css">
<tree editable='bottom'>
<field name="sequence" widget="handle" string="序号"/>
<field name="partner_id" string="名称"/>

View File

@@ -59,14 +59,14 @@
id="menu_sf_cutting_tool_type"
parent="menu_sf_cutting_tool"
name="刀具类型"
sequence="2"
sequence="10"
action="action_sf_cutting_tool_type"
/>
<menuitem
id="menu_sf_cutting_tool_standard_library"
parent="menu_sf_cutting_tool"
name="刀具标准库"
sequence="3"
sequence="20"
action="action_sf_cutting_tool_standard_library"
/>
<!-- 功能刀具 -->
@@ -82,7 +82,7 @@
id="menu_sf_functional_cutting_tool_model_type"
parent="menu_sf_cutting_tool"
name="功能刀具类型"
sequence="4"
sequence="30"
action="action_sf_functional_cutting_tool_model_type"
/>
@@ -91,14 +91,14 @@
name="能力特征库"
parent="menu_sf_cutting_tool"
action="action_maintenance_equipment_image"
sequence="5"/>
sequence="40"/>
<menuitem
id="menu_sf_tool_groups"
name="刀具组"
parent="menu_sf_cutting_tool"
action="sf_tool_groups_view_act"
sequence="10"/>
sequence="50"/>
</data>
</odoo>

View File

@@ -123,7 +123,7 @@
<form string="刀具标准库" delete="0" create="0" edit="0">
<sheet>
<field name="image" widget='image' class="oe_avatar"
required="1"/>
required="1"/>
<div class="oe_title">
<h1>
<field name="code" readonly="1" force_save="1"/>
@@ -547,7 +547,75 @@
<!-- <field name="cutting_depth"/>-->
<!-- </tree>-->
<!-- </field>-->
<!-- </record>-->
<!-- </record>-->'
<!-- ================================================功能刀具清单================================================ -->
<record id="view_tool_inventory_tree" model="ir.ui.view">
<field name="name">sf.tool.inventory.tree</field>
<field name="model">sf.tool.inventory</field>
<field name="arch" type="xml">
<tree string="功能刀具清单" create="1" edit="1" delete="0" editable="bottom">
<field name="name"/>
<field name="functional_cutting_tool_model_id"/>
<field name="tool_groups_id"/>
<field name="work_material"/>
<field name="life_span"/>
<field name="prefix" optional="hide"/>
<field name="postfix" optional="hide"/>
<field name="diameter"/>
<field name="angle"/>
<field name="tool_length"/>
<field name="blade_length"/>
<field name="knife_head_name" optional="hide"/>
<field name="cutter_number"/>
<field name="blade_number"/>
<field name="extension"/>
<field name="create_uid" string="创建人" optional="hide"/>
<field name="create_date" string="创建时间" optional="hide"/>
<field name="type" invisible="1"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="view_cutting_tool_material_search">
<field name="name">sf.tool.inventory.search</field>
<field name="model">sf.tool.inventory</field>
<field name="arch" type="xml">
<search string="功能刀具清单">
<field name="name" string="名称搜索" filter_domain="[('name','ilike',self)]"/>
<field name="functional_cutting_tool_model_id"/>
<field name="tool_groups_id"/>
<field name="work_material"/>
<field name="life_span"/>
<field name="prefix"/>
<field name="postfix"/>
<field name="diameter"/>
<field name="angle"/>
<field name="tool_length"/>
<field name="blade_length"/>
<field name="knife_head_name"/>
<field name="cutter_number"/>
<field name="blade_number"/>
<field name="extension"/>
<filter name="filter_active" string="已归档" domain="[('active','=',False)]"/>
</search>
</field>
</record>
<record id="action_sf_tool_inventory" model="ir.actions.act_window">
<field name="name">功能刀具清单</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sf.tool.inventory</field>
<field name="view_mode">tree</field>
</record>
<menuitem
id="menu_sf_tool_inventory"
parent="menu_sf_cutting_tool"
name="功能刀具清单"
sequence="25"
action="action_sf_tool_inventory"
/>
</odoo>

View File

@@ -238,7 +238,7 @@ class Manufacturing_Connect(http.Controller):
workorder = request.env['mrp.workorder'].sudo().search(
[('production_id', '=', production_id), ('routing_type', '=', routing_type)], limit=1)
if workorder:
workorder.test_result = ret['Quality']
# workorder.test_results = ret['Quality']
logging.info('制造订单:%s' % workorder.production_id.name)
if 'ReportPaht' in ret:
download_state = request.env['mrp.workorder'].with_user(
@@ -261,8 +261,7 @@ class Manufacturing_Connect(http.Controller):
('picking_id', '=', stock_picking.id)])
if quality_check:
logging.info('质检单:%s' % quality_check.name)
quality_check.write({'report_pdf': workorder.detection_report,
'report_result': workorder.test_result})
quality_check.write({'report_pdf': workorder.detection_report})
elif download_state == 2:
res = {'Succeed': False, 'ErrorCode': 205,
'Error': 'ReportPaht中的工件号与制造订单%s不匹配请检查ReportPaht是否正确' % workorder.production_id.name}

View File

@@ -67,5 +67,21 @@
search="[('barcode','=','WH-PREPRODUCTION')]"/>
<field name="default_location_dest_id" ref="stock_location_locations_virtual_outcontract"/>
</record>
<record id="route_surface_technology_outsourcing" model="stock.route">
<field name="name">表面工艺外协</field>
<!-- <field name="company_id"></field>-->
<field name="active">True</field>
<field name="sequence">11</field>
</record>
<!-- <record id="route_surface_technology_outsourcing" model="stock.rule">-->
<!-- <field name="name">外协出库单</field>-->
<!-- <field name="action">push</field>-->
<!-- <field name="pick_type_id" ref="outcontract_picking_out"></field>-->
<!-- <field name="location_src_id" ref=""/>-->
<!-- <field name="location_dest_id" ref="stock_location_locations_virtual_outcontract"/>-->
<!-- <field name="active">True</field>-->
<!-- <field name="sequence">11</field>-->
<!-- </record>-->
</data>
</odoo>

View File

@@ -1,3 +1,5 @@
import re
import logging
import base64
import urllib.parse
@@ -96,7 +98,8 @@ class ResMrpWorkOrder(models.Model):
Y10_axis = fields.Float(default=0)
Z10_axis = fields.Float(default=0)
X_deviation_angle = fields.Integer(string="X轴偏差度", default=0)
test_result = fields.Char("检测结果")
test_results = fields.Selection([("合格", "合格"), ("返工", "返工"), ("报废", "报废")], default='合格',
string="检测结果")
cnc_ids = fields.One2many("sf.cnc.processing", 'workorder_id', string="CNC加工程序")
cmm_ids = fields.One2many("sf.cmm.program", 'workorder_id', string="CMM程序")
tray_code = fields.Char(string="托盘编码")
@@ -141,6 +144,7 @@ class ResMrpWorkOrder(models.Model):
production_line_state = fields.Selection(related='production_id.production_line_state',
string='上/下产线', store=True)
detection_report = fields.Binary('检测报告', readonly=True)
is_remanufacture = fields.Boolean(string='是否重新生成制造订单', default=True)
def get_plan_workorder(self, production_line):
tomorrow = (date.today() + timedelta(days=+1)).strftime("%Y-%m-%d")
@@ -444,7 +448,7 @@ class ResMrpWorkOrder(models.Model):
"""
重新生成制造订单或者重新生成工单
"""
if self.test_result == '报废':
if self.test_results == '报废':
values = self.env['mrp.production'].create_production1_values(self.production_id)
productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company(
self.production_id.company_id).create(
@@ -476,7 +480,7 @@ class ResMrpWorkOrder(models.Model):
'mail.message_origin_link',
values={'self': production, 'origin': origin_production},
subtype_id=self.env.ref('mail.mt_note').id)
if self.test_result == '返工':
if self.test_results == '返工':
productions = self.production_id
# self.env['stock.move'].sudo().create(productions._get_moves_raw_values())
# self.env['stock.move'].sudo().create(productions._get_moves_finished_values())
@@ -606,6 +610,8 @@ class ResMrpWorkOrder(models.Model):
if self.routing_type == '装夹预调':
if not self.material_center_point and self.X_deviation_angle > 0:
raise UserError("请对前置三元检测定位参数进行计算定位")
if not self.rfid_code:
raise UserError("请扫RFID码进行绑定")
if self.picking_out_id:
picking_out = self.env['stock.picking'].search([('id', '=', self.picking_out_id.id)])
if picking_out.workorder_out_id:
@@ -819,25 +825,33 @@ class SfWorkOrderBarcodes(models.Model):
workorder = self.env['mrp.workorder'].browse(self.ids)
# workorder = self.env['mrp.workorder'].search(
# [('routing_type', '=', '装夹预调'), ('production_id', '=', self.production_id.id)])
# workorder_old = self.env['mrp.workorder'].search([('rfid_code', '=', barcode)])
# if workorder_old:
# raise UserError('该托盘已绑定工件,请先解除绑定!!!')
if workorder:
if workorder.routing_type == '装夹预调':
stock_move_line = self.env['stock.move.line'].search([('lot_name', '=', barcode)])
if stock_move_line.product_id.categ_type == '夹具':
workorder.write({
'tray_serial_number': stock_move_line.lot_name,
'tray_product_id': stock_move_line.product_id.id,
'tray_brand_id': stock_move_line.product_id.brand_id.id,
'tray_type_id': stock_move_line.product_id.fixture_material_id.id,
'tray_model_id': stock_move_line.product_id.fixture_model_id.id
})
workorder.button_start()
# return {
# 'type': 'ir.actions.act_window',
# 'res_model': 'mrp.workorder',
# 'view_mode': 'form',
# 'domain': [('id', 'in', workorder.id)],
# 'target': 'current'
# }
if workorder.state in ['progress', 'done']:
work_state = {'progress': '进行中', 'done': '已完工'}
raise UserError('该工单%s,不能重新绑定托盘' % work_state.get(workorder.state))
lots = self.env['stock.lot'].sudo().search([('rfid', '=', barcode)])
if lots:
for lot in lots:
if lot.product_id.categ_type == '夹具':
val = {
'tray_serial_number': lot.name,
'tray_product_id': lot.product_id.id,
'tray_brand_id': lot.product_id.brand_id.id,
'tray_type_id': lot.product_id.fixture_material_id.id,
'tray_model_id': lot.product_id.fixture_model_id.id,
'rfid_code': barcode
}
workorder.write(val)
self.write(val)
workorder_rfid = self.env['mrp.workorder'].search(
[('production_id', '=', workorder.production_id.id)])
if workorder_rfid:
for item in workorder_rfid:
item.write({'rfid_code': barcode})
else:
embryo_stock_lot = self.env['stock.lot'].search([('name', '=', barcode)])
if embryo_stock_lot:
@@ -869,7 +883,58 @@ class SfWorkOrderBarcodes(models.Model):
[('production_id', '=', workorder.production_id.id)])
if workorder_rfid:
for item in workorder_rfid:
item.write({'rfid_code': barcode})
if item.state == "progress":
item.write({'rfid_code': barcode})
raise UserError('该托盘信息不存在!!!')
# stock_move_line = self.env['stock.move.line'].search([('lot_name', '=', barcode)])
# if stock_move_line.product_id.categ_type == '夹具':
# workorder.write({
# 'tray_serial_number': stock_move_line.lot_name,
# 'tray_product_id': stock_move_line.product_id.id,
# 'tray_brand_id': stock_move_line.product_id.brand_id.id,
# 'tray_type_id': stock_move_line.product_id.fixture_material_id.id,
# 'tray_model_id': stock_move_line.product_id.fixture_model_id.id
# })
# workorder.button_start()
# # return {
# # 'type': 'ir.actions.act_window',
# # 'res_model': 'mrp.workorder',
# # 'view_mode': 'form',
# # 'domain': [('id', 'in', workorder.id)],
# # 'target': 'current'
# # }
# else:
# embryo_stock_lot = self.env['stock.lot'].search([('name', '=', barcode)])
# if embryo_stock_lot:
# embryo_stock_move_line = self.env['stock.move.line'].search(
# [('product_id', '=', embryo_stock_lot.product_id.id),
# ('reference', '=', workorder.production_id.name),
# ('lot_id', '=', embryo_stock_lot.id),
# ('product_category_name', '=', '坯料')])
# if embryo_stock_move_line:
# bom_production = self.env['mrp.production'].search(
# [('product_id', '=', embryo_stock_lot.product_id.id),
# ('origin', '=', workorder.production_id.name)], limit=1, order='id asc')
# workpiece_delivery = self.env['sf.workpiece.delivery'].search(
# [('workorder_id', '=', workorder.id)], limit=1, order='id asc')
# if workpiece_delivery:
# embryo_workpiece_code = workpiece_delivery.workpiece_code
# if bom_production:
# if workpiece_delivery.workpiece_code and bom_production.name not in \
# workpiece_delivery.workpiece_code:
# embryo_workpiece_code = workpiece_delivery.workpiece_code + ',' + \
# bom_production.name
# if not workpiece_delivery.workpiece_code:
# embryo_workpiece_code = bom_production.name
# workpiece_delivery.write({'workpiece_code': embryo_workpiece_code})
# else:
# raise UserError('工件生产线不一致,请重新确认')
# else:
# workorder_rfid = self.env['mrp.workorder'].search(
# [('production_id', '=', workorder.production_id.id)])
# if workorder_rfid:
# for item in workorder_rfid:
# item.write({'rfid_code': barcode})
class WorkPieceDelivery(models.Model):
@@ -909,16 +974,24 @@ class WorkPieceDelivery(models.Model):
# 配送至avg小车
def _delivery_avg(self):
res = {'reqCode': urllib.parse.quote(self.production_id.name), 'reqTime': '', 'clientCode': '', 'tokenCode': '',
'taskTyp': 'F01', 'ctnrTyp': '', 'ctnrCode': '', 'wbCode': '006848AB006774', 'positionCodePath': [],
config = self.env['res.config.settings'].get_values()
agv_site = self.env['res.agv.site'].search([])
positionCode_Arr = []
if agv_site:
for item in agv_site:
positionCode_Arr.append({
'positionCode': item.content,
'code': item.type
})
res = {'reqCode': self.production_id.name, 'reqTime': '', 'clientCode': '', 'tokenCode': '',
'taskTyp': config['task_type_no'], 'ctnrTyp': '', 'ctnrCode': '', 'wbCode': config['wbcode'],
'positionCodePath': positionCode_Arr,
'podCode': '',
'podDir': '', 'materialLot': '', 'priority': '', 'taskCode': '', 'agvCode': '', 'materialLot': '',
'data': ''}
config = self.env['res.config.settings'].get_values()
try:
logging.info('AGV请求路径:%s' % config['agv_rcs_url'])
logging.info('AGV-json:%s' % res)
headers = {'Content-Type': 'application/json'}
ret = requests.post((config['agv_rcs_url']), json=res, headers=headers)
ret = ret.json()

View File

@@ -6,12 +6,11 @@ import os
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):
_inherit = 'product.template'
@@ -107,7 +106,10 @@ class ResProductMo(models.Model):
@api.onchange('cutting_tool_model_id')
def _onchange_cutting_tool_model_id(self):
self.specification_id = False
for item in self:
if item:
item.specification_id = False
item.cutting_tool_chuck_id = item.cutting_tool_model_id.chuck_id
@api.onchange('cutting_tool_material_id')
def _onchange_cutting_tool_material_id(self):
@@ -310,7 +312,6 @@ class ResProductMo(models.Model):
self.cutting_tool_is_safety_lock = self.specification_id.is_safe_lock
self.cutting_tool_fit_nut_model = self.specification_id.nut
self.cutting_tool_wrench = self.specification_id.spanner
self.cutting_tool_chuck_id = self.specification_id.chuck_id.id
self.cutting_tool_jump_accuracy = self.specification_id.diameter_slip_accuracy
self.cutting_tool_taper_shank_model = self.specification_id.taper_shank_model
self.cutting_tool_cooling_type = self.specification_id.cooling_model

View File

@@ -17,6 +17,50 @@ from io import BytesIO
from odoo.exceptions import ValidationError
class stockWarehouse(models.Model):
_inherit = 'stock.warehouse'
subcontracting_surface_technology_pull_out_id = fields.Many2one(
'stock.rule', '表面工艺规则1')
subcontracting_surface_technology_pull_in_id = fields.Many2one(
'stock.rule', '表面工艺规则2'
)
def _get_global_route_rules_values(self):
rules = super(stockWarehouse, self)._get_global_route_rules_values()
location_virtual_id = self.env.ref(
'sf_manufacturing.stock_location_locations_virtual_outcontract').id,
location_pre_id = self.env['stock.location'].search(
[('barcode', 'ilike', 'WH-PREPRODUCTION')]).id,
rules.update({
'subcontracting_surface_technology_pull_in_id': {
'create_values': {
'action': 'pull',
'picking_type_id': self.env.ref('sf_manufacturing.outcontract_picking_in').id,
'group_propagation_option': 'none',
'company_id': self.company_id.id,
'location_src_id': location_virtual_id,
'location_dest_id': location_pre_id,
'route_id': self._find_global_route('sf_manufacturing.route_surface_technology_outsourcing',
_('表面工艺外协')).id,
}
},
'subcontracting_surface_technology_pull_out_id': {
'create_values': {
'action': 'pull',
'picking_type_id': self.env.ref('sf_manufacturing.outcontract_picking_out').id,
'group_propagation_option': 'none',
'company_id': self.company_id.id,
'location_src_id': location_pre_id,
'location_dest_id': location_virtual_id,
'route_id': self._find_global_route('sf_manufacturing.route_surface_technology_outsourcing',
_('表面工艺外协')).id,
}
}
})
return rules
class StockRule(models.Model):
_inherit = 'stock.rule'
@@ -222,6 +266,21 @@ class ProductionLot(models.Model):
_name = 'stock.lot'
_inherit = ['stock.lot', 'printing.utils']
rfid = fields.Char('Rfid', readonly=True)
product_specification = fields.Char('规格', compute='_compute_product_specification', store=True)
@api.depends('product_id')
def _compute_product_specification(self):
for stock in self:
if stock:
if stock.product_id:
if stock.product_id.categ_id.name in '刀具':
stock.product_specification = stock.product_id.specification_id.name
elif stock.product_id.categ_id.name in '夹具':
stock.product_specification = stock.product_id.specification_fixture_id.name
else:
stock.product_specification = stock.product_id.default_code
@api.model
def generate_lot_names1(self, display_name, first_lot, count):
"""Generate `lot_names` from a string."""
@@ -264,7 +323,7 @@ class ProductionLot(models.Model):
if not last_serial:
return "%s-%s%03d" % (product.cutting_tool_model_id.code[:-12], now, 1)
else:
return "%s-%s%03d" % (product.cutting_tool_model_id.code[:-12], now, int(last_serial.name[-3:]) + 2)
return "%s-%s%03d" % (product.cutting_tool_model_id.code[:-12], now, int(last_serial.name[-3:]) + 1)
else:
raise ValidationError('该刀具物料产品的型号字段为空,请补充完整!!!')

View File

@@ -422,7 +422,8 @@
<div name="product_specification_id" class="mt-1">
规格:
<field name="specification_id"></field>
<field name="specification_id"/>
<field name="specification_fixture_id"/>
</div>
<t t-if="record.default_code.value">[<field name="default_code"/>]
</t>

View File

@@ -104,18 +104,14 @@
<field name='user_permissions' invisible="1"/>
<field name='name' invisible="1"/>
<field name='is_delivery' invisible="1"/>
<!-- 工单form页面的开始停工按钮等 -->
<!-- 工单form页面的开始停工按钮等 -->
<button name="button_start" type="object" string="开始" class="btn-success"
attrs="{'invisible': ['|', '|', '|', '|','|', ('production_state','in', ('draft', 'done',
'cancel')), ('working_state', '=', 'blocked'), ('state', 'in', ('done', 'cancel')),
('is_user_working', '!=', False),('user_permissions','=',False), ('routing_type', '=', 'CNC加工')]}"
groups="sf_base.group_sf_mrp_user"/>
<button name="button_pending" type="object" string="暂停" class="btn-warning"
groups="sf_base.group_sf_mrp_user"
attrs="{'invisible': ['|', '|','|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('is_user_working', '=', False), ('routing_type', '=', 'CNC加工')]}"/>
groups="sf_base.group_sf_mrp_user"/>
<button name="button_finish" type="object" string="完成" class="btn-success"
groups="sf_base.group_sf_mrp_user"
attrs="{'invisible': ['|', '|','|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('is_user_working', '=', False), ('routing_type', '=', 'CNC加工')]}"/>
groups="sf_base.group_sf_mrp_user" confirm="是否确认完工"/>
<button name="%(mrp.act_mrp_block_workcenter_wo)d" type="action" string="停工"
context="{'default_workcenter_id': workcenter_id}" class="btn-danger"
groups="sf_base.group_sf_mrp_user"
@@ -184,10 +180,10 @@
attrs='{"invisible": [("routing_type","!=","装夹预调")]}'/>
<field name="functional_fixture_type_id"
attrs='{"invisible": [("routing_type","!=","装夹预调")]}'/>
<field name="rfid_code" force_save="1" readonly="1" class="customRFID"
<field name="rfid_code" force_save="1" readonly="1" cache="True"
attrs="{'invisible': [('rfid_code_old', '!=', False)]}"/>
<field name="rfid_code_old" readonly="1" attrs="{'invisible': [('rfid_code_old', '=', False)]}"/>
<script src="/sf_manufacturing/static/src/js/customRFID.js"></script>
</group>
<!-- <group>-->
<!-- <div>-->
@@ -242,6 +238,7 @@
<!-- </page>-->
<page string="工件装夹" attrs='{"invisible": [("routing_type","!=","装夹预调")]}'>
<group>
<field name="_barcode_scanned" widget="barcode_handler"/>
<group string="卡盘">
<field name="chuck_serial_number"/>
<field name="chuck_name"/>
@@ -250,7 +247,6 @@
<field name="chuck_model_id"/>
</group>
<group string="托盘">
<field name="_barcode_scanned" widget="barcode_handler"/>
<field name="tray_serial_number" readonly="1" string="序列号"/>
<field name="tray_product_id" readonly="1" string="名称"/>
<field name="tray_brand_id" readonly="1" string="品牌"/>
@@ -437,16 +433,17 @@
<field name="results" invisible="1"/>
<page string="后置三元检测" attrs='{"invisible": [("routing_type","!=","CNC加工")]}'>
<group>
<field name="test_result" readonly="1" attrs='{"invisible":[("results","!=",False)]}'/>
<field name="test_results" attrs='{"invisible":[("results","!=",False)]}'/>
<field name="is_remanufacture" attrs='{"invisible":[("test_results","=","合格")]}'/>
<field name="results" readonly="1" attrs='{"invisible":[("results","!=","合格")]}'/>
<field name="detection_report" attrs='{"invisible":[("results","!=",False)]}'
widget="pdf_viewer"/>
</group>
<div class="col-12 col-lg-6 o_setting_box">
<button type="object" class="oe_highlight" name="recreateManufacturingOrWorkerOrder"
string="检测确认"
attrs='{"invisible": ["|","|",("state","!=","progress"),("user_permissions","=",False),("results","=","合格")]}'/>
</div>
<!-- <div class="col-12 col-lg-6 o_setting_box">-->
<!-- <button type="object" class="oe_highlight" name="recreateManufacturingOrWorkerOrder"-->
<!-- string="检测确认"-->
<!-- attrs='{"invisible": ["|","|",("state","!=","progress"),("user_permissions","=",False),("results","=","合格")]}'/>-->
<!-- </div>-->
</page>
</xpath>
<xpath expr="//page[1]" position="before">

View File

@@ -13,6 +13,12 @@
<button string="打印二维码" name="print_single_method" type="object" class="btn-primary"/>
</header>
</xpath>
<xpath expr="//field[@name='product_id']" position="before">
<field name="rfid" attrs="{'invisible': [('rfid', '=', False)]}"/>
</xpath>
<xpath expr="//field[@name='product_id']" position="after">
<field name="product_specification"/>
</xpath>
</field>
</record>
</odoo>

View File

@@ -13,10 +13,11 @@ class ResConfigSettings(models.TransientModel):
token = fields.Char(string='TOKEN', default='b811ac06-3f00-11ed-9aed-0242ac110003')
sf_secret_key = fields.Char(string='密钥', default='wBmxej38OkErKhD6')
sf_url = fields.Char(string='访问地址', default='https://sf.cs.jikimo.com')
agv_rcms_url = fields.Char(string='avg_rcms访问地址',
default='http://IP:PORT/rcms/services/rest/hikRpcService/genAgvSchedulingTask')
agv_rcs_url = fields.Char(string='avg_rcs访问地址', default='http://IP:PORT/xxx/agv/agvCallbackService/agvCallback')
agv_rcs_url = fields.Char(string='avg_rcs访问地址',
default='http://172.16.10.114:8182/rcms/services/rest/hikRpcService/genAgvSchedulingTask')
wbcode = fields.Char('地码')
agv_code = fields.Char(string='agv编号')
task_type_no = fields.Char('任务单类型编号')
model_parser_url = fields.Char('特征识别路径')
ftp_host = fields.Char(string='FTP的ip')
ftp_port = fields.Char(string='FTP端口')
@@ -95,8 +96,10 @@ class ResConfigSettings(models.TransientModel):
token = config.get_param('token', default='')
sf_secret_key = config.get_param('sf_secret_key', default='')
sf_url = config.get_param('sf_url', default='')
agv_rcms_url = config.get_param('agv_rcms_url', default='')
agv_rcs_url = config.get_param('agv_rcs_url', default='')
wbcode = config.get_param('wbcode', default='')
agv_code = config.get_param('agv_code', default='')
task_type_no = config.get_param('task_type_no', default='')
ftp_host = config.get_param('ftp_host', default='')
ftp_port = config.get_param('ftp_port', default='')
ftp_user = config.get_param('ftp_user', default='')
@@ -106,8 +109,10 @@ class ResConfigSettings(models.TransientModel):
token=token,
sf_secret_key=sf_secret_key,
sf_url=sf_url,
agv_rcms_url=agv_rcms_url,
agv_rcs_url=agv_rcs_url,
wbcode=wbcode,
agv_code=agv_code,
task_type_no=task_type_no,
ftp_host=ftp_host,
ftp_port=ftp_port,
ftp_user=ftp_user,
@@ -121,9 +126,19 @@ class ResConfigSettings(models.TransientModel):
ir_config.set_param("token", self.token or "")
ir_config.set_param("sf_secret_key", self.sf_secret_key or "")
ir_config.set_param("sf_url", self.sf_url or "")
ir_config.set_param("agv_rcms_url", self.agv_rcms_url or "")
ir_config.set_param("agv_rcs_url", self.agv_rcs_url or "")
ir_config.set_param("wbcode", self.wbcode or "")
ir_config.set_param("agv_code", self.agv_code or "")
ir_config.set_param("task_type_no", self.task_type_no or "")
ir_config.set_param("ftp_host", self.ftp_host or "")
ir_config.set_param("ftp_port", self.ftp_port or "")
ir_config.set_param("ftp_user", self.ftp_user or "")
ir_config.set_param("ftp_password", self.ftp_password or "")
class ResAgvSite(models.Model):
_name = 'res.agv.site'
_description = 'agv站点'
type = fields.Selection([('00', '位置编号'), ('01', '库区编号'), ('02', '货架编号')], '类型')
content = fields.Char('内容')

View File

@@ -52,8 +52,6 @@ class MrStaticResourceDataSync(models.Model):
logging.info("夹具型号已每日同步成功")
self.env['sf.fixture.materials.basic.parameters'].sync_fixture_materials_basic_parameters_yesterday()
logging.info("夹具型号基本参数已每日同步成功")
self.env['sf.functional.fixture.type'].sync_fixture_materials_basic_parameters_yesterday()
logging.info("夹具型号基本参数已每日同步成功")
self.env['sf.functional.fixture.type'].sync_functional_fixture_type_yesterday()
logging.info("功能夹具类型已每日同步成功")
self.env['sf.cutting.tool.material'].sync_cutting_tool_material_yesterday()
@@ -1952,24 +1950,22 @@ class CuttingSpeed(models.Model):
'active': item['active'],
})
else:
if item['active'] is False:
item.write({'active': False})
else:
self.write({
'execution_standard_id': self.env['sf.international.standards'].search(
[('code', '=', item['execution_standard_code'])]).id,
'material_name_id': self.env['sf.materials.model'].search(
[('materials_no', '=', item['material_name'])]).id,
'cutting_width_depth_id': self.env['sf.cutting.width.depth'].search(
[('name', '=', item['cutting_width_depth'])]).id,
'ability_feature_library': self.env['maintenance.equipment.image'].search(
[('name', '=', item['ability_feature_library']), ('type', '=', '加工能力')]).id,
'material_code': item['material_code'],
'material_grade': item['material_grade'],
'tensile_strength': item['tensile_strength'],
'hardness': item['hardness'],
'cutting_speed': item['cutting_speed'],
'application': item['application'], })
cutting_speed.write({
'execution_standard_id': self.env['sf.international.standards'].search(
[('code', '=', item['execution_standard_code'])]).id,
'material_name_id': self.env['sf.materials.model'].search(
[('materials_no', '=', item['material_name'])]).id,
'cutting_width_depth_id': self.env['sf.cutting.width.depth'].search(
[('name', '=', item['cutting_width_depth'])]).id,
'ability_feature_library': self.env['maintenance.equipment.image'].search(
[('name', '=', item['ability_feature_library']), ('type', '=', '加工能力')]).id,
'material_code': item['material_code'],
'material_grade': item['material_grade'],
'tensile_strength': item['tensile_strength'],
'hardness': item['hardness'],
'cutting_speed': item['cutting_speed'],
'application': item['application'],
'active': item['active']})
else:
raise ValidationError("切削速度认证未通过")
@@ -2006,24 +2002,22 @@ class CuttingSpeed(models.Model):
'active': item['active'],
})
else:
if item['active'] is False:
item.write({'active': False})
else:
self.write({
'execution_standard_id': self.env['sf.international.standards'].search(
[('code', '=', item['execution_standard_code'])]).id,
'material_name_id': self.env['sf.materials.model'].search(
[('materials_no', '=', item['material_name'])]).id,
'cutting_width_depth_id': self.env['sf.cutting.width.depth'].search(
[('name', '=', item['cutting_width_depth'])]).id,
'ability_feature_library': self.env['maintenance.equipment.image'].search(
[('name', '=', item['ability_feature_library']), ('type', '=', '加工能力')]).id,
'material_code': item['material_code'],
'material_grade': item['material_grade'],
'tensile_strength': item['tensile_strength'],
'hardness': item['hardness'],
'cutting_speed': item['cutting_speed'],
'application': item['application'], })
cutting_speed.write({
'execution_standard_id': self.env['sf.international.standards'].search(
[('code', '=', item['execution_standard_code'])]).id,
'material_name_id': self.env['sf.materials.model'].search(
[('materials_no', '=', item['material_name'])]).id,
'cutting_width_depth_id': self.env['sf.cutting.width.depth'].search(
[('name', '=', item['cutting_width_depth'])]).id,
'ability_feature_library': self.env['maintenance.equipment.image'].search(
[('name', '=', item['ability_feature_library']), ('type', '=', '加工能力')]).id,
'material_code': item['material_code'],
'material_grade': item['material_grade'],
'tensile_strength': item['tensile_strength'],
'hardness': item['hardness'],
'cutting_speed': item['cutting_speed'],
'application': item['application'],
'active': item['active']})
else:
raise ValidationError("切削速度认证未通过")
@@ -2098,16 +2092,14 @@ class CuttingSpeed(models.Model):
'active': item['active'],
})
else:
if item['active'] is False:
item.write({'active': False})
else:
self.write({
'materials_type_id': self.env['sf.materials.model'].search(
[('materials_no', '=', item['materials_type_code'])]).id,
'cutting_width_depth_id': self.env['sf.cutting.width.depth'].search(
[('name', '=', item['cutting_width_depth'])]).id,
'blade_diameter': item['blade_diameter'],
'feed_per_tooth': item['feed_per_tooth'], })
feed_per_tooth.write({
'materials_type_id': self.env['sf.materials.model'].search(
[('materials_no', '=', item['materials_type_code'])]).id,
'cutting_width_depth_id': self.env['sf.cutting.width.depth'].search(
[('name', '=', item['cutting_width_depth'])]).id,
'blade_diameter': item['blade_diameter'],
'feed_per_tooth': item['feed_per_tooth'],
'active': item['active']})
else:
raise ValidationError("每齿走刀量认证未通过")
@@ -2136,16 +2128,14 @@ class CuttingSpeed(models.Model):
'active': item['active'],
})
else:
if item['active'] is False:
item.write({'active': False})
else:
self.write({
'materials_type_id': self.env['sf.materials.model'].search(
[('materials_no', '=', item['materials_type_code'])]).id,
'cutting_width_depth_id': self.env['sf.cutting.width.depth'].search(
[('name', '=', item['cutting_width_depth'])]).id,
'blade_diameter': item['blade_diameter'],
'feed_per_tooth': item['feed_per_tooth'], })
feed_per_tooth.write({
'materials_type_id': self.env['sf.materials.model'].search(
[('materials_no', '=', item['materials_type_code'])]).id,
'cutting_width_depth_id': self.env['sf.cutting.width.depth'].search(
[('name', '=', item['cutting_width_depth'])]).id,
'blade_diameter': item['blade_diameter'],
'feed_per_tooth': item['feed_per_tooth'],
'active': item['active']})
else:
raise ValidationError("每齿走刀量认证未通过")
@@ -2421,7 +2411,7 @@ class CuttingToolBasicParameters(models.Model):
'active': integral_tool_item['active'],
})
else:
self.write({
self.search([('code', '=', integral_tool_item['code'])]).write({
'name': integral_tool_item['name'],
'total_length': integral_tool_item['total_length'],
'blade_diameter': integral_tool_item['blade_diameter'],
@@ -2482,7 +2472,7 @@ class CuttingToolBasicParameters(models.Model):
'active': blade_item['active'],
})
else:
self.write({
self.search([('code', '=', blade_item['code'])]).write({
'name': blade_item['name'],
'length': blade_item['length'],
'thickness': blade_item['thickness'],
@@ -2539,7 +2529,7 @@ class CuttingToolBasicParameters(models.Model):
'active': chuck_item['active'],
})
else:
self.write({
self.search([('code', '=', chuck_item['code'])]).write({
'name': chuck_item['name'],
'er_size_model': chuck_item['size_model'],
'min_clamping_diameter': chuck_item['clamping_diameter_min'],
@@ -2598,7 +2588,7 @@ class CuttingToolBasicParameters(models.Model):
'active': cutter_arbor_item['active'],
})
else:
self.write({
self.search([('code', '=', cutter_arbor_item['code'])]).write({
'name': cutter_arbor_item['name'],
'height': cutter_arbor_item['height'],
'width': cutter_arbor_item['width'],
@@ -2662,7 +2652,7 @@ class CuttingToolBasicParameters(models.Model):
'active': cutter_head_item['active'],
})
else:
self.write({
self.search([('code', '=', cutter_head_item['code'])]).write({
'name': cutter_head_item['name'],
'install_blade_tip_num': cutter_head_item['number_blade_installed'],
'blade_diameter': cutter_head_item['blade_diameter'],
@@ -2691,57 +2681,38 @@ class CuttingToolBasicParameters(models.Model):
for knife_handle_item in basic_parameters_knife_handle_list:
knife_handle = self.search(
[('code', '=', knife_handle_item['code']), ('active', 'in', [True, False])])
val = {
'name': knife_handle_item['name'],
'taper_shank_model': knife_handle_item['taper_shank_model'],
'total_length': knife_handle_item['total_length'],
'flange_shank_length': knife_handle_item['flange_length'],
'flange_diameter': knife_handle_item['flange_diameter'],
'shank_length': knife_handle_item['shank_length'],
'shank_diameter': knife_handle_item['shank_diameter'],
'min_clamping_diameter': knife_handle_item['clamping_diameter_min'],
'max_clamping_diameter': knife_handle_item['clamping_diameter_max'],
'clamping_mode': knife_handle_item['clamping_way'],
'tool_changing_time': knife_handle_item['tool_changing_time'],
'max_rotate_speed': knife_handle_item['rotate_speed_max'],
'diameter_slip_accuracy': knife_handle_item['diameter_slip_accuracy'],
'cooling_model': knife_handle_item['cooling_model'],
'fit_chuck_size': knife_handle_item['fit_chuck_size'],
'is_quick_cutting': knife_handle_item['is_quick_cutting'],
'is_safe_lock': knife_handle_item['is_safe_lock'],
'screw': knife_handle_item['fit_wrench_model'],
'nut': knife_handle_item['fit_nut_model'],
'dynamic_balance_class': knife_handle_item['dynamic_balance_class'],
'active': knife_handle_item['active'],
}
if not knife_handle:
self.create({
'name': knife_handle_item['name'],
'code': knife_handle_item['code'],
'cutting_tool_type': '刀柄',
'taper_shank_model': knife_handle_item['taper_shank_model'],
'standard_library_id': self.env['sf.cutting_tool.standard.library'].search(
[('code', '=', knife_handle_item['standard_library_code'].replace("JKM", result[
'factory_short_name']))]).id,
'total_length': knife_handle_item['total_length'],
'flange_shank_length': knife_handle_item['flange_length'],
'flange_diameter': knife_handle_item['flange_diameter'],
'shank_length': knife_handle_item['shank_length'],
'shank_diameter': knife_handle_item['shank_diameter'],
'min_clamping_diameter': knife_handle_item['clamping_diameter_min'],
'max_clamping_diameter': knife_handle_item['clamping_diameter_max'],
'clamping_mode': knife_handle_item['clamping_way'],
'tool_changing_time': knife_handle_item['tool_changing_time'],
'max_rotate_speed': knife_handle_item['rotate_speed_max'],
'diameter_slip_accuracy': knife_handle_item['diameter_slip_accuracy'],
'cooling_model': knife_handle_item['cooling_model'],
'is_quick_cutting': knife_handle_item['is_quick_cutting'],
'is_safe_lock': knife_handle_item['is_safe_lock'],
'screw': knife_handle_item['fit_wrench_model'],
'nut': knife_handle_item['fit_nut_model'],
'dynamic_balance_class': knife_handle_item['dynamic_balance_class'],
'active': knife_handle_item['active'],
})
val['code'] = knife_handle_item['code']
val['cutting_tool_type'] = '刀柄'
val['standard_library_id'] = self.env['sf.cutting_tool.standard.library'].search(
[('code', '=', knife_handle_item['standard_library_code'].replace("JKM", result[
'factory_short_name']))]).id
self.create(val)
else:
self.write({
'name': knife_handle_item['name'],
'taper_shank_model': knife_handle_item['taper_shank_model'],
'total_length': knife_handle_item['total_length'],
'flange_shank_length': knife_handle_item['flange_length'],
'flange_diameter': knife_handle_item['flange_diameter'],
'shank_length': knife_handle_item['shank_length'],
'shank_diameter': knife_handle_item['shank_diameter'],
'min_clamping_diameter': knife_handle_item['clamping_diameter_min'],
'max_clamping_diameter': knife_handle_item['clamping_diameter_max'],
'clamping_mode': knife_handle_item['clamping_way'],
'tool_changing_time': knife_handle_item['tool_changing_time'],
'max_rotate_speed': knife_handle_item['rotate_speed_max'],
'diameter_slip_accuracy': knife_handle_item['diameter_slip_accuracy'],
'cooling_model': knife_handle_item['cooling_model'],
'is_quick_cutting': knife_handle_item['is_quick_cutting'],
'is_safe_lock': knife_handle_item['is_safe_lock'],
'screw': knife_handle_item['fit_wrench_model'],
'nut': knife_handle_item['fit_nut_model'],
'dynamic_balance_class': knife_handle_item['dynamic_balance_class'],
'active': knife_handle_item['active'],
})
self.search([('code', '=', knife_handle_item['code'])]).write(val)
else:
raise ValidationError("刀具物料基本参数认证未通过")
@@ -2790,29 +2761,26 @@ class CuttingToolBasicParameters(models.Model):
'active': integral_tool_item['active'],
})
else:
if integral_tool_item['active'] is False:
integral_tool.write({'active': False})
else:
self.write({
'name': integral_tool_item['name'],
'total_length': integral_tool_item['total_length'],
'blade_diameter': integral_tool_item['blade_diameter'],
'blade_length': integral_tool_item['blade_length'],
'blade_number': integral_tool_item['blade_number'],
'neck_length': integral_tool_item['neck_length'],
'neck_diameter': integral_tool_item['neck_diameter'],
'handle_diameter': integral_tool_item['shank_diameter'],
'handle_length': integral_tool_item['shank_length'],
'blade_tip_diameter': integral_tool_item['tip_diameter'],
'blade_tip_working_size': integral_tool_item['tip_handling_size'],
'blade_tip_taper': integral_tool_item['knife_tip_taper'],
'blade_helix_angle': integral_tool_item['blade_helix_angle'],
'blade_width': integral_tool_item['blade_width'],
'blade_depth': integral_tool_item['blade_depth'],
'pitch': integral_tool_item['pitch'],
'cutting_depth': integral_tool_item['cutting_depth_max'],
'active': integral_tool_item['active'],
})
integral_tool.write({
'name': integral_tool_item['name'],
'total_length': integral_tool_item['total_length'],
'blade_diameter': integral_tool_item['blade_diameter'],
'blade_length': integral_tool_item['blade_length'],
'blade_number': integral_tool_item['blade_number'],
'neck_length': integral_tool_item['neck_length'],
'neck_diameter': integral_tool_item['neck_diameter'],
'handle_diameter': integral_tool_item['shank_diameter'],
'handle_length': integral_tool_item['shank_length'],
'blade_tip_diameter': integral_tool_item['tip_diameter'],
'blade_tip_working_size': integral_tool_item['tip_handling_size'],
'blade_tip_taper': integral_tool_item['knife_tip_taper'],
'blade_helix_angle': integral_tool_item['blade_helix_angle'],
'blade_width': integral_tool_item['blade_width'],
'blade_depth': integral_tool_item['blade_depth'],
'pitch': integral_tool_item['pitch'],
'cutting_depth': integral_tool_item['cutting_depth_max'],
'active': integral_tool_item['active'],
})
if 'basic_parameters_blade' in result['cutting_tool_basic_parameters_yesterday_list']:
if result['cutting_tool_basic_parameters_yesterday_list']['basic_parameters_blade']:
basic_parameters_blade_list = json.loads(
@@ -2854,35 +2822,33 @@ class CuttingToolBasicParameters(models.Model):
'active': blade_item['active'],
})
else:
if blade_item['active'] is False:
blade.write({'active': False})
else:
self.write({
'name': blade_item['name'],
'length': blade_item['length'],
'thickness': blade_item['thickness'],
'cutting_blade_length': blade_item['cutting_blade_length'],
'relief_angle': blade_item['relief_angle'],
'blade_tip_circular_arc_radius': blade_item['radius_tip_re'],
'inscribed_circle_diameter': blade_item['diameter_inner_circle'],
'install_aperture_diameter': blade_item['diameter_mounting_hole'],
'pitch': blade_item['pitch'],
'chip_breaker_groove': blade_item['is_chip_breaker'],
'chip_breaker_type_code': blade_item['chip_breaker_type_code'],
'blade_teeth_model': '' if not blade_item['blade_profile'] else blade_item[
'blade_profile'],
'blade_blade_number': blade_item['blade_number'],
'cutting_depth': blade_item['cutting_depth_max'],
'blade_width': blade_item['blade_width'],
'main_included_angle': blade_item['edge_angle'],
'top_angle': blade_item['top_angle'],
'thread_model': '' if not blade_item['thread_type'] else blade_item[
'thread_type'],
'thread_num': blade_item['threads_per_inch'],
'blade_tip_height_tolerance': blade_item['tip_height_tolerance'],
'inscribed_circle_tolerance': blade_item['internal_circle_tolerance'],
'thickness_tolerance': blade_item['thickness_tolerance'],
})
blade.write({
'name': blade_item['name'],
'length': blade_item['length'],
'thickness': blade_item['thickness'],
'cutting_blade_length': blade_item['cutting_blade_length'],
'relief_angle': blade_item['relief_angle'],
'blade_tip_circular_arc_radius': blade_item['radius_tip_re'],
'inscribed_circle_diameter': blade_item['diameter_inner_circle'],
'install_aperture_diameter': blade_item['diameter_mounting_hole'],
'pitch': blade_item['pitch'],
'chip_breaker_groove': blade_item['is_chip_breaker'],
'chip_breaker_type_code': blade_item['chip_breaker_type_code'],
'blade_teeth_model': '' if not blade_item['blade_profile'] else blade_item[
'blade_profile'],
'blade_blade_number': blade_item['blade_number'],
'cutting_depth': blade_item['cutting_depth_max'],
'blade_width': blade_item['blade_width'],
'main_included_angle': blade_item['edge_angle'],
'top_angle': blade_item['top_angle'],
'thread_model': '' if not blade_item['thread_type'] else blade_item[
'thread_type'],
'thread_num': blade_item['threads_per_inch'],
'blade_tip_height_tolerance': blade_item['tip_height_tolerance'],
'inscribed_circle_tolerance': blade_item['internal_circle_tolerance'],
'thickness_tolerance': blade_item['thickness_tolerance'],
'active': blade_item['active']
})
if 'basic_parameters_chuck' in result['cutting_tool_basic_parameters_yesterday_list']:
if result['cutting_tool_basic_parameters_yesterday_list']['basic_parameters_chuck']:
basic_parameters_chuck_list = json.loads(
@@ -2913,24 +2879,22 @@ class CuttingToolBasicParameters(models.Model):
'active': chuck_item['active'],
})
else:
if chuck_item['active'] is False:
chuck.write({'active': False})
else:
self.write({
'name': chuck_item['name'],
'er_size_model': chuck_item['size_model'],
'min_clamping_diameter': chuck_item['clamping_diameter_min'],
'max_clamping_diameter': chuck_item['clamping_diameter_max'],
'outer_diameter': chuck_item['outer_diameter'],
'inner_diameter': chuck_item['inner_diameter'],
'run_out_accuracy': chuck_item['run_out_accuracy'],
'total_length': chuck_item['total_length'],
'taper': chuck_item['taper'],
'top_diameter': chuck_item['top_diameter'],
'weight': chuck_item['weight'],
'max_load_capacity': chuck_item['load_capacity_max'],
'cooling_jacket': chuck_item['cooling_sleeve_model'],
})
chuck.write({
'name': chuck_item['name'],
'er_size_model': chuck_item['size_model'],
'min_clamping_diameter': chuck_item['clamping_diameter_min'],
'max_clamping_diameter': chuck_item['clamping_diameter_max'],
'outer_diameter': chuck_item['outer_diameter'],
'inner_diameter': chuck_item['inner_diameter'],
'run_out_accuracy': chuck_item['run_out_accuracy'],
'total_length': chuck_item['total_length'],
'taper': chuck_item['taper'],
'top_diameter': chuck_item['top_diameter'],
'weight': chuck_item['weight'],
'max_load_capacity': chuck_item['load_capacity_max'],
'cooling_jacket': chuck_item['cooling_sleeve_model'],
'active': chuck_item['active']
})
if 'basic_parameters_cutter_arbor' in result['cutting_tool_basic_parameters_yesterday_list']:
if result['cutting_tool_basic_parameters_yesterday_list']['basic_parameters_cutter_arbor']:
basic_parameters_cutter_arbor_list = json.loads(
@@ -2974,38 +2938,36 @@ class CuttingToolBasicParameters(models.Model):
'active': cutter_arbor_item['active'],
})
else:
if cutter_arbor_item['active'] is False:
cutter_arbor.write({'active': False})
else:
self.write({
'name': cutter_arbor_item['name'],
'height': cutter_arbor_item['height'],
'width': cutter_arbor_item['width'],
'total_length': cutter_arbor_item['total_length'],
'knife_head_height': cutter_arbor_item['head_length'],
'knife_head_width': cutter_arbor_item['head_width'],
'knife_head_length': cutter_arbor_item['head_length'],
'cutter_arbor_diameter': cutter_arbor_item['arbor_diameter'],
'main_included_angle': cutter_arbor_item['edge_angle'],
'relief_angle': cutter_arbor_item['relief_angle'],
'cutting_depth': cutter_arbor_item['cutting_depth_max'],
'min_machining_aperture': cutter_arbor_item['machining_aperture_min'],
'install_blade_tip_num': cutter_arbor_item['number_blade_installed'],
'is_cooling_hole': cutter_arbor_item['is_cooling_hole'],
'locating_slot_code': cutter_arbor_item['locator_slot_code'],
'installing_structure': cutter_arbor_item['mounting_structure'],
'blade_id': False if not cutter_arbor_item['fit_blade_model_code'] else
self.env[
'sf.cutting_tool.standard.library'].search(
[('code', '=',
cutter_arbor_item['fit_blade_model_code'].replace("JKM", result[
'factory_short_name']))]).id,
'tool_shim': cutter_arbor_item['fit_knife_pad_model'],
'cotter_pin': cutter_arbor_item['fit_pin_model'],
'pressing_plate': cutter_arbor_item['fit_plate_model'],
'screw': cutter_arbor_item['fit_screw_model'],
'spanner': cutter_arbor_item['fit_wrench_model'],
})
cutter_arbor.write({
'name': cutter_arbor_item['name'],
'height': cutter_arbor_item['height'],
'width': cutter_arbor_item['width'],
'total_length': cutter_arbor_item['total_length'],
'knife_head_height': cutter_arbor_item['head_length'],
'knife_head_width': cutter_arbor_item['head_width'],
'knife_head_length': cutter_arbor_item['head_length'],
'cutter_arbor_diameter': cutter_arbor_item['arbor_diameter'],
'main_included_angle': cutter_arbor_item['edge_angle'],
'relief_angle': cutter_arbor_item['relief_angle'],
'cutting_depth': cutter_arbor_item['cutting_depth_max'],
'min_machining_aperture': cutter_arbor_item['machining_aperture_min'],
'install_blade_tip_num': cutter_arbor_item['number_blade_installed'],
'is_cooling_hole': cutter_arbor_item['is_cooling_hole'],
'locating_slot_code': cutter_arbor_item['locator_slot_code'],
'installing_structure': cutter_arbor_item['mounting_structure'],
'blade_id': False if not cutter_arbor_item['fit_blade_model_code'] else
self.env[
'sf.cutting_tool.standard.library'].search(
[('code', '=',
cutter_arbor_item['fit_blade_model_code'].replace("JKM", result[
'factory_short_name']))]).id,
'tool_shim': cutter_arbor_item['fit_knife_pad_model'],
'cotter_pin': cutter_arbor_item['fit_pin_model'],
'pressing_plate': cutter_arbor_item['fit_plate_model'],
'screw': cutter_arbor_item['fit_screw_model'],
'spanner': cutter_arbor_item['fit_wrench_model'],
'active': cutter_arbor_item['active']
})
if 'basic_parameters_cutter_head' in result['cutting_tool_basic_parameters_yesterday_list']:
if result['cutting_tool_basic_parameters_yesterday_list']['basic_parameters_cutter_head']:
basic_parameters_cutter_head_list = json.loads(
@@ -3042,30 +3004,28 @@ class CuttingToolBasicParameters(models.Model):
'active': cutter_head_item['active'],
})
else:
if cutter_head_item['active'] is False:
cutter_head.write({'active': False})
else:
self.write({
'name': cutter_head_item['name'],
'install_blade_tip_num': cutter_head_item['number_blade_installed'],
'blade_diameter': cutter_head_item['blade_diameter'],
'cutter_head_diameter': cutter_head_item['cutter_diameter'],
'interface_diameter': cutter_head_item['interface_diameter'],
'total_length': cutter_head_item['total_length'],
'blade_length': cutter_head_item['blade_length'],
'cutting_depth': cutter_head_item['cutting_depth_max'],
'main_included_angle': cutter_head_item['edge_angle'],
'installing_structure': cutter_head_item['mounting_structure'],
'blade_id': False if not cutter_head_item['fit_blade_model_code'] else self.env[
'sf.cutting_tool.standard.library'].search(
[('code', '=',
cutter_head_item['fit_blade_model_code'].replace("JKM", result[
'factory_short_name']))]).id,
'screw': cutter_head_item['fit_screw_model'],
'spanner': cutter_head_item['fit_wrench_model'],
'is_cooling_hole': cutter_head_item['is_cooling_hole'],
'locating_slot_code': cutter_head_item['locator_slot_code'],
})
cutter_head.write({
'name': cutter_head_item['name'],
'install_blade_tip_num': cutter_head_item['number_blade_installed'],
'blade_diameter': cutter_head_item['blade_diameter'],
'cutter_head_diameter': cutter_head_item['cutter_diameter'],
'interface_diameter': cutter_head_item['interface_diameter'],
'total_length': cutter_head_item['total_length'],
'blade_length': cutter_head_item['blade_length'],
'cutting_depth': cutter_head_item['cutting_depth_max'],
'main_included_angle': cutter_head_item['edge_angle'],
'installing_structure': cutter_head_item['mounting_structure'],
'blade_id': False if not cutter_head_item['fit_blade_model_code'] else self.env[
'sf.cutting_tool.standard.library'].search(
[('code', '=',
cutter_head_item['fit_blade_model_code'].replace("JKM", result[
'factory_short_name']))]).id,
'screw': cutter_head_item['fit_screw_model'],
'spanner': cutter_head_item['fit_wrench_model'],
'is_cooling_hole': cutter_head_item['is_cooling_hole'],
'locating_slot_code': cutter_head_item['locator_slot_code'],
'active': cutter_head_item['active']
})
if 'basic_parameters_knife_handle' in result['cutting_tool_basic_parameters_yesterday_list']:
if result['cutting_tool_basic_parameters_yesterday_list']['basic_parameters_knife_handle']:
basic_parameters_knife_handle_list = json.loads(
@@ -3097,35 +3057,35 @@ class CuttingToolBasicParameters(models.Model):
'cooling_model': knife_handle_item['cooling_model'],
'is_quick_cutting': knife_handle_item['is_quick_cutting'],
'is_safe_lock': knife_handle_item['is_safe_lock'],
'fit_chuck_size': knife_handle_item['fit_chuck_size'],
'screw': knife_handle_item['fit_wrench_model'],
'nut': knife_handle_item['fit_nut_model'],
'dynamic_balance_class': knife_handle_item['dynamic_balance_class'],
'active': knife_handle_item['active'],
})
else:
if knife_handle_item['active'] is False:
knife_handle.write({'active': False})
else:
self.write({
'name': knife_handle_item['name'],
'total_length': knife_handle_item['total_length'],
'taper_shank_model': knife_handle_item['taper_shank_model'],
'flange_shank_length': knife_handle_item['flange_length'],
'flange_diameter': knife_handle_item['flange_diameter'],
'shank_length': knife_handle_item['shank_length'],
'shank_diameter': knife_handle_item['shank_diameter'],
'min_clamping_diameter': knife_handle_item['clamping_diameter_min'],
'max_clamping_diameter': knife_handle_item['clamping_diameter_max'],
'clamping_mode': knife_handle_item['clamping_way'],
'tool_changing_time': knife_handle_item['tool_changing_time'],
'max_rotate_speed': knife_handle_item['rotate_speed_max'],
'diameter_slip_accuracy': knife_handle_item['diameter_slip_accuracy'],
'cooling_model': knife_handle_item['cooling_model'],
'is_quick_cutting': knife_handle_item['is_quick_cutting'],
'is_safe_lock': knife_handle_item['is_safe_lock'],
'screw': knife_handle_item['fit_wrench_model'],
'nut': knife_handle_item['fit_nut_model'],
'dynamic_balance_class': knife_handle_item['dynamic_balance_class'],
})
knife_handle.write({
'name': knife_handle_item['name'],
'total_length': knife_handle_item['total_length'],
'taper_shank_model': knife_handle_item['taper_shank_model'],
'flange_shank_length': knife_handle_item['flange_length'],
'flange_diameter': knife_handle_item['flange_diameter'],
'shank_length': knife_handle_item['shank_length'],
'shank_diameter': knife_handle_item['shank_diameter'],
'min_clamping_diameter': knife_handle_item['clamping_diameter_min'],
'max_clamping_diameter': knife_handle_item['clamping_diameter_max'],
'clamping_mode': knife_handle_item['clamping_way'],
'tool_changing_time': knife_handle_item['tool_changing_time'],
'max_rotate_speed': knife_handle_item['rotate_speed_max'],
'diameter_slip_accuracy': knife_handle_item['diameter_slip_accuracy'],
'cooling_model': knife_handle_item['cooling_model'],
'fit_chuck_size': knife_handle_item['fit_chuck_size'],
'is_quick_cutting': knife_handle_item['is_quick_cutting'],
'is_safe_lock': knife_handle_item['is_safe_lock'],
'screw': knife_handle_item['fit_wrench_model'],
'nut': knife_handle_item['fit_nut_model'],
'dynamic_balance_class': knife_handle_item['dynamic_balance_class'],
'active': knife_handle_item['active']
})
else:
raise ValidationError("刀具物料基本参数认证未通过")

View File

@@ -1,5 +1,6 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_sf_static_resource_datasync,sf_static_resource_datasync,model_sf_static_resource_datasync,base.group_user,1,1,1,1
access_res_agv_site,access_res_agv_site,model_res_agv_site,base.group_system,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_sf_static_resource_datasync sf_static_resource_datasync model_sf_static_resource_datasync base.group_user 1 1 1 1
3 access_res_agv_site access_res_agv_site model_res_agv_site base.group_system 1 1 1 1
4
5
6

View File

@@ -1,6 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="view_agv_site_tree" model="ir.ui.view">
<field name="name">agv站点集合</field>
<field name="model">res.agv.site</field>
<field name="arch" type="xml">
<tree editable="bottom">
<field name="type"/>
<field name="content"/>
</tree>
</field>
</record>
<record id="action_agv_site_form" model="ir.actions.act_window">
<field name="name">站点集合</field>
<field name="res_model">res.agv.site</field>
<field name="view_mode">tree</field>
</record>
<menuitem id="menu_action_agv_site_form" action="sf_mrs_connect.action_agv_site_form" name="站点集合"
sequence="11"/>
<record id="res_config_settings_view_form_sf_sync" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.sf_sync</field>
<field name="model">res.config.settings</field>
@@ -84,10 +104,22 @@
<label for="agv_rcs_url" string="访问地址"/>
<field name="agv_rcs_url"/>
</div>
<div class="text-muted">
<label for="task_type_no"/>
<field name="task_type_no"/>
</div>
<div class="text-muted">
<label for="agv_code" string="车辆编号"/>
<field name="agv_code"/>
</div>
<div class="text-muted">
<label for="wbcode"/>
<field name="wbcode"/>
</div>
<div class="mt8">
<button type="action" name="%(sf_mrs_connect.action_agv_site_form)d"
string="站点集合" class="btn-link" icon="fa-arrow-right"/>
</div>
</div>
</div>
</div>

View File

@@ -1,5 +1,6 @@
from . import sale_order
from . import quick_easy_order
# from . import quick_easy_order
from . import quick_easy_order_old
from . import auto_quatotion_common
from . import parser_and_calculate_work_time
from . import preload_datas_functions

View File

@@ -2,7 +2,7 @@
import logging
from odoo.modules import get_resource_path
from odoo import fields, models, api
from quatotion import readSql, feature_recognize, auto_quatotion
# from quatotion import readSql, feature_recognize, auto_quatotion
__author__ = 'jinling.yang'
_logger = logging.getLogger(__name__)

View File

@@ -8,8 +8,8 @@ from datetime import datetime
import requests
from odoo import http
from odoo.http import request
from OCC.Extend.DataExchange import read_step_file
from OCC.Extend.DataExchange import write_stl_file
# 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

View File

@@ -0,0 +1,326 @@
import logging
import base64
import hashlib
import os
import platform
import json
from datetime import datetime
import requests
from odoo import http
from odoo.http import request
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
from . import parser_and_calculate_work_time as pc
class QuickEasyOrder(models.Model):
_name = 'quick.easy.order'
_description = '简易下单'
_order = 'id desc'
name = fields.Char('订单编号', default=lambda self: self.env['ir.sequence'].next_by_code('quick.easy.order'))
model_length = fields.Float('长(mm)', digits=(16, 3))
model_width = fields.Float('宽(mm)', digits=(16, 3))
model_height = fields.Float('高(mm)', digits=(16, 3))
model_volume = fields.Float('体积(mm³)', digits=(16, 3))
model_processing_side = fields.Char('加工面', default='A')
model_feature = fields.Char('特征')
machining_precision = fields.Selection([
('0.10', '±0.10mm'),
('0.05', '±0.05mm'),
('0.03', '±0.03mm'),
('0.02', '±0.02mm'),
('0.01', '±0.01mm')], string='加工精度', default='0.10')
material_id = fields.Many2one('sf.production.materials', '材料')
material_model_id = fields.Many2one('sf.materials.model', '型号')
# process_id = fields.Many2one('sf.production.process', string='表面工艺')
parameter_ids = fields.Many2many('sf.production.process.parameter', 'process_item_order_rel', string='可选参数')
quantity = fields.Integer('数量', default=1)
unit_price = fields.Float('单价')
price = fields.Float('总价')
model_file = fields.Binary('glb模型文件')
upload_model_file = fields.Many2many('ir.attachment', 'upload_qf_model_file_attachment_ref', string='上传模型文件')
delivery_time = fields.Date('交货日期')
customer_id = fields.Many2one('res.partner', string='客户', default=lambda self: self.env.user.partner_id.id)
state = fields.Selection([('草稿', '草稿'), ('待派单', '待派单'),
('待接单', '待接单'), ('加工中', '加工中'),
('物流中', '物流中'), ('已交付', '已交付')], string='订单状态', default='草稿',
readonly=True)
model_color_state = fields.Selection([
('success', '成功'),
('fail', '失败')], string='模型上色状态')
processing_time = fields.Integer('加工时长(min)')
@api.depends('unit_price', 'quantity')
def _compute_total_amount(self):
for item in self:
item.price = item.unit_price * item.quantity
@api.depends('material_id', 'material_model_id')
def _compute_material_model(self):
for item in self:
materials = self.env['sf.production.materials'].search([], limit=1, order='id desc')
item.material_id = materials.id
item.material_model_id = self.env['sf.materials.model'].search(
[('materials_id', '=', materials.id)],
limit=1, order='id desc')
@api.model
def create(self, vals):
if vals.get('upload_model_file'):
logging.info('create-attachment:%s' % vals['upload_model_file'][0])
for item in vals['upload_model_file']:
print(len(item[2]))
if len(item[2]) > 0:
logging.info('create-attachment:%s' % int(item[2][0]))
attachment = self.env['ir.attachment'].sudo().search([('id', '=', int(item[2][0]))])
base64_data = base64.b64encode(attachment.datas)
base64_datas = base64_data.decode('utf-8')
model_code = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest()
report_path = attachment._full_path(attachment.store_fname)
vals['model_file'] = self.transition_glb_file(report_path, model_code)
logging.info('create-model_file:%s' % len(vals['model_file']))
obj = super(QuickEasyOrder, self).create(vals)
self.model_coloring(obj)
logging.info('---------开始派单到工厂-------')
self.distribute_to_factory(obj)
obj.state = '待接单'
return obj
# 将attach的datas内容转为glb文件
def transition_glb_file(self, report_path, model_code):
shapes = read_step_file(report_path)
output_file = os.path.join('/tmp', str(model_code) + '.stl')
write_stl_file(shapes, output_file, 'binary', 0.03, 0.5)
# 转化为glb
output_glb_file = os.path.join('/tmp', str(model_code) + '.glb')
util_path = get_resource_path('sf_base', 'static/util')
cmd = 'python3 %s/stl2gltf.py %s %s -b' % (util_path, output_file, output_glb_file)
os.system(cmd)
# 转base64
with open(output_glb_file, 'rb') as fileObj:
image_data = fileObj.read()
base64_data = base64.b64encode(image_data)
return base64_data
# return False
@api.onchange('upload_model_file')
def onchange_model_file(self):
for item in self:
if len(item.upload_model_file) > 1:
raise ValidationError('只允许上传一个文件')
if item.upload_model_file:
file_attachment_id = item.upload_model_file[0]
# 附件路径
report_path = file_attachment_id._full_path(file_attachment_id.store_fname)
logging.info("模型路径: %s" % report_path)
base64_data = base64.b64encode(file_attachment_id.datas)
base64_datas = base64_data.decode('utf-8')
model_code = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest()
logging.info("模型编码: %s" % model_code)
item.model_file = self.transition_glb_file(report_path, model_code)
else:
item.model_file = False
item.model_feature = False
item.model_length = 0
item.model_width = 0
item.model_height = 0
item.model_volume = 0
def distribute_to_factory(self, obj):
"""
派单到工厂
:return:
"""
try:
logging.info('---------派单到工厂-------')
res = {'bfm_process_order_list': []}
for item in obj:
attachment = item.upload_model_file[0]
base64_data = base64.b64encode(attachment.datas)
base64_datas = base64_data.decode('utf-8')
barcode = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest()
# logging.info('model_file-size: %s' % len(item.model_file))
res['bfm_process_order_list'].append({
'model_long': item.model_length,
'model_width': item.model_width,
'model_height': item.model_height,
'model_volume': item.model_volume,
'model_machining_precision': item.machining_precision,
'model_name': attachment.name,
'model_data': base64_datas,
'model_file': base64.b64encode(item.model_file).decode('utf-8'),
'texture_code': item.material_id.materials_no,
'texture_type_code': item.material_model_id.materials_no,
# 'surface_process_code': self.env['jikimo.surface.process']._json_surface_process_code(item),
'process_parameters_code': self.env[
'sf.production.process.parameter']._json_production_process_item_code(
item),
'price': item.price,
'number': item.quantity,
'total_amount': item.price,
'remark': '',
'barcode': barcode
})
# res['bfm_process_order_list'] = json.dumps(res['bfm_process_order_list'])
product_id = self.env.ref('sf_dlm.product_template_sf').sudo()
self_machining_id = self.env.ref('sf_dlm.product_embryo_sf_self_machining').sudo()
outsource_id = self.env.ref('sf_dlm.product_embryo_sf_outsource').sudo()
purchase_id = self.env.ref('sf_dlm.product_embryo_sf_purchase').sudo()
company_id = self.env.ref('base.main_company').sudo()
# user_id = request.env.ref('base.user_admin').sudo()
order_id = self.env['sale.order'].sale_order_create(company_id, 'XXXXX', 'XXXXX', 'XXXXX',
str(datetime.now()), '现结', '支付宝')
i = 1
# 给sale_order的default_code字段赋值
aa = self.env['sale.order'].sudo().search([('name', '=', order_id.name)])
logging.info('---------aa------- %s' % aa.name)
aa.default_code = obj.name
for item in res['bfm_process_order_list']:
product = self.env['product.template'].sudo().product_create(product_id, item, order_id,
obj.name, i)
bom_data = self.env['mrp.bom'].get_bom(product)
logging.info('bom_data:%s' % bom_data)
if bom_data:
bom = self.env['mrp.bom'].bom_create(product, 'normal', False)
bom.bom_create_line_has(bom_data)
else:
if product.materials_type_id.gain_way == '自加工':
# 创建坯料
self_machining_embryo = self.env['product.template'].sudo().no_bom_product_create(
self_machining_id,
item, order_id,
'self_machining',
i)
# 创建坯料的bom
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 is False:
self.cr.rollback()
return UserError('该订单模型的材料型号在您分配的工厂里暂未有原材料,请先配置再进行分配')
# 产品配置bom
product_bom_self_machining = self.env['mrp.bom'].bom_create(product, 'normal', False)
product_bom_self_machining.bom_create_line_has(self_machining_embryo)
elif product.materials_type_id.gain_way == '外协':
# 创建坯料
outsource_embryo = self.env['product.template'].sudo().no_bom_product_create(outsource_id, item,
order_id,
'subcontract', i)
# 创建坯料的bom
outsource_bom = self.env['mrp.bom'].bom_create(outsource_embryo, 'subcontract', True)
# 创建坯料的bom的组件
outsource_bom_line = outsource_bom.with_user(
self.env.ref("base.user_admin")).bom_create_line(outsource_embryo)
if outsource_bom_line is False:
self.cr.rollback()
return UserError('该订单模型的材料型号在您分配的工厂里暂未有原材料,请先配置再进行分配')
# 产品配置bom
product_bom_outsource = self.env['mrp.bom'].bom_create(product, 'normal', False)
product_bom_outsource.bom_create_line_has(outsource_embryo)
elif product.materials_type_id.gain_way == '采购':
purchase_embryo = self.env['product.template'].sudo().no_bom_product_create(purchase_id, item,
order_id,
'purchase', i)
# 产品配置bom
product_bom_purchase = self.env['mrp.bom'].bom_create(product, 'normal', False)
product_bom_purchase.bom_create_line_has(purchase_embryo)
order_id.with_user(self.env.ref("base.user_admin")).sale_order_create_line(product, item)
except Exception as e:
# self.cr.rollback()
return UserError('工厂创建销售订单和产品失败,请联系管理员')
# 特征识别
def feature_recognition(self, report_path, model_code):
feature_path = self.env['sf.auto_quatotion.common'].sudo().get_feature_full_path()
process_time_db_path = self.env['sf.auto_quatotion.common'].sudo().get_process_time_db_path()
ret = self.env['sf.auto_quatotion.common'].sudo().get_auto_quatotion(report_path, feature_path,
process_time_db_path,
model_code)
return ret
# 模型上色
def model_coloring(self, order):
url = '/api/library_of_models/create'
config = self.env['res.config.settings'].get_values()
config_header = Common.get_headers(self, config['token'], config['sf_secret_key'])
logging.info('order: %s' % order.name)
if order:
attachment = order.upload_model_file[0]
base64_data = base64.b64encode(attachment.datas)
base64_datas = base64_data.decode('utf-8')
model_code = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest()
logging.info('model_file-size: %s' % len(order.model_file))
logging.info('attachment.datas-size: %s' % len(attachment.datas))
vals = {
'model_code': model_code,
'model_data': base64_data,
'model_name': attachment.name,
'model_long': order.model_length,
'model_width': order.model_width,
'model_height': order.model_height,
'model_volume': order.model_volume,
'model_order_no': order.name,
'remark': '订单号:%s 客户:%s' % (order.name, order.customer_id.name)
}
try:
ret = requests.post((config['sf_url'] + url), json={}, data=vals, headers=config_header,
timeout=60)
ret = ret.json()
# result = json.loads(ret['result'])
if ret['status'] == 1:
order.model_color_state = 'success'
else:
order.model_color_state = 'fail'
raise UserError(ret['message'])
except Exception as e:
order.model_color_state = 'fail'
raise UserError("模型上色失败")
# 自动报价
def _get_price(self, order):
url = '/api/automatic_quotes'
config = self.env['res.config.settings'].sudo().get_values()
config_header = Common.get_headers(self, config['token'], config['sf_secret_key'])
logging.info("报价接口..........% s" % order.name)
try:
if order:
vals = {}
# mrs合作伙伴token
vals['token'] = config['token']
vals['accuracy'] = order.machining_precision
vals['number'] = order.quantity
vals['process_code'] = 0
vals['texture_code'] = order.material_model_id.materials_no
vals['delivery_days'] = 15
if order.model_file:
for item in order.upload_model_file:
if item.ids[0]:
logging.info('create-attachment:%s' % int(item.ids[0]))
attachment = self.env['ir.attachment'].sudo().search([('id', '=', int(item.ids[0]))])
vals['attachment_id'] = attachment.id
else:
vals['attachment_id'] = ''
vals['feature_infos'] = order.model_feature
vals['model_long'] = order.model_length
vals['model_width'] = order.model_width
vals['model_height'] = order.model_height
logging.info('vals:%s' % vals)
ret = requests.post((config['sf_url'] + url), json={}, data=vals, headers=config_header)
result = json.dumps(json.loads(ret.text), ensure_ascii=False, indent=4, separators=(',', ':'))
logging.info('报价接口返回:%s' % result)
price_result = json.loads(result)
# random.randint(0, 10000)
order.write({'price': price_result.get('price')})
else:
raise UserError("订单不存在")
except Exception as e:
if ret['status'] != 1:
raise UserError(e)
else:
raise UserError("自动报价失败,请联系管理员")

View File

@@ -85,11 +85,16 @@ class ReSaleOrder(models.Model):
self.check_status = 'pending'
def get_customer(self):
partner_tag = self.env['res.partner.category'].search([('name', '=', '业务平台')], limit=1, order='id asc')
if not partner_tag:
partner_tag = self.env['res.partner.category'].create({'name': '平台客户'})
customer = self.env['res.partner'].search([('name', '=', '业务平台')], limit=1, order='id asc')
if customer:
if not customer.vat:
customer.write({'name': '业务平台', 'vat': '91430103MA7BRH9K4M', 'phone': '0731-85115515',
'email': 'jikimo@jikimo.com', 'category_id': [Command.set([partner_tag.id])]})
return customer
else:
partner_tag = self.env['res.partner.category'].create({'name': '平台客户'})
partner = self.env['res.partner'].create(
{'name': '业务平台', 'vat': '91430103MA7BRH9K4M', 'phone': '0731-85115515',
'email': 'jikimo@jikimo.com', 'category_id': [Command.set([partner_tag.id])]})

View File

@@ -26,7 +26,7 @@
</field>
<field name="email" position="replace">
<field name="email"
attrs="{'required' : [('customer_rank','>', 0)],'readonly': [('id','!=', False)]}"/>
attrs="{'readonly': [('id','!=', False)]}"/>
</field>
<field name="mobile" position="attributes">
<attribute name="attrs">{'required': [('phone', '=', False)],'readonly': [('id','!=', False)]}
@@ -37,19 +37,19 @@
</attribute>
</field>
<field name="street" position="attributes">
<attribute name="attrs">{'required': [('supplier_rank','>', 0)],'readonly': [('id','!=', False)]}
<attribute name="attrs">{'readonly': [('id','!=', False)]}
</attribute>
</field>
<field name="street2" position="attributes">
<attribute name="attrs">{'required': [('supplier_rank','>', 0)],'readonly': [('id','!=', False)]}
<attribute name="attrs">{'readonly': [('id','!=', False)]}
</attribute>
</field>
<field name="city" position="attributes">
<attribute name="attrs">{'required': [('supplier_rank','>', 0)],'readonly': [('id','!=', False)]}
<attribute name="attrs">{'readonly': [('id','!=', False)]}
</attribute>
</field>
<field name="country_id" position="attributes">
<attribute name="attrs">{'required': [('supplier_rank','>', 0)],'readonly': [('id','!=', False)]}
<attribute name="attrs">{'readonly': [('id','!=', False)]}
</attribute>
</field>
<xpath expr="//group[@name='sale']/field[@name='user_id']" position="replace">

View File

@@ -309,7 +309,8 @@ class RealTimeDistributionOfFunctionalTools(models.Model):
_name = 'sf.real.time.distribution.of.functional.tools'
_description = '功能刀具安全库存'
name = fields.Char('功能刀具名称', readonly=True, compute='_compute_name')
name = fields.Char('名称', readonly=True, compute='_compute_name', store=True)
functional_name_id = fields.Many2one('sf.tool.inventory', string='功能刀具名称', required=True)
tool_groups_id = fields.Many2one('sf.tool.groups', '刀具组', readonly=False, required=True)
sf_cutting_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', readonly=False,
group_expand='_read_mrs_cutting_tool_type_ids', store=True)
@@ -355,13 +356,13 @@ class RealTimeDistributionOfFunctionalTools(models.Model):
active = fields.Boolean(string='已归档', default=True)
@api.depends('tool_groups_id', 'diameter', 'knife_tip_r_angle')
@api.depends('functional_name_id')
def _compute_name(self):
for obj in self:
if obj.tool_groups_id:
obj.sudo().name = '%s-D%sR%s' % (obj.tool_groups_id.name, obj.diameter, obj.knife_tip_r_angle)
obj.name = obj.functional_name_id.name
else:
obj.sudo().name = None
obj.sudo().name = ''
@api.constrains('min_stock_num', 'max_stock_num')
def _check_stock_num(self):
@@ -452,7 +453,8 @@ class RealTimeDistributionOfFunctionalTools(models.Model):
"""
# 根据功能刀具名称、刀具组、直径或尖刀R角、粗/中/精查询该功能刀具是否已经存在
record = self.env['sf.real.time.distribution.of.functional.tools'].search(
[('name', '=', vals['name']), ('sf_cutting_tool_type_id', '=', vals['sf_cutting_tool_type_id']),
[('functional_name_id', '=', vals['functional_name_id']),
('sf_cutting_tool_type_id', '=', vals['sf_cutting_tool_type_id']),
('diameter', '=', vals['diameter']), ('knife_tip_r_angle', '=', vals['knife_tip_r_angle']),
('coarse_middle_thin', '=', vals['coarse_middle_thin']), ('tool_groups_id', '=', vals['tool_groups_id'])])
if len(record) > 0:

View File

@@ -40,7 +40,7 @@ class StockLot(models.Model):
sf_secret_key = sf_sync_config['sf_secret_key']
headers = Common.get_headers(self, token, sf_secret_key)
str_url = sf_sync_config['sf_url'] + "/api/tool_material_stock/create"
objs_all = self.env['stock.lot'].search([('id', '=', self.id)])
objs_all = self.env['stock.lot'].search([('id', '=', self.id), ('active', 'in', [True, False])])
tool_material_stock_list = []
if objs_all:
for item in objs_all:

View File

@@ -299,7 +299,8 @@
<field name="model">sf.real.time.distribution.of.functional.tools</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="name" invisible="1"/>
<field name="functional_name_id"/>
<field name="sf_cutting_tool_type_id" invisible="True"/>
<field name="tool_groups_id"/>
<field name="diameter"/>
@@ -329,9 +330,11 @@
<sheet>
<div class="oe_title">
<h1>
<field name="name"/>
<field name="functional_name_id" placeholder="请选择"
attrs="{'readonly': [('status_create', '=', False)]}"/>
</h1>
</div>
<field name="name" invisible="1"/>
<field name="status_create" invisible="1"/>
<group>
<group>
@@ -1056,7 +1059,7 @@
<group>
<group>
<field name="barcode_id" invisible="True"/>
<field name="rfid" string="功能刀具rfid" readonly="false"/>
<field name="rfid" string="功能刀具rfid"/>
<field name="code"/>
<field name="after_assembly_functional_tool_name"
string="功能刀具名称"/>

View File

@@ -222,110 +222,162 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
image = fields.Binary('图片')
# 功能刀具组装信息
# 整体式刀具型号
# ===============整体式刀具型号=================
integral_freight_barcode = fields.Char('整体式刀具货位')
integral_code_id = fields.Many2one('stock.lot', string='整体式刀具序列号',
domain=[('product_id.cutting_tool_material_id.name', '=', '整体式刀具'),
('tool_material_status', '=', '可用')])
integral_product_id = fields.Many2one('product.product', string='整体式刀具名称',
compute='_compute_integral_product_id', store=True)
cutting_tool_integral_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='整体式刀具型号',
related='integral_code_id.product_id.cutting_tool_model_id')
integral_name = fields.Char('整体式刀具名称', related='integral_code_id.product_id.name')
related='integral_product_id.cutting_tool_model_id')
integral_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='整体式刀具规格',
related='integral_code_id.product_id.specification_id')
related='integral_product_id.specification_id')
sf_tool_brand_id_1 = fields.Many2one('sf.machine.brand', string='整体式刀具品牌',
related='integral_code_id.product_id.brand_id')
related='integral_product_id.brand_id')
# 刀片型号
@api.depends('integral_freight_barcode')
def _compute_integral_product_id(self):
location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', self.integral_freight_barcode)])
if location:
self.integral_product_id = location.product_id.id
# ===============刀片型号====================
blade_freight_barcode = fields.Char('刀片货位')
blade_code_id = fields.Many2one('stock.lot', '刀片序列号',
domain=[('product_id.cutting_tool_material_id.name', '=', '刀片'),
('tool_material_status', '=', '可用')])
blade_product_id = fields.Many2one('product.product', string='刀片名称', compute='_compute_blade_product_id',
store=True)
cutting_tool_blade_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀片型号',
related='blade_code_id.product_id.cutting_tool_model_id')
blade_name = fields.Char('刀片名称', related='blade_code_id.product_id.name')
related='blade_product_id.cutting_tool_model_id')
blade_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='刀片规格',
related='blade_code_id.product_id.specification_id')
sf_tool_brand_id_2 = fields.Many2one('sf.machine.brand', '刀片品牌', related='blade_code_id.product_id.brand_id')
related='blade_product_id.specification_id')
sf_tool_brand_id_2 = fields.Many2one('sf.machine.brand', '刀片品牌', related='blade_product_id.brand_id')
# 刀杆型号
@api.depends('blade_freight_barcode')
def _compute_blade_product_id(self):
location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', self.blade_freight_barcode)])
if location:
self.blade_product_id = location.product_id.id
# ====================刀杆型号==================
bar_freight_barcode = fields.Char('刀杆货位')
bar_code_id = fields.Many2one('stock.lot', '刀杆序列号',
domain=[('product_id.cutting_tool_material_id.name', '=', '刀杆'),
('tool_material_status', '=', '可用')])
bar_product_id = fields.Many2one('product.product', string='刀杆名称', compute='_compute_bar_product_id',
store=True)
cutting_tool_cutterbar_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀杆型号',
related='bar_code_id.product_id.cutting_tool_model_id')
bar_name = fields.Char('刀杆名称', related='bar_code_id.product_id.name')
related='bar_product_id.cutting_tool_model_id')
bar_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='刀杆规格',
related='bar_code_id.product_id.specification_id')
sf_tool_brand_id_3 = fields.Many2one('sf.machine.brand', '刀杆品牌', related='bar_code_id.product_id.brand_id')
related='bar_product_id.specification_id')
sf_tool_brand_id_3 = fields.Many2one('sf.machine.brand', '刀杆品牌', related='bar_product_id.brand_id')
# 刀盘型号
@api.depends('bar_freight_barcode')
def _compute_bar_product_id(self):
location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', self.bar_freight_barcode)])
if location:
self.bar_product_id = location.product_id.id
# ===============刀盘型号===================
pad_freight_barcode = fields.Char('刀盘货位')
pad_code_id = fields.Many2one('stock.lot', '刀盘序列号',
domain=[('product_id.cutting_tool_material_id.name', '=', '刀盘'),
('tool_material_status', '=', '可用')])
pad_product_id = fields.Many2one('product.product', string='刀盘名称', compute='_compute_pad_product_id',
store=True)
cutting_tool_cutterpad_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀盘型号',
related='pad_code_id.product_id.cutting_tool_model_id')
pad_name = fields.Char('刀盘名称', related='pad_code_id.product_id.name')
related='pad_product_id.cutting_tool_model_id')
pad_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='刀盘规格',
related='pad_code_id.product_id.specification_id')
sf_tool_brand_id_4 = fields.Many2one('sf.machine.brand', '刀盘品牌', related='pad_code_id.product_id.brand_id')
related='pad_product_id.specification_id')
sf_tool_brand_id_4 = fields.Many2one('sf.machine.brand', '刀盘品牌', related='pad_product_id.brand_id')
# 刀柄型号
@api.depends('pad_freight_barcode')
def _compute_pad_product_id(self):
location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', self.pad_freight_barcode)])
if location:
self.pad_product_id = location.product_id.id
# ================刀柄型号===============
handle_code_id = fields.Many2one('stock.lot', '刀柄序列号', required=True,
domain=[('product_id.cutting_tool_material_id.name', '=', '刀柄'),
('tool_material_status', '=', '可用')])
handle_product_id = fields.Many2one('product.product', string='刀柄名称', related='handle_code_id.product_id')
cutting_tool_cutterhandle_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀柄型号',
related='handle_code_id.product_id.cutting_tool_model_id')
handle_name = fields.Char('刀柄名称', related='handle_code_id.product_id.name')
handle_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='刀柄规格',
related='handle_code_id.product_id.specification_id')
sf_tool_brand_id_5 = fields.Many2one('sf.machine.brand', '刀柄品牌', related='handle_code_id.product_id.brand_id')
# 夹头型号
chuck_code_id = fields.Many2one('stock.lot', '夹头序列号', required=True,
# =================夹头型号==============
chuck_freight_barcode = fields.Char('夹头货位', required=True)
chuck_code_id = fields.Many2one('stock.lot', '夹头序列号',
domain=[('product_id.cutting_tool_material_id.name', '=', '夹头'),
('tool_material_status', '=', '可用')])
chuck_product_id = fields.Many2one('product.product', string='夹头名称', compute='_compute_chuck_product_id',
store=True)
cutting_tool_cutterhead_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='夹头型号',
related='chuck_code_id.product_id.cutting_tool_model_id')
chuck_name = fields.Char('夹头名称', related='chuck_code_id.product_id.name')
related='chuck_product_id.cutting_tool_model_id')
chuck_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='夹头规格',
related='chuck_code_id.product_id.specification_id')
sf_tool_brand_id_6 = fields.Many2one('sf.machine.brand', '夹头品牌', related='chuck_code_id.product_id.brand_id')
related='chuck_product_id.specification_id')
sf_tool_brand_id_6 = fields.Many2one('sf.machine.brand', '夹头品牌', related='chuck_product_id.brand_id')
@api.depends('chuck_freight_barcode')
def _compute_chuck_product_id(self):
location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', self.chuck_freight_barcode)])
if location:
self.chuck_product_id = location.product_id.id
# ========================================
def on_barcode_scanned(self, barcode):
"""
智能工厂组装单处扫码绑定刀具物料')
智能工厂组装单处扫码绑定刀具物料
"""
for record in self:
if 'DJWL' in barcode:
records = record.env['stock.lot'].search([('name', '=', barcode)])
if not records:
raise ValidationError('扫描的条形码数据不存在,请重新扫描!')
for record_stock_lot in records:
if record_stock_lot.quant_ids[-1].location_id.name == '刀具组装位置':
raise ValidationError('该刀具物料已使用,请重新选择')
elif record_stock_lot.quant_ids[-1].location_id.name not in '刀具房':
raise ValidationError('该刀具物料未入库,请重新选择')
tool_material_name = record_stock_lot.product_id.cutting_tool_material_id.name
if tool_material_name == '整体式刀具':
record.integral_code_id = record_stock_lot.id
elif tool_material_name == '刀片':
record.blade_code_id = record_stock_lot.id
elif tool_material_name == '刀杆':
record.bar_code_id = record_stock_lot.id
elif tool_material_name == '刀盘':
record.pad_code_id = record_stock_lot.id
elif tool_material_name == '刀柄':
record.handle_code_id = record_stock_lot.id
elif tool_material_name == '夹头':
record.chuck_code_id = record_stock_lot.id
lot_ids = self.env['stock.lot'].sudo().search([('rfid', '=', barcode)])
if lot_ids:
for lot_id in lot_ids:
if lot_id.quant_ids[-1].location_id.name in '刀具房':
record.handle_code_id = lot_id.id
elif lot_id.quant_ids[-1].location_id.name == '刀具组装位置':
raise ValidationError('该刀已使用,请重新扫描')
else:
raise ValidationError('该刀未入库,请重新扫描')
else:
location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', barcode)])
if location:
material_name = location.product_id.cutting_tool_material_id.name
if material_name == '整体式刀具':
record.integral_freight_barcode = barcode
elif material_name == '刀片':
record.blade_freight_barcode = barcode
elif material_name == '刀杆':
record.bar_freight_barcode = barcode
elif material_name == '刀盘':
record.pad_freight_barcode = barcode
elif material_name == '夹头':
record.chuck_freight_barcode = barcode
else:
raise ValidationError('扫描的刀具物料不存在,请重新扫描!')
else:
raise ValidationError('扫描的刀具物料不存在,请重新扫描!')
@api.depends('handle_code_id')
def _compute_rfid(self):
for item in self:
if item:
item.rfid = item.handle_code_id.rfid
else:
record.rfid = barcode
item.rfid = None
# 组装功能刀具参数信息
after_name_id = fields.Many2one('sf.tool.inventory', string='功能刀具名称', required=True)
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号')
rfid = fields.Char('Rfid', required=True)
rfid = fields.Char('Rfid', readonly=True, store=True, compute='_compute_rfid')
tool_code = fields.Char(string='功能刀具编码', readonly=True, compute='_compute_tool_code')
after_assembly_functional_tool_name = fields.Char(string='组装后功能刀具名称', compute='_compute_name')
after_assembly_functional_tool_name = fields.Char(string='组装后功能刀具名称', compute='_compute_name', store=True)
after_assembly_functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model',
string='组装后功能刀具类型',
compute='_compute_after_assembly_functional_tool_type_id')
@@ -377,7 +429,7 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
num = self._get_code(str_2)
obj.tool_code = str_2 + str(num)
else:
obj.tool_code = None
obj.tool_code = ''
def _get_code(self, str_2):
functional_tool_assembly = self.env['sf.functional.tool.assembly'].sudo().search(
@@ -392,17 +444,15 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
num = "%03d" % m
return num
@api.depends('after_assembly_functional_tool_diameter', 'after_assembly_knife_tip_r_angle', 'tool_groups_id')
@api.depends('after_name_id')
def _compute_name(self):
for obj in self:
if obj.tool_groups_id:
obj.after_assembly_functional_tool_name = '%s-D%sR%s' % (
obj.tool_groups_id.name, obj.after_assembly_functional_tool_diameter,
obj.after_assembly_knife_tip_r_angle)
if obj.after_name_id:
obj.after_assembly_functional_tool_name = obj.after_name_id.name
else:
obj.after_assembly_functional_tool_name = None
obj.after_assembly_functional_tool_name = ''
@api.onchange('integral_code_id')
@api.onchange('integral_freight_barcode')
def _onchange_after_assembly_functional_tool_diameter(self):
for obj in self:
if obj.integral_code_id:
@@ -434,28 +484,23 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
else:
record.L_D_number = 0
@api.constrains('after_assembly_tool_loading_length', 'after_assembly_functional_tool_length')
@api.constrains('after_assembly_tool_loading_length', 'after_assembly_functional_tool_length',
'after_assembly_max_lifetime_value', 'after_assembly_alarm_value',
'after_assembly_effective_length', 'hiding_length')
def _check_length_control(self):
for obj in self:
if obj.after_assembly_tool_loading_length == 0:
raise ValidationError('组装参数信息【总长度】不能为0')
if obj.after_assembly_functional_tool_length == 0:
raise ValidationError('组装参数信息【伸出长】不能为0')
@api.constrains('rfid')
def _check_rfid(self):
self.get_rfid()
@api.onchange('rfid')
def _onchange_rfid(self):
self.get_rfid()
def get_rfid(self):
for obj in self:
if obj.rfid:
tool_entity = self.env['sf.functional.cutting.tool.entity'].sudo().search([('rfid', '=', obj.rfid)])
if tool_entity:
raise ValidationError('%s】的Rfid已被使用请重新录入' % obj.rfid)
if obj.after_assembly_max_lifetime_value == 0:
raise ValidationError('组装参数信息【最大寿命值】不能为0')
if obj.after_assembly_alarm_value == 0:
raise ValidationError('组装参数信息【报警值】不能为0')
if obj.after_assembly_effective_length == 0:
raise ValidationError('组装参数信息【有效长】不能为0')
if obj.hiding_length == 0:
raise ValidationError('组装参数信息【避空长】不能为0')
def functional_tool_assembly(self):
"""
@@ -499,7 +544,7 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
record_1 = self.env['sf.functional.cutting.tool.entity'].create(desc_2)
# 创建安全库存信息
self.env['sf.real.time.distribution.of.functional.tools'].create_or_edit_safety_stock({
'name': self.after_assembly_functional_tool_name,
'functional_name_id': self.after_name_id.id,
'sf_cutting_tool_type_id': self.after_assembly_functional_tool_type_id.id,
'tool_groups_id': self.tool_groups_id.id,
'diameter': self.after_assembly_functional_tool_diameter,
@@ -543,12 +588,12 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
'name': self.after_assembly_functional_tool_name,
'rfid': self.rfid,
'tool_groups_id': self.tool_groups_id.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,
'integral_product_id': self.integral_product_id.id,
'blade_product_id': self.blade_product_id.id,
'bar_product_id': self.bar_product_id.id,
'pad_product_id': self.pad_product_id.id,
'handle_code_id': self.handle_code_id.id,
'chuck_code_id': self.chuck_code_id.id,
'chuck_product_id': self.chuck_product_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,
@@ -583,12 +628,12 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
'tool_groups_id': self.tool_groups_id.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,
'cutting_tool_integral_model_id': self.integral_product_id.id,
'cutting_tool_blade_model_id': self.blade_product_id.id,
'cutting_tool_cutterbar_model_id': self.bar_product_id.id,
'cutting_tool_cutterpad_model_id': self.pad_product_id.id,
'cutting_tool_cutterhandle_model_id': self.handle_product_id.id,
'cutting_tool_cutterhead_model_id': self.chuck_product_id.id,
'functional_tool_diameter': self.after_assembly_functional_tool_diameter,
'knife_tip_r_angle': self.after_assembly_knife_tip_r_angle,

View File

@@ -201,20 +201,18 @@
<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)]}">
attrs="{'invisible': ['|','|',('blade_freight_barcode', '!=', False),('bar_freight_barcode', '!=', False),('pad_freight_barcode', '!=', False)]}">
<div>
<separator string="整体式刀具:" style="font-size: 13px;"/>
</div>
<group>
<group>
<field name="integral_code_id" placeholder="请选择" string="序列号"
class="custom_required"
options="{'no_create': True, 'no_quick_create': True}"/>
<field name="integral_freight_barcode" string="货位"/>
</group>
</group>
<group col="2">
<group>
<field name="integral_name" string="名称"/>
<field name="integral_product_id" string="名称"/>
<field name="integral_specification_id" string="规格"/>
</group>
<group>
@@ -223,20 +221,18 @@
</group>
</group>
</group>
<group col="1" attrs="{'invisible': [('integral_code_id', '!=', False)]}">
<group col="1" attrs="{'invisible': [('integral_freight_barcode', '!=', False)]}">
<div>
<separator string="刀片:" style="font-size: 13px;"/>
</div>
<group>
<group>
<field name="blade_code_id" placeholder="请选择" string="序列号"
class="custom_required"
options="{'no_create': True, 'no_quick_create': True}"/>
<field name="blade_freight_barcode" string="货位"/>
</group>
</group>
<group col="2">
<group>
<field name="blade_name" string="名称"/>
<field name="blade_product_id" string="名称"/>
<field name="blade_specification_id" string="规格"/>
</group>
<group>
@@ -246,20 +242,18 @@
</group>
</group>
<group col="1"
attrs="{'invisible': ['|',('integral_code_id', '!=', False),('pad_code_id', '!=', False)]}">
attrs="{'invisible': ['|',('integral_freight_barcode', '!=', False),('pad_freight_barcode', '!=', False)]}">
<div>
<separator string="刀杆:" style="font-size: 13px;"/>
</div>
<group>
<group>
<field name="bar_code_id" placeholder="请选择" string="序列号"
class="custom_required"
options="{'no_create': True, 'no_quick_create': True}"/>
<field name="bar_freight_barcode" string="货位"/>
</group>
</group>
<group col="2">
<group>
<field name="bar_name" string="名称"/>
<field name="bar_product_id" string="名称"/>
<field name="bar_specification_id" string="规格"/>
</group>
<group>
@@ -269,20 +263,18 @@
</group>
</group>
<group col="1"
attrs="{'invisible': ['|',('integral_code_id', '!=', False),('bar_code_id', '!=', False)]}">
attrs="{'invisible': ['|',('bar_freight_barcode', '!=', False),('bar_freight_barcode', '!=', False)]}">
<div>
<separator string="刀盘:" style="font-size: 13px;"/>
</div>
<group>
<group>
<field name="pad_code_id" placeholder="请选择" string="序列号"
class="custom_required"
options="{'no_create': True, 'no_quick_create': True}"/>
<field name="pad_freight_barcode" string="货位"/>
</group>
</group>
<group col="2">
<group>
<field name="pad_name" string="名称"/>
<field name="pad_product_id" string="名称"/>
<field name="pad_specification_id" string="规格"/>
</group>
<group>
@@ -304,7 +296,7 @@
</group>
<group col="2">
<group>
<field name="handle_name" string="名称"/>
<field name="handle_product_id" string="名称"/>
<field name="handle_specification_id" string="规格"/>
</group>
<group>
@@ -319,14 +311,12 @@
</div>
<group>
<group>
<field name="chuck_code_id" string="序列号" placeholder="请选择"
class="custom_required"
options="{'no_create': True, 'no_quick_create': True}"/>
<field name="chuck_freight_barcode" string="货位"/>
</group>
</group>
<group col="2">
<group>
<field name="chuck_name" string="名称"/>
<field name="chuck_product_id" string="名称"/>
<field name="chuck_specification_id" string="规格"/>
</group>
<group>
@@ -342,7 +332,8 @@
<field name="barcode_id" invisible="True"/>
<field name="tool_code" readonly="True"/>
<field name="rfid" placeholder="请输入rfid码" class="custom_required"/>
<field name="after_assembly_functional_tool_name" string="功能刀具名称"/>
<field name="after_name_id" string="功能刀具名称"/>
<field name="after_assembly_functional_tool_name" string="功能刀具名称" invisible="1"/>
<field name="after_assembly_functional_tool_type_id" string="功能刀具类型"
options="{'no_create': True, 'no_quick_create': True}"/>
<field name="tool_groups_id"/>

View File

@@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
import re
import datetime
import logging
import base64
@@ -19,14 +21,6 @@ class SfLocation(models.Model):
name = fields.Char('Location Name', required=True, size=20)
barcode = fields.Char('Barcode', copy=False, size=15)
check_state = fields.Selection([
('enable', '启用'),
('close', '关闭')
], string='审核状态', default='close')
def action_check(self):
self.check_state = 'enable'
# 仓库类别selection库区、库位、货位
# location_type = fields.Selection([
# ('库区', '库区'),
@@ -444,6 +438,8 @@ class Sf_stock_move_line(models.Model):
current_product_id = fields.Integer(compute='_compute_location_dest_id_value', store=True)
there_is_no_sn = fields.Boolean('是否有序列号', default=False)
rfid = fields.Char('Rfid', readonly=True)
def action_revert_inventory(self):
# 检查用户是否有执行操作的权限
if not self.env.user.has_group('sf_warehouse.group_sf_stock_user'):
@@ -774,21 +770,30 @@ class SfStockPicking(models.Model):
# line.current_location_id.location_status = '空闲'
line.current_location_id.product_num = 0
for move in self.move_ids:
if move and move.product_id.cutting_tool_material_id.name == '刀柄' or '托盘' in (
move.product_id.fixture_material_id.name or ''):
for item in move.move_line_nosuggest_ids:
if item.location_dest_id.name == '进货':
if not item.rfid:
raise ValidationError('你需要提供%s的Rfid' % move.product_id.name)
self.env['stock.lot'].search([('name', '=', item.lot_name)]).write({'rfid': item.rfid})
return res
# def print_all_barcode(self):
# """
# 打印所有编码
# """
# print('================')
# for record in self.move_ids_without_package:
# print('record', record)
# print('record.move_line_ids', record.move_line_ids)
#
# # record.move_line_ids.print_qr_code()
#
# print('record.move_line_ids.lot_id', record.move_line_ids.lot_id)
# print('record.move_line_ids.lot_id.name', record.move_line_ids.lot_id.name)
# def print_all_barcode(self):
# """
# 打印所有编码
# """
# print('================')
# for record in self.move_ids_without_package:
# print('record', record)
# print('record.move_line_ids', record.move_line_ids)
#
# # record.move_line_ids.print_qr_code()
#
# print('record.move_line_ids.lot_id', record.move_line_ids.lot_id)
# print('record.move_line_ids.lot_id.name', record.move_line_ids.lot_id.name)
class SfProcurementGroup(models.Model):
@@ -854,117 +859,43 @@ class SfProcurementGroup(models.Model):
return res
class SfWarehouse(models.Model):
_inherit = 'stock.warehouse'
check_state = fields.Selection([
('enable', '启用'),
('close', '关闭')
], string='审核状态', default='close')
def action_check(self):
self.check_state = 'enable'
class SfRule(models.Model):
_inherit = 'stock.rule'
check_state = fields.Selection([
('enable', '启用'),
('close', '关闭')
], string='审核状态', default='close')
def action_check(self):
self.check_state = 'enable'
class SfRoute(models.Model):
_inherit = 'stock.route'
check_state = fields.Selection([
('enable', '启用'),
('close', '关闭')
], string='审核状态', default='close')
def action_check(self):
self.check_state = 'enable'
class SfPickingType(models.Model):
_inherit = 'stock.picking.type'
check_state = fields.Selection([
('enable', '启用'),
('close', '关闭')
], string='审核状态', default='close')
def action_check(self):
self.check_state = 'enable'
class SfBarcodeNomenclature(models.Model):
_inherit = 'barcode.nomenclature'
check_state = fields.Selection([
('enable', '启用'),
('close', '关闭')
], string='审核状态', default='close')
def action_check(self):
self.check_state = 'enable'
class SfPutawayRule(models.Model):
_inherit = 'stock.putaway.rule'
check_state = fields.Selection([
('enable', '同意'),
('close', '不同意')
], string='审核状态', default='close')
def action_check(self):
self.check_state = 'enable'
class SfWarehouseOrderpoint(models.Model):
_inherit = 'stock.warehouse.orderpoint'
check_state = fields.Selection([
('enable', '同意'),
('close', '不同意')
], string='审核状态', default='close')
def action_check(self):
self.check_state = 'enable'
class SfStockQuant(models.Model):
_inherit = 'stock.quant'
check_state = fields.Selection([
('enable', '同意'),
('close', '不同意')
], string='审核状态', default='close')
def action_check(self):
self.check_state = 'enable'
class SfStockScrap(models.Model):
_inherit = 'stock.scrap'
check_state = fields.Selection([
('enable', '启用'),
('close', '关闭')
], string='审核状态', default='close')
def action_check(self):
self.check_state = 'enable'
def _default_show_operations(self):
return self.user_has_groups('stock.group_production_lot,'
'stock.group_stock_multi_locations,'
'stock.group_tracking_lot',
'sf_warehouse.group_sf_stock_user',
'sf_warehouse.group_sf_stock_manager')
class CustomStockMove(models.Model):
_name = 'stock.move'
_inherit = ['stock.move', 'printing.utils']
_inherit = ['stock.move', 'printing.utils', 'barcodes.barcode_events_mixin']
def on_barcode_scanned(self, barcode):
"""
采购入库扫码绑定Rfid码
"""
for record in self:
if record:
if '刀柄' in (record.product_id.cutting_tool_material_id.name or '') or '托盘' in (
record.product_id.fixture_material_id.name or ''):
for move_line_nosuggest_id in record.move_line_nosuggest_ids:
if move_line_nosuggest_id.rfid:
if move_line_nosuggest_id.rfid == barcode:
if record.product_id.cutting_tool_material_id.name:
raise ValidationError('该刀柄的Rfid已经录入请勿重复录入')
else:
raise ValidationError('该托盘的Rfid已经录入请勿重复录入')
else:
line_id = int(re.sub(r"\D", "", str(move_line_nosuggest_id.id)))
self.env['stock.move.line'].sudo().search([('id', '=', line_id)]).write({'rfid': barcode})
move_line_nosuggest_id.rfid = barcode
break
else:
raise ValidationError('该产品不需要录入Rfid')
def action_assign_serial_show_details(self):
# 首先执行原有逻辑

View File

@@ -39,15 +39,16 @@
<field name="current_location_id" force_save="1"/>
</xpath>
<xpath expr="//field[@name='location_dest_id']" position="after">
<field name="destination_location_id" />
<!-- <field name="location_dest_id_product_type"/> -->
<!-- <field name="location_dest_id"/> -->
<field name="destination_location_id"/>
<!-- <field name="location_dest_id_product_type"/> -->
<!-- <field name="location_dest_id"/> -->
<field name="location_dest_id_value" invisible="1"/>
<!-- <button name="button_test" string="测试" type="object" class="oe_highlight"/> -->
<!-- <button name="button_test" string="测试" type="object" class="oe_highlight"/> -->
</xpath>
</field>
</record>
<record id="sf_stock_move_line_form" model="ir.ui.view">
<field name="name">sf.stock.move.line.form</field>
<field name="model">stock.move.line</field>
@@ -71,6 +72,9 @@
<field name="model">stock.move.line</field>
<field name="inherit_id" ref="stock.view_stock_move_line_operation_tree"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='lot_name']" position="after">
<field name="rfid"/>
</xpath>
<xpath expr="//field[@name='product_uom_id']" position="after">
<field name="lot_qr_code" widget="image"/>
<button name="print_single_method" string="打印编码" type="object" class="oe_highlight"/>
@@ -111,10 +115,10 @@
groups="sf_warehouse.group_sf_stock_user" data-hotkey="k"/>
</xpath>
<!-- <xpath expr="//form//sheet//notebook//page//field[@name='move_ids_without_package']" position="before"> -->
<!-- <field name="check_in" invisible="True"/> -->
<!-- <button name="print_all_barcode" string="打印所有编码" type="object" attrs="{'invisible': [('check_in', '!=', 'IN')]}"/> -->
<!-- </xpath> -->
<!-- <xpath expr="//form//sheet//notebook//page//field[@name='move_ids_without_package']" position="before"> -->
<!-- <field name="check_in" invisible="True"/> -->
<!-- <button name="print_all_barcode" string="打印所有编码" type="object" attrs="{'invisible': [('check_in', '!=', 'IN')]}"/> -->
<!-- </xpath> -->
</field>
</record>
@@ -153,11 +157,23 @@
<field name="model">stock.move</field>
<field name="inherit_id" ref="stock.view_stock_move_operations"/>
<field name="arch" type="xml">
<!-- <xpath expr="//form//field[@name='move_line_ids']" position="before"> -->
<!-- <button name="print_all_barcode" type="object" string="打印所有编码"/> -->
<!-- </xpath> -->
<!-- <xpath expr="//form//field[@name='move_line_ids']" position="before"> -->
<!-- <button name="print_all_barcode" type="object" string="打印所有编码"/> -->
<!-- </xpath> -->
<xpath expr="//form//field[@name='product_id']" position="before">
<button name="print_all_barcode" type="object" string="打印所有编码" class="oe_highlight"/> -->
<button name="print_all_barcode" type="object" string="打印所有编码" class="oe_highlight"/>
-->
</xpath>
</field>
</record>
<record id="mrp_subcontracting_view_stock_move_barcode_scanned" model="ir.ui.view">
<field name="name">mrp.subcontracting.stock.move.barcode.scanned.form</field>
<field name="model">stock.move</field>
<field name="inherit_id" ref="stock.view_stock_move_nosuggest_operations"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='move_line_nosuggest_ids']" position="before">
<field name="_barcode_scanned" widget="barcode_handler"/>
</xpath>
</field>
</record>

View File

@@ -67,16 +67,16 @@
</notebook>
</xpath>
<xpath expr="//sheet" position="before">
<header>
<field name="check_state" invisible="1"/>
<button name="action_check" string="审核" type="object"
attrs="{'invisible': [('check_state','=', 'enable')]}"
groups="sf_warehouse.group_sf_stock_manager"
class="oe_highlight"/>
</header>
<!-- <xpath expr="//sheet" position="before">-->
<!-- <header>-->
<!-- <field name="check_state" invisible="1"/>-->
<!-- <button name="action_check" string="审核" type="object"-->
<!-- attrs="{'invisible': [('check_state','=', 'enable')]}"-->
<!-- groups="sf_warehouse.group_sf_stock_manager"-->
<!-- class="oe_highlight"/>-->
<!-- </header>-->
</xpath>
<!-- </xpath>-->
</field>
</record>
@@ -188,23 +188,23 @@
<!-- </record>-->
<!--仓库根据权限增加审核按钮-->
<record id="view_warehouse_form_sf_inherit" model="ir.ui.view">
<field name="name">stock.warehouse.form.sf.inherit</field>
<field name="model">stock.warehouse</field>
<field name="inherit_id" ref="stock.view_warehouse"/>
<field name="arch" type="xml">
<xpath expr="//sheet" position="before">
<header>
<field name="check_state" invisible="1"/>
<button name="action_check" string="审核" type="object"
attrs="{'invisible': [('check_state','=', 'enable')]}"
groups="sf_warehouse.group_sf_stock_manager"
class="oe_highlight"/>
</header>
<!-- <record id="view_warehouse_form_sf_inherit" model="ir.ui.view">-->
<!-- <field name="name">stock.warehouse.form.sf.inherit</field>-->
<!-- <field name="model">stock.warehouse</field>-->
<!-- <field name="inherit_id" ref="stock.view_warehouse"/>-->
<!-- <field name="arch" type="xml">-->
<!-- <xpath expr="//sheet" position="before">-->
<!-- <header>-->
<!-- <field name="check_state" invisible="1"/>-->
<!-- <button name="action_check" string="审核" type="object"-->
<!-- attrs="{'invisible': [('check_state','=', 'enable')]}"-->
<!-- groups="sf_warehouse.group_sf_stock_manager"-->
<!-- class="oe_highlight"/>-->
<!-- </header>-->
</xpath>
</field>
</record>
<!-- </xpath>-->
<!-- </field>-->
<!-- </record>-->
<!-- <record id="view_warehouse_tree_sf_inherit" model="ir.ui.view">-->
<!-- <field name="name">stock.warehouse.tree.sf.inherit</field>-->
@@ -220,23 +220,23 @@
<!--路线根据权限增加审核按钮-->
<record id="view_route_form_sf_inherit" model="ir.ui.view">
<field name="name">stock.route.form.sf.inherit</field>
<field name="model">stock.route</field>
<field name="inherit_id" ref="stock.stock_location_route_form_view"/>
<field name="arch" type="xml">
<xpath expr="//sheet" position="before">
<header>
<field name="check_state" invisible="1"/>
<button name="action_check" string="审核" type="object"
attrs="{'invisible': [('check_state','=', 'enable')]}"
groups="sf_warehouse.group_sf_stock_manager"
class="oe_highlight"/>
</header>
<!-- <record id="view_route_form_sf_inherit" model="ir.ui.view">-->
<!-- <field name="name">stock.route.form.sf.inherit</field>-->
<!-- <field name="model">stock.route</field>-->
<!-- <field name="inherit_id" ref="stock.stock_location_route_form_view"/>-->
<!-- <field name="arch" type="xml">-->
<!-- <xpath expr="//sheet" position="before">-->
<!-- <header>-->
<!-- <field name="check_state" invisible="1"/>-->
<!-- <button name="action_check" string="审核" type="object"-->
<!-- attrs="{'invisible': [('check_state','=', 'enable')]}"-->
<!-- groups="sf_warehouse.group_sf_stock_manager"-->
<!-- class="oe_highlight"/>-->
<!-- </header>-->
</xpath>
</field>
</record>
<!-- </xpath>-->
<!-- </field>-->
<!-- </record>-->
<!-- <record id="view_route_tree_sf_inherit" model="ir.ui.view">-->
<!-- <field name="name">stock.route.tree.sf.inherit</field>-->
@@ -251,23 +251,23 @@
<!-- </record>-->
<!--规则根据权限增加审核按钮-->
<record id="view_rule_form_sf_inherit" model="ir.ui.view">
<field name="name">stock.rule.form.sf.inherit</field>
<field name="model">stock.rule</field>
<field name="inherit_id" ref="stock.view_stock_rule_form"/>
<field name="arch" type="xml">
<xpath expr="//sheet" position="before">
<header>
<field name="check_state" invisible="1"/>
<button name="action_check" string="审核" type="object"
attrs="{'invisible': [('check_state','=', 'enable')]}"
groups="sf_warehouse.group_sf_stock_manager"
class="oe_highlight"/>
</header>
<!-- <record id="view_rule_form_sf_inherit" model="ir.ui.view">-->
<!-- <field name="name">stock.rule.form.sf.inherit</field>-->
<!-- <field name="model">stock.rule</field>-->
<!-- <field name="inherit_id" ref="stock.view_stock_rule_form"/>-->
<!-- <field name="arch" type="xml">-->
<!-- <xpath expr="//sheet" position="before">-->
<!-- <header>-->
<!-- <field name="check_state" invisible="1"/>-->
<!-- <button name="action_check" string="审核" type="object"-->
<!-- attrs="{'invisible': [('check_state','=', 'enable')]}"-->
<!-- groups="sf_warehouse.group_sf_stock_manager"-->
<!-- class="oe_highlight"/>-->
<!-- </header>-->
</xpath>
</field>
</record>
<!-- </xpath>-->
<!-- </field>-->
<!-- </record>-->
<!-- <record id="view_rule_tree_sf_inherit" model="ir.ui.view">-->
<!-- <field name="name">stock.rule.tree.sf.inherit</field>-->
@@ -282,23 +282,23 @@
<!-- </record>-->
<!--作业类型根据权限增加审核按钮-->
<record id="view_picking_type_form_sf_inherit" model="ir.ui.view">
<field name="name">stock.picking.type.form.sf.inherit</field>
<field name="model">stock.picking.type</field>
<field name="inherit_id" ref="stock.view_picking_type_form"/>
<field name="arch" type="xml">
<xpath expr="//sheet" position="before">
<header>
<field name="check_state" invisible="1"/>
<button name="action_check" string="审核" type="object"
attrs="{'invisible': [('check_state','=', 'enable')]}"
groups="sf_warehouse.group_sf_stock_manager"
class="oe_highlight"/>
</header>
<!-- <record id="view_picking_type_form_sf_inherit" model="ir.ui.view">-->
<!-- <field name="name">stock.picking.type.form.sf.inherit</field>-->
<!-- <field name="model">stock.picking.type</field>-->
<!-- <field name="inherit_id" ref="stock.view_picking_type_form"/>-->
<!-- <field name="arch" type="xml">-->
<!-- <xpath expr="//sheet" position="before">-->
<!-- <header>-->
<!-- <field name="check_state" invisible="1"/>-->
<!-- <button name="action_check" string="审核" type="object"-->
<!-- attrs="{'invisible': [('check_state','=', 'enable')]}"-->
<!-- groups="sf_warehouse.group_sf_stock_manager"-->
<!-- class="oe_highlight"/>-->
<!-- </header>-->
</xpath>
</field>
</record>
<!-- </xpath>-->
<!-- </field>-->
<!-- </record>-->
<!-- <record id="view_picking_type_tree_sf_inherit" model="ir.ui.view">-->
<!-- <field name="name">stock.picking.type.tree.sf.inherit</field>-->