Merge branch refs/heads/develop into refs/heads/feature/修改机床参数bug
This commit is contained in:
@@ -19,3 +19,13 @@ class Common(models.Model):
|
||||
'TIMESTAMP': str(timestamp),
|
||||
'checkstr': check_sf_str}
|
||||
return headers
|
||||
|
||||
def get_add_time(self, parse_time):
|
||||
"""
|
||||
把时间增加8小时
|
||||
:return:
|
||||
"""
|
||||
dt = datetime.datetime.strptime(parse_time, "%Y-%m-%d %H:%M:%S")
|
||||
d = dt + datetime.timedelta(hours=8)
|
||||
nTime = d.strftime("%Y-%m-%d %H:%M:%S")
|
||||
return nTime
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import json
|
||||
import requests
|
||||
from odoo import fields, models, api
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.addons.sf_base.commons.common import Common
|
||||
|
||||
|
||||
class CuttingToolMaterial(models.Model):
|
||||
@@ -249,3 +253,37 @@ class ToolGroups(models.Model):
|
||||
name = fields.Char('名称')
|
||||
equipment_ids = fields.Many2many('maintenance.equipment', 'ref_maintenance_equipment', string='机台号')
|
||||
remark = fields.Char('备注', size=50)
|
||||
|
||||
# ==========机床刀具组接口==========
|
||||
def _register_tool_groups(self, obj):
|
||||
create_url = '/AutoDeviceApi/FeedBackOut'
|
||||
sf_sync_config = self.env['res.config.settings'].get_values()
|
||||
token = sf_sync_config['token']
|
||||
sf_secret_key = sf_sync_config['sf_secret_key']
|
||||
headers = Common.get_headers(obj, token, sf_secret_key)
|
||||
strurl = sf_sync_config['sf_url'] + create_url
|
||||
device_id = ''
|
||||
for equipment_id in obj.equipment_ids:
|
||||
device_id = '%s,%s' % (device_id, equipment_id.name)
|
||||
val = {
|
||||
'DeviceId': device_id,
|
||||
'GroupName': obj.name,
|
||||
}
|
||||
kw = json.dumps(val, ensure_ascii=False)
|
||||
r = requests.post(strurl, json={}, data={'kw': kw, 'token': token}, headers=headers)
|
||||
ret = r.json()
|
||||
if r == 200:
|
||||
return "机床刀具组发送成功"
|
||||
else:
|
||||
raise ValidationError("机床刀具组发送失败")
|
||||
|
||||
# def write(self, vals):
|
||||
# obj = super().write(vals)
|
||||
# self._register_tool_groups(obj)
|
||||
# return obj
|
||||
#
|
||||
# @api.model_create_multi
|
||||
# def create(self, vals_list):
|
||||
# records = super(ToolGroups, self).create(vals_list)
|
||||
# self._register_tool_groups(records)
|
||||
# return records
|
||||
|
||||
@@ -28,7 +28,7 @@ access_sf_sync_common,sf_sync_common,model_sf_sync_common,base.group_user,1,1,1,
|
||||
access_sf_international_standards,sf_international_standards,model_sf_international_standards,base.group_user,1,1,1,1
|
||||
access_material_apply,material_apply,model_material_apply,base.group_user,1,1,1,1
|
||||
access_sf_cutting_tool_standard_library,sf_cutting_tool_standard_library,model_sf_cutting_tool_standard_library,base.group_user,1,1,1,1
|
||||
access_sf_tool_groups,sf_tool_groups,model_sf_tool_groups,base.group_user,1,1,1,1
|
||||
|
||||
access_sf_tool_materials_basic_parameters,sf_tool_materials_basic_parameters,model_sf_tool_materials_basic_parameters,base.group_user,1,1,1,1
|
||||
access_sf_cutting_speed,sf_cutting_speed,model_sf_cutting_speed,base.group_user,1,1,1,1
|
||||
access_sf_feed_per_tooth,sf_feed_per_tooth,model_sf_feed_per_tooth,base.group_user,1,1,1,1
|
||||
@@ -77,6 +77,9 @@ access_purchase_order_line_group_purchase,access_purchase_order_line_group_purch
|
||||
access_purchase_order_line_group_purchase_director,access_purchase_order_line_group_purchase_director,purchase.model_purchase_order_line,sf_base.group_purchase_director,1,1,1,0
|
||||
access_spindle_taper_type,spindle_taper_type,model_spindle_taper_type,base.group_user,1,1,1,1
|
||||
|
||||
access_sf_tool_groups_group_plan_dispatch,sf_tool_groups,model_sf_tool_groups,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_sf_tool_groups_group_sf_tool_user,sf_tool_groups,model_sf_tool_groups,sf_base.group_sf_tool_user,1,1,1,1
|
||||
|
||||
|
||||
|
||||
access_purchase_order,purchase.order,purchase.model_purchase_order,sf_base.group_plan_dispatch,1,0,0,0
|
||||
|
||||
|
@@ -495,7 +495,7 @@
|
||||
<field name="name">刀具组</field>
|
||||
<field name="model">sf.tool.groups</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree create="1" edit="1" delete="1" editable="bottom">
|
||||
<tree editable="bottom">
|
||||
<field name="name"/>
|
||||
<field name="equipment_ids" widget="many2many_tags"/>
|
||||
<field name="remark"/>
|
||||
|
||||
@@ -33,6 +33,7 @@ class Sf_Bf_Connect(http.Controller):
|
||||
aa = request.env['sale.order'].sudo().search([('name', '=', order_id.name)])
|
||||
logging.info('get_bfm_process_or===================================:%s' % order_id.name)
|
||||
aa.default_code = kw['order_number']
|
||||
aa.logistics_way = kw['logistics_way']
|
||||
logging.info('get_bfm_process_order_listaaaaaaaaaaaaaaaaaaaaaaaaaaaa================:%s' % aa.default_code)
|
||||
for item in bfm_process_order_list:
|
||||
product = request.env['product.template'].sudo().product_create(product_id, item, order_id,
|
||||
|
||||
@@ -42,6 +42,25 @@ class JdEclp(models.Model):
|
||||
# bill_show = fields.Binary(string='物流面单展示', readonly=True, related='self.bill.datas')
|
||||
bill_show = fields.Binary(string='物流面单展示', readonly=True)
|
||||
check_out = fields.Char(string='查询是否为出库单', compute='_check_is_out')
|
||||
# 是否下了快递单
|
||||
is_bill = fields.Boolean(string='是否下了快递单', default=False)
|
||||
# 物流状态
|
||||
logistics_status = fields.Selection([('0', '未下单'), ('1', '已下单'), ('2', '已获取物流面单'), ('3', '已打印物流单')],
|
||||
string='物流状态', default='0', readonly=True)
|
||||
|
||||
logistics_way = fields.Selection([('自提', '自提'), ('到付', '到付'), ('在线支付', '在线支付')], string='物流方式', readonly=True)
|
||||
|
||||
def button_validate(self):
|
||||
"""
|
||||
重写出库方法,获取物流面单
|
||||
"""
|
||||
res = super(JdEclp, self).button_validate()
|
||||
if self.check_out == 'OUT':
|
||||
if self.logistics_way != '自提':
|
||||
if self.logistics_status != '3':
|
||||
raise ValidationError('非自提订单,必须先下物流单,并获取物流面单后才可出库!')
|
||||
return res
|
||||
|
||||
|
||||
@api.depends('name')
|
||||
def _check_is_out(self):
|
||||
@@ -68,6 +87,7 @@ class JdEclp(models.Model):
|
||||
# if self.receiverName and self.receiverMobile and self.receiverProvinceName and self.receiverCityName and
|
||||
# self.receiverCountyName and self.receiverTownName:
|
||||
sale_order_id = self.env['sale.order'].search([('name', '=', self.origin)])
|
||||
self.logistics_way = sale_order_id.logistics_way
|
||||
# stock_picking_type_id = self.enc['stock.picking.type'].search([('picking_type_id', '=', '')])
|
||||
# if sale_order_id.address_of_delivery != False:
|
||||
# if not sale_order_id:
|
||||
@@ -141,6 +161,8 @@ class JdEclp(models.Model):
|
||||
response = requests.post(url2, json=json2, data=None)
|
||||
# _logger.info('调用成功2', response.json()['result']['wbNo'])
|
||||
self.carrier_tracking_ref = response.json()['result']['wbNo']
|
||||
self.is_bill = True
|
||||
self.logistics_status = '1'
|
||||
|
||||
# else:
|
||||
# raise UserError("选择京东物流才能下单呦")
|
||||
@@ -180,3 +202,4 @@ class JdEclp(models.Model):
|
||||
# 'model_name': 'stock.picking',
|
||||
})
|
||||
_logger.info(attachment)
|
||||
self.logistics_status = '2'
|
||||
|
||||
@@ -12,16 +12,30 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- <record id="sf_bf_connect_vpicktree" model="ir.ui.view"> -->
|
||||
<!-- <field name="name">sf.bf.connect.vpicktree</field> -->
|
||||
<!-- <field name="model">stock.picking</field> -->
|
||||
<!-- <field name="inherit_id" ref="stock.vpicktree"/> -->
|
||||
<!-- <field name="arch" type="xml"> -->
|
||||
<!-- <field name="state" position="after"> -->
|
||||
<!-- <field name="logistics_status" string="物流状态"/> -->
|
||||
<!-- </field> -->
|
||||
<!-- </field> -->
|
||||
<!-- </record> -->
|
||||
|
||||
<record id="custom_view_picking_form" model="ir.ui.view">
|
||||
<field name="name">物流</field>
|
||||
<field name="model">stock.picking</field>
|
||||
<field name="inherit_id" ref="stock.view_picking_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//form//header//button[@name='action_assign']" position="after">
|
||||
<field name="is_bill" invisible="True"/>
|
||||
<field name="logistics_status" invisible="True"/>
|
||||
<field name="logistics_way" invisible="True"/>
|
||||
<button string="京东物流下单" name="create_order" type="object" confirm="是否确认物流下单" class="btn-primary"
|
||||
attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
attrs="{'invisible': ['|', '|', '|', ('check_out', '!=', 'OUT'), ('state', '!=', 'assigned'), ('is_bill', '=', True), ('logistics_way', '=', '自提')]}"/>
|
||||
<button string="获取物流面单" name="get_bill" type="object" confirm="是否获取物流面单" class="btn-primary"
|
||||
attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
attrs="{'invisible': ['|', '|', '|', '|', ('check_out', '!=', 'OUT'), ('state', '!=', 'assigned'), ('logistics_status', '=', '2'), ('is_bill', '=', False), ('logistics_way', '=', '自提')]}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
@@ -31,6 +45,12 @@
|
||||
<field name="model">stock.picking</field>
|
||||
<field name="inherit_id" ref="delivery.view_picking_withcarrier_out_form"/>
|
||||
<field name="arch" type="xml">
|
||||
|
||||
<field name="location_id" position="after">
|
||||
<field name="logistics_status" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="logistics_way" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
</field>
|
||||
|
||||
<xpath expr="//group//field[@name='carrier_id']" position="after">
|
||||
<!-- <field name="senderNickName" domain="[('self.name', 'like', '%OUT%')]"/> -->
|
||||
<field name="senderNickName" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
@@ -48,6 +68,7 @@
|
||||
<field name="grossVolume" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="pickupBeginTime" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="bill_show" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
<field name="logistics_status"/>
|
||||
</xpath>
|
||||
<xpath expr="//group//field[@name='group_id']" position="after">
|
||||
<field name="bill_show" widget="pdf_viewer" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<field name="sequence_number"/>
|
||||
<field name="program_name"/>
|
||||
<field name="cnc_id" string="文件"/>
|
||||
<field name="functional_tool_type_id"/>
|
||||
<field name="cutting_tool_name"/>
|
||||
<field name="cutting_tool_no"/>
|
||||
<field name="processing_type"/>
|
||||
|
||||
@@ -21,7 +21,8 @@ access_maintenance_equipment_agv_log,maintenance_equipment_agv_log,model_mainten
|
||||
access_maintenance_equipment_agv_log,maintenance_equipment_agv_log,model_maintenance_equipment_agv_log,base.group_user,1,1,1,1
|
||||
|
||||
|
||||
access_maintenance_request_group_plan_dispatch,maintenance.request,maintenance.model_maintenance_request,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_maintenance_system_user,equipment.request system user,maintenance.model_maintenance_request,base.group_user,1,0,0,0
|
||||
|
||||
access_maintenance_equipment_group_plan_dispatch,maintenance.equipment,maintenance.model_maintenance_equipment,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_sf_maintenance_logs_group_plan_dispatch,sf_maintenance_logs,model_sf_maintenance_logs,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_maintenance_standard_image_group_plan_dispatch,maintenance_standard_image,model_maintenance_standard_image,sf_base.group_plan_dispatch,1,0,0,0
|
||||
|
||||
|
@@ -11,5 +11,18 @@
|
||||
<field name="perm_create">False</field>
|
||||
<field name="perm_unlink">False</field>
|
||||
</record>
|
||||
|
||||
<!-- 对维保计划做“最小权限”控制,计划调度岗只能看到所有的维保计划,不能修改,不能删除,不能创建 -->
|
||||
<record id="maintenance_request_rule_plan_dispatch" model="ir.rule">
|
||||
<field name="name">Maintenance Request Plan Dispatch Rule</field>
|
||||
<field name="model_id" ref="maintenance.model_maintenance_request"/>
|
||||
<field name="groups" eval="[(4, ref('sf_base.group_plan_dispatch'))]"/>
|
||||
<!-- <field name="domain_force">['|',('user_id','=',user.id),('user_id','=',False)]</field> -->
|
||||
<field name="perm_read">True</field>
|
||||
<field name="perm_write">False</field>
|
||||
<field name="perm_create">False</field>
|
||||
<field name="perm_unlink">False</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import logging
|
||||
import json
|
||||
import base64
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
|
||||
@@ -21,9 +20,9 @@ class Manufacturing_Connect(http.Controller):
|
||||
res = {'Succeed': True, 'Datas': []}
|
||||
datas = request.httprequest.data
|
||||
ret = json.loads(datas)
|
||||
ret = json.loads(ret['result'])
|
||||
logging.info('RfidCode:%s' % ret)
|
||||
workorder = request.env['mrp.workorder'].sudo().search([('name', '=', ret['RfidCode'])])
|
||||
workorder = request.env['mrp.workorder'].sudo().search(
|
||||
[('production_id.name', '=', 'WH/MO/00071'), ('routing_type', '=', '装夹')])
|
||||
if workorder:
|
||||
for item in workorder:
|
||||
res['Datas'].append({
|
||||
@@ -33,14 +32,88 @@ class Manufacturing_Connect(http.Controller):
|
||||
'Quantity': 1,
|
||||
'MaterialId': item.product_id.default_code,
|
||||
'MaterialName': item.product_id.name,
|
||||
# 'Spec':item.mat,
|
||||
'Material': item.materials_type_id.name
|
||||
'Spec': '%s×%s×%s' % (item.move_raw_ids.materiel_length, item.move_raw_ids.materiel_width,
|
||||
item.move_raw_ids.materiel_height),
|
||||
'Material': item.product_id.materials_type_id.name
|
||||
})
|
||||
except Exception as e:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
|
||||
logging.info('get_Work_Info error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
|
||||
@http.route('/AutoDeviceApi/GetShiftPlan', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def get_ShiftPlan(self, **kw):
|
||||
"""
|
||||
自动化每天获取机台日计划
|
||||
:param kw:
|
||||
:return:
|
||||
"""
|
||||
logging.info('get_ShiftPlan:%s' % kw)
|
||||
try:
|
||||
res = {'Succeed': True, 'Datas': []}
|
||||
datas = request.httprequest.data
|
||||
ret = json.loads(datas)
|
||||
ret = json.loads(ret['result'])
|
||||
logging.info('RfidCode:%s' % ret)
|
||||
workorder = request.env['mrp.workorder'].sudo().search([('name', '=', ret['ProductionLine'])])
|
||||
if workorder:
|
||||
for item in workorder:
|
||||
date_planned_start = ''
|
||||
date_planned_finished = ''
|
||||
if item.date_planned_start is not False:
|
||||
planned_start = item.date_planned_start.strftime("%Y-%m-%d %H:%M:%S")
|
||||
date_planned_start = request.env['sf.sync.common'].sudo().get_add_time(planned_start)
|
||||
if item.date_planned_finished is not False:
|
||||
planned_finished = item.date_planned_finished.strftime("%Y-%m-%d %H:%M:%S")
|
||||
date_planned_finished = request.env['sf.sync.common'].sudo().get_add_time(planned_finished)
|
||||
res['Datas'].append({
|
||||
'BillId': item.production_id.name,
|
||||
'RfidCode': item.RfidCode,
|
||||
'CraftName': item.name,
|
||||
'Quantity': 1,
|
||||
'WortkStart': date_planned_start,
|
||||
'WorkEnd': date_planned_finished,
|
||||
'MaterialId': item.product_id.default_code,
|
||||
'MaterialName': item.product_id.name,
|
||||
# 'Spec':item.mat,
|
||||
'Material': item.materials_type_id.name
|
||||
})
|
||||
except Exception as e:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
|
||||
logging.info('get_ShiftPlan error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
|
||||
@http.route('/AutoDeviceApi/QcCheck', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def get_qcCheck(self, **kw):
|
||||
"""
|
||||
工件预调(前置三元检测)
|
||||
1、前置三元检测在产线外:三元检测设备把测量信息上传给MES,
|
||||
MES生成检测定位数据。中控系统传递RFID编号给MES获取测量偏置结果。(来源为三元检测工单上的字段)
|
||||
:param kw:
|
||||
:return:
|
||||
"""
|
||||
logging.info('get_qcCheck:%s' % kw)
|
||||
try:
|
||||
res = {'Succeed': True, 'Datas': []}
|
||||
datas = request.httprequest.data
|
||||
ret = json.loads(datas)
|
||||
ret = json.loads(ret['result'])
|
||||
logging.info('RfidCode:%s' % ret)
|
||||
workorder = request.env['mrp.workorder'].sudo().search([('routing_type', '=', '前置三元定位检测')])
|
||||
if workorder:
|
||||
for item in workorder:
|
||||
res['Datas'].append({
|
||||
'XOffset': item.production_id.name,
|
||||
'YOffset': item.RfidCode,
|
||||
'ZOffet': item.name,
|
||||
'COffset': 1
|
||||
})
|
||||
except Exception as e:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
|
||||
logging.info('get_qcCheck error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
|
||||
@http.route('/AutoDeviceApi/FeedBackStart', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
@@ -50,7 +123,7 @@ class Manufacturing_Connect(http.Controller):
|
||||
:param kw:
|
||||
:return:
|
||||
"""
|
||||
logging.info('get_Work_Info:%s' % kw)
|
||||
logging.info('button_Work_START:%s' % kw)
|
||||
try:
|
||||
res = {'Succeed': True, 'Datas': []}
|
||||
datas = request.httprequest.data
|
||||
@@ -69,11 +142,9 @@ class Manufacturing_Connect(http.Controller):
|
||||
workorder = request.env['mrp.workorder'].sudo().search(
|
||||
[('production_id', '=', production_id), ('routing_type', '=', routing_type)], limit=1)
|
||||
workorder.button_start()
|
||||
|
||||
|
||||
except Exception as e:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
|
||||
logging.info('get_Work_Info error:%s' % e)
|
||||
logging.info('button_Work_START error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
|
||||
@http.route('/AutoDeviceApi/FeedBackEnd', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||
@@ -84,7 +155,7 @@ class Manufacturing_Connect(http.Controller):
|
||||
:param kw:
|
||||
:return:
|
||||
"""
|
||||
logging.info('get_Work_Info:%s' % kw)
|
||||
logging.info('button_Work_End:%s' % kw)
|
||||
try:
|
||||
res = {'Succeed': True, 'Datas': []}
|
||||
datas = request.httprequest.data
|
||||
@@ -103,14 +174,11 @@ class Manufacturing_Connect(http.Controller):
|
||||
workorder = request.env['mrp.workorder'].sudo().search(
|
||||
[('production_id', '=', production_id), ('routing_type', '=', routing_type)], limit=1)
|
||||
workorder.button_finish()
|
||||
|
||||
|
||||
except Exception as e:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
|
||||
logging.info('get_Work_Info error:%s' % e)
|
||||
logging.info('button_Work_End error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
|
||||
|
||||
@http.route('/AutoDeviceApi/QcCheck', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def Workorder_QcCheck(self, **kw):
|
||||
@@ -119,7 +187,7 @@ class Manufacturing_Connect(http.Controller):
|
||||
:param kw:
|
||||
:return:
|
||||
"""
|
||||
logging.info('get_Work_Info:%s' % kw)
|
||||
logging.info('Workorder_QcCheck:%s' % kw)
|
||||
try:
|
||||
res = {'Succeed': True, 'Datas': []}
|
||||
datas = request.httprequest.data
|
||||
@@ -143,8 +211,7 @@ class Manufacturing_Connect(http.Controller):
|
||||
routing_type = ret['CraftId']
|
||||
request.env['mrp.workorder'].sudo().search(
|
||||
[('production_id', '=', production_id), ('routing_type', '=', routing_type)], limit=1)
|
||||
|
||||
except Exception as e:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
|
||||
logging.info('get_Work_Info error:%s' % e)
|
||||
logging.info('Workorder_QcCheck error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
@@ -597,6 +597,7 @@ class CNCprocessing(models.Model):
|
||||
cnc_id = fields.Many2one('ir.attachment')
|
||||
sequence_number = fields.Char('序号')
|
||||
program_name = fields.Char('程序名')
|
||||
functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型')
|
||||
cutting_tool_name = fields.Char('刀具名称')
|
||||
cutting_tool_no = fields.Char('刀号')
|
||||
processing_type = fields.Char('加工类型')
|
||||
@@ -771,3 +772,34 @@ class SfWorkOrderBarcodes(models.Model):
|
||||
#
|
||||
# else:
|
||||
# self.pro_code_ok = workorder.pro_code_is_ok(barcode)
|
||||
|
||||
|
||||
class WorkpieceDelivery(models.Model):
|
||||
_name = 'sf.workpiece.delivery'
|
||||
_description = '工件配送单列表'
|
||||
|
||||
name = fields.Char('工件编码/任务编码')
|
||||
mrp_workorder_id = fields.Many2one('mrp.workorder', string='工件编码/任务编码',
|
||||
domain=[('name', 'in', ('装夹', '解除装夹'))])
|
||||
workpiece_code = fields.Char('同运工件编码')
|
||||
feeder_station_start = fields.Char('起点接驳站')
|
||||
feeder_station_destination = fields.Char('目的接驳站')
|
||||
production_line_id = fields.Many2one('sf.production.line', string='目标生产线')
|
||||
task_delivery_time = fields.Datetime('任务下发时间')
|
||||
task_completion_time = fields.Datetime('任务完成时间')
|
||||
delivery_time = fields.Char('配送时长', compute='_compute_delivery_time')
|
||||
status = fields.Selection([('待下发', '待下发'), ('待配送', '待配送'), ('已配送', '已配送')], string='状态',
|
||||
default='待下发')
|
||||
|
||||
@api.depends('task_delivery_time', 'task_completion_time')
|
||||
def _compute_delivery_time(self):
|
||||
for obj in self:
|
||||
if obj.task_delivery_time and obj.task_completion_time:
|
||||
delivery_duration = obj.task_completion_time - obj.task_delivery_time
|
||||
hours, seconds = divmod(delivery_duration.total_seconds(), 3600)
|
||||
minutes, _ = divmod(seconds, 60)
|
||||
delivery_time_str = "{:.0f}时 {:.0f}分".format(hours, minutes)
|
||||
|
||||
obj.delivery_time = delivery_time_str
|
||||
else:
|
||||
obj.delivery_time = ''
|
||||
|
||||
@@ -870,6 +870,11 @@ class SfMaintenanceEquipmentTool(models.Model):
|
||||
_description = '机床刀位'
|
||||
|
||||
equipment_id = fields.Many2one('maintenance.equipment', string='设备')
|
||||
|
||||
code = fields.Char('机床刀位号')
|
||||
name = fields.Char('刀位号', compute='_compute_name')
|
||||
|
||||
# 待删除字段
|
||||
product_template_id = fields.Many2one('product.template', string='功能刀具名称',
|
||||
domain="[('categ_type', '=', '刀具')]")
|
||||
image_1920 = fields.Binary('图片', related='product_template_id.image_1920')
|
||||
@@ -882,9 +887,6 @@ class SfMaintenanceEquipmentTool(models.Model):
|
||||
life_value_max = fields.Char('最大寿命值')
|
||||
alarm_value = fields.Char('报警值')
|
||||
used_value = fields.Char('已使用值')
|
||||
code = fields.Char('机床刀位号')
|
||||
|
||||
name = fields.Char('', compute='_compute_name')
|
||||
|
||||
@api.depends('code')
|
||||
def _compute_name(self):
|
||||
|
||||
@@ -23,6 +23,9 @@ access_mrp_workcenter_manager,mrp_workcenter,model_mrp_workcenter,sf_base.group_
|
||||
access_mrp_workcenter_productivity,mrp_workcenter_productivity,model_mrp_workcenter_productivity,sf_base.group_sf_mrp_user,1,0,0,0
|
||||
access_mrp_workcenter_productivity_manager,mrp_workcenter_productivity,model_mrp_workcenter_productivity,sf_base.group_sf_mrp_manager,1,1,1,0
|
||||
|
||||
access_sf_workpiece_delivery,sf_workpiece_delivery,model_sf_workpiece_delivery,sf_base.group_sf_mrp_user,1,0,0,0
|
||||
access_sf_workpiece_delivery_manager,sf_workpiece_delivery,model_sf_workpiece_delivery,sf_base.group_sf_mrp_manager,1,1,1,0
|
||||
|
||||
access_mrp_workcenter_productivity_loss_manager,mrp.workcenter.productivity.loss,mrp.model_mrp_workcenter_productivity_loss,sf_base.group_sf_mrp_user,1,1,1,0
|
||||
access_mrp_workcenter_productivity_loss,mrp.workcenter.productivity.loss,mrp.model_mrp_workcenter_productivity_loss,sf_base.group_sf_mrp_user,1,0,0,0
|
||||
access_mrp_workcenter_productivity_loss_type,mrp.workcenter.productivity.loss.type,mrp.model_mrp_workcenter_productivity_loss_type,sf_base.group_sf_mrp_user,1,0,0,0
|
||||
@@ -87,6 +90,7 @@ access_mrp_production_split,access.mrp.production.split,mrp.model_mrp_production
|
||||
access_mrp_production_split_line,access.mrp.production.split.line,mrp.model_mrp_production_split_line,sf_base.group_sf_mrp_user,1,1,1,0
|
||||
access_mrp_workcenter_capacity_manager,mrp.workcenter.capacity.manager,mrp.model_mrp_workcenter_capacity,sf_base.group_sf_mrp_user,1,1,1,0
|
||||
|
||||
|
||||
access_mrp_production_group_plan_dispatch,mrp_production,model_mrp_production,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_mrp_workorder,mrp_workorder,model_mrp_workorder,sf_base.group_plan_dispatch,1,1,1,0
|
||||
access_sf_production_line_group_plan_dispatch,sf.production.line,model_sf_production_line,sf_base.group_plan_dispatch,1,0,0,0
|
||||
|
||||
|
@@ -76,7 +76,7 @@
|
||||
confirm="There are no components to consume. Are you still sure you want to continue?" data-hotkey="g" groups="sf_base.group_sf_mrp_user"/>
|
||||
</xpath>
|
||||
<xpath expr="(//header//button[@name='button_mark_done'])[2]" position="replace">
|
||||
<button name="button_mark_done" attrs="{'invisible': ['|', '|', ('state', 'in', ('draft', 'cancel', 'done', 'to_close')), ('qty_producing', '=', 0), ('move_raw_ids', '=', [])]}" string="Validate" type="object" class="oe_highlight" data-hotkey="g" groups="sf_base.group_sf_mrp_user"/>
|
||||
<button name="button_mark_done" attrs="{'invisible': ['|', '|', ('state', 'in', ('draft', 'cancel', 'done', 'to_close')), ('qty_producing', '=', 0), ('move_raw_ids', '=', [])]}" string="验证" type="object" class="oe_highlight" data-hotkey="g" groups="sf_base.group_sf_mrp_user"/>
|
||||
</xpath>
|
||||
<xpath expr="(//header//button[@name='button_mark_done'])[3]" position="replace">
|
||||
<button name="button_mark_done" attrs="{'invisible': [
|
||||
@@ -86,7 +86,7 @@
|
||||
'|',
|
||||
('state', 'not in', ('confirmed', 'progress')),
|
||||
('qty_producing', '!=', 0),
|
||||
('state', '!=', 'to_close')]}" string="Mark as Done" type="object" class="oe_highlight" data-hotkey="g" groups="sf_base.group_sf_mrp_user"/>
|
||||
('state', '!=', 'to_close')]}" string="标记完成" type="object" class="oe_highlight" data-hotkey="g" groups="sf_base.group_sf_mrp_user"/>
|
||||
</xpath>
|
||||
<xpath expr="(//header//button[@name='button_mark_done'])[4]" position="replace">
|
||||
<button name="button_mark_done" attrs="{'invisible': [
|
||||
@@ -96,7 +96,7 @@
|
||||
'|',
|
||||
('state', 'not in', ('confirmed', 'progress')),
|
||||
('qty_producing', '!=', 0),
|
||||
('state', '!=', 'to_close')]}" string="Mark as Done" type="object" class="oe_highlight" data-hotkey="g"
|
||||
('state', '!=', 'to_close')]}" string="标记完成" type="object" class="oe_highlight" data-hotkey="g"
|
||||
confirm="There are no components to consume. Are you still sure you want to continue?" groups="sf_base.group_sf_mrp_user"/>
|
||||
</xpath>
|
||||
<xpath expr="//header//button[@name='button_unplan']" position="replace">
|
||||
@@ -108,41 +108,41 @@
|
||||
|
||||
|
||||
<xpath expr="//header//button[@name='action_confirm']" position="replace">
|
||||
<button name="action_confirm" attrs="{'invisible': [('state', '!=', 'draft')]}" string="Confirm" type="object" class="oe_highlight" data-hotkey="v" groups="sf_base.group_sf_mrp_user"/>
|
||||
<button name="action_confirm" attrs="{'invisible': [('state', '!=', 'draft')]}" string="确认" type="object" class="oe_highlight" data-hotkey="v" groups="sf_base.group_sf_mrp_user"/>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//header//button[@name='button_plan']" position="replace">
|
||||
<button name="button_plan" attrs="{'invisible': ['|', '|', ('state', 'not in', ('confirmed', 'progress', 'to_close')), ('workorder_ids', '=', []), ('is_planned', '=', True)]}" type="object" string="Plan" class="oe_highlight" data-hotkey="x" groups="sf_base.group_sf_mrp_user"/>
|
||||
<!-- <button name="button_plan" attrs="{'invisible': ['|', '|', ('state', 'not in', ('confirmed', 'progress', 'to_close')), ('workorder_ids', '=', []), ('is_planned', '=', True)]}" type="object" string="Plan" class="oe_highlight" data-hotkey="x" groups="sf_base.group_sf_mrp_user"/> -->
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//header//button[@name='action_assign']" position="replace">
|
||||
<button name="action_assign" attrs="{'invisible': ['|', ('state', 'in', ('draft', 'done', 'cancel')), ('reserve_visible', '=', False)]}" string="Check availability" type="object" data-hotkey="q" groups="sf_base.group_sf_mrp_user"/>
|
||||
<button name="action_assign" attrs="{'invisible': ['|', ('state', 'in', ('draft', 'done', 'cancel')), ('reserve_visible', '=', False)]}" string="检查可用量" type="object" data-hotkey="q" groups="sf_base.group_sf_mrp_user"/>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//header//button[@name='do_unreserve']" position="replace">
|
||||
<button name="do_unreserve" type="object" string="Unreserve" attrs="{'invisible': [('unreserve_visible', '=', False)]}" data-hotkey="w" groups="sf_base.group_sf_mrp_user"/>
|
||||
<button name="do_unreserve" type="object" string="取消保留" attrs="{'invisible': [('unreserve_visible', '=', False)]}" data-hotkey="w" groups="sf_base.group_sf_mrp_user"/>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//header//button[@name='action_toggle_is_locked']" position="replace">
|
||||
<button name="action_toggle_is_locked" attrs="{'invisible': ['|', ('show_lock', '=', False), ('is_locked', '=', False)]}" string="Unlock" groups="sf_base.group_sf_mrp_user" type="object" help="Unlock the manufacturing order to adjust what has been consumed or produced." data-hotkey="l"/>
|
||||
<button name="action_toggle_is_locked" attrs="{'invisible': ['|', ('show_lock', '=', False), ('is_locked', '=', False)]}" string="取消阻塞" groups="sf_base.group_sf_mrp_user" type="object" help="Unlock the manufacturing order to adjust what has been consumed or produced." data-hotkey="l"/>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//header//button[@name='action_toggle_is_locked']" position="replace">
|
||||
<button name="action_toggle_is_locked" attrs="{'invisible': ['|', ('show_lock', '=', False), ('is_locked', '=', True)]}" string="Lock" groups="sf_base.group_sf_mrp_user" type="object" help="Lock the manufacturing order to prevent changes to what has been consumed or produced." data-hotkey="l"/>
|
||||
<button name="action_toggle_is_locked" attrs="{'invisible': ['|', ('show_lock', '=', False), ('is_locked', '=', True)]}" string="阻塞" groups="sf_base.group_sf_mrp_user" type="object" help="Lock the manufacturing order to prevent changes to what has been consumed or produced." data-hotkey="l"/>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//header//button[@name='action_serial_mass_produce_wizard']" position="replace">
|
||||
<button name="action_serial_mass_produce_wizard" attrs="{'invisible': [('show_serial_mass_produce', '=', False)]}" string="Mass Produce" type="object" groups="sf_base.group_sf_mrp_user"/>
|
||||
<button name="action_serial_mass_produce_wizard" attrs="{'invisible': [('show_serial_mass_produce', '=', False)]}" string="批量生产" type="object" groups="sf_base.group_sf_mrp_user"/>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//header//button[@name='action_cancel']" position="replace">
|
||||
<button name="action_cancel" type="object" string="Cancel" data-hotkey="z"
|
||||
<button name="action_cancel" type="object" string="取消" data-hotkey="z"
|
||||
attrs="{'invisible': ['|', '|', ('id', '=', False), ('state', 'in', ('done', 'cancel')), ('confirm_cancel', '=', False)]}"
|
||||
confirm="Some product moves have already been confirmed, this manufacturing order can't be completely cancelled. Are you still sure you want to process ?" groups="sf_base.group_sf_mrp_user"/>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//header//button[@name='button_unbuild']" position="replace">
|
||||
<button name="button_unbuild" type="object" string="Unbuild" attrs="{'invisible': [('state', '!=', 'done')]}" data-hotkey="shift+v" groups="sf_base.group_sf_mrp_user"/>
|
||||
<button name="button_unbuild" type="object" string="拆单" attrs="{'invisible': [('state', '!=', 'done')]}" data-hotkey="shift+v" groups="sf_base.group_sf_mrp_user"/>
|
||||
</xpath>
|
||||
|
||||
|
||||
@@ -157,28 +157,28 @@
|
||||
<field name="inherit_id" ref="mrp.mrp_production_workorder_tree_editable_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//tree//button[@name='button_start']" position="replace">
|
||||
<button name="button_start" type="object" string="Start" class="btn-success"
|
||||
<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)]}" groups="sf_base.group_sf_mrp_user"/>
|
||||
</xpath>
|
||||
<xpath expr="//tree//button[@name='button_pending']" position="replace">
|
||||
<button name="button_pending" type="object" string="Pause" class="btn-warning"
|
||||
<button name="button_pending" type="object" string="暂停" class="btn-warning"
|
||||
attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('is_user_working', '=', False)]}" groups="sf_base.group_sf_mrp_user"/>
|
||||
</xpath>
|
||||
<xpath expr="//tree//button[@name='button_finish']" position="replace">
|
||||
<button name="button_finish" type="object" string="Done" class="btn-success"
|
||||
<button name="button_finish" type="object" string="完成" class="btn-success"
|
||||
attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('is_user_working', '=', False)]}" groups="sf_base.group_sf_mrp_user"/>
|
||||
</xpath>
|
||||
<xpath expr="//tree//button[@name='%(mrp.act_mrp_block_workcenter_wo)d']" position="replace">
|
||||
<button name="%(mrp.act_mrp_block_workcenter_wo)d" type="action" string="Block" context="{'default_workcenter_id': workcenter_id}" class="btn-danger"
|
||||
<button name="%(mrp.act_mrp_block_workcenter_wo)d" type="action" string="阻塞" context="{'default_workcenter_id': workcenter_id}" class="btn-danger"
|
||||
attrs="{'invisible': ['|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked')]}" groups="sf_base.group_sf_mrp_user"/>
|
||||
</xpath>
|
||||
<xpath expr="//tree//button[@name='button_unblock']" position="replace">
|
||||
<button name="button_unblock" type="object" string="Unblock" context="{'default_workcenter_id': workcenter_id}" class="btn-danger"
|
||||
<button name="button_unblock" type="object" string="取消阻塞" context="{'default_workcenter_id': workcenter_id}" class="btn-danger"
|
||||
attrs="{'invisible': ['|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '!=', 'blocked')]}" groups="sf_base.group_sf_mrp_user"/>
|
||||
</xpath>
|
||||
<xpath expr="//tree//button[@name='action_open_wizard']" position="replace">
|
||||
<button name="action_open_wizard" type="object" icon="fa-external-link" class="oe_edit_only"
|
||||
title="Open Work Order"
|
||||
title="未完成工单"
|
||||
context="{'default_workcenter_id': workcenter_id}" groups="sf_base.group_sf_mrp_user"/>
|
||||
</xpath>
|
||||
|
||||
|
||||
@@ -107,16 +107,21 @@
|
||||
<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),('name','=','获取CNC加工程序')]}"/>
|
||||
('is_user_working', '!=', False),('user_permissions','=',False),('name','=','获取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),('name','=','获取CNC加工程序')]}"/>
|
||||
<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)]}"/>
|
||||
<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"
|
||||
attrs="{'invisible': ['|', '|','|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'),('user_permissions','=',False),('name','=','获取CNC加工程序')]}"/>
|
||||
<button name="button_unblock" type="object" string="Unblock"
|
||||
context="{'default_workcenter_id': workcenter_id}" class="btn-danger"
|
||||
groups="sf_base.group_sf_mrp_user"
|
||||
attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '!=', 'blocked'),('name','=','获取CNC加工程序')]}"/>
|
||||
</xpath>
|
||||
<xpath expr="//page[1]" position="before">
|
||||
@@ -398,7 +403,6 @@
|
||||
</xpath>
|
||||
|
||||
|
||||
|
||||
<xpath expr="//page[1]" position="before">
|
||||
<field name="results" invisible="1"/>
|
||||
<page string="后置三元检测" attrs='{"invisible": [("routing_type","!=","CNC加工")]}'>
|
||||
@@ -488,5 +492,53 @@
|
||||
<record id="mrp.menu_mrp_workorder_todo" model="ir.ui.menu">
|
||||
<field name="active" eval="False"/>
|
||||
</record>
|
||||
|
||||
|
||||
<!--=========================================工件配送单列表======================================-->
|
||||
<record id="sf_workpiece_delivery_tree" model="ir.ui.view">
|
||||
<field name="name">工件配送单列表</field>
|
||||
<field name="model">sf.workpiece.delivery</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="工件配送单列表" editable="bottom">
|
||||
<field name="mrp_workorder_id"/>
|
||||
<field name="workpiece_code"/>
|
||||
<field name="feeder_station_start"/>
|
||||
<field name="production_line_id"/>
|
||||
<field name="task_delivery_time"/>
|
||||
<field name="feeder_station_destination"/>
|
||||
<field name="task_completion_time"/>
|
||||
<field name="delivery_time"/>
|
||||
<field name="status"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="sf_workpiece_delivery_search" model="ir.ui.view">
|
||||
<field name="name">工件配送单列表</field>
|
||||
<field name="model">sf.workpiece.delivery</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="工件配送单列表">
|
||||
<field name="mrp_workorder_id"/>
|
||||
<field name="workpiece_code"/>
|
||||
<field name="feeder_station_start"/>
|
||||
<field name="production_line_id"/>
|
||||
<field name="task_delivery_time"/>
|
||||
<field name="feeder_station_destination"/>
|
||||
<field name="task_completion_time"/>
|
||||
<field name="delivery_time"/>
|
||||
<field name="status"/>
|
||||
<searchpanel>
|
||||
<field name="production_line_id" icon="fa-building" enable_counters="1"/>
|
||||
<field name="status" icon="fa-building" enable_counters="1"/>
|
||||
</searchpanel>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="sf_workpiece_delivery_act" model="ir.actions.act_window">
|
||||
<field name="name">工件配送单列表</field>
|
||||
<field name="res_model">sf.workpiece.delivery</field>
|
||||
<field name="view_mode">tree,search</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
|
||||
<!-- 设备增加刀具库位table-->
|
||||
设备增加刀具库位table
|
||||
<record id="sf_manufacturing_hr_equipment_view_form" model="ir.ui.view">
|
||||
<field name="name">sf_manufacturing_equipment.form</field>
|
||||
<field name="model">maintenance.equipment</field>
|
||||
@@ -13,17 +13,6 @@
|
||||
<field name = 'product_template_ids' >
|
||||
<tree editable='bottom'>
|
||||
<field name="code"/>
|
||||
<field name="product_template_id"/>
|
||||
<field name="image_1920" widget="image"/>
|
||||
<field name="categ_type"/>
|
||||
<field name="diameter"/>
|
||||
<field name="precision"/>
|
||||
<field name="tool_code"/>
|
||||
<field name="hilt_name"/>
|
||||
<field name="hilt_code"/>
|
||||
<field name="life_value_max"/>
|
||||
<field name="alarm_value"/>
|
||||
<field name="used_value"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
|
||||
@@ -194,7 +194,8 @@ class sf_production_plan(models.Model):
|
||||
record.date_planned_start, record.date_planned_finished = \
|
||||
item.date_planned_start, item.date_planned_finished
|
||||
record.state = 'done'
|
||||
record.production_id.schedule_state = '已排'
|
||||
# record.production_id.schedule_state = '已排'
|
||||
record.sudo().production_id.schedule_state = '已排'
|
||||
# self.env['sale.order'].browse(record.production_id.origin).schedule_status = 'to process'
|
||||
sale_obj = self.env['sale.order'].search([('name', '=', record.origin)])
|
||||
if 'S' in sale_obj.name:
|
||||
@@ -202,7 +203,7 @@ class sf_production_plan(models.Model):
|
||||
mrp_production_ids = record.production_id._get_children().ids
|
||||
print('mrp_production_ids', mrp_production_ids)
|
||||
for i in mrp_production_ids:
|
||||
record.env['mrp.production'].browse(i).schedule_state = '已排'
|
||||
record.env['mrp.production'].sudo().browse(i).schedule_state = '已排'
|
||||
# record.production_id.date_planned_start = record.date_planned_start
|
||||
# record.production_id.date_planned_finished = record.date_planned_finished
|
||||
else:
|
||||
|
||||
@@ -327,6 +327,14 @@
|
||||
action="mrp_custom_action"
|
||||
parent="sf_production_plan_menu"
|
||||
/>
|
||||
|
||||
<menuitem
|
||||
id="sf_workpiece_delivery_menu"
|
||||
name="工件配送单列表"
|
||||
sequence="10"
|
||||
action="sf_manufacturing.sf_workpiece_delivery_act"
|
||||
parent="mrp.menu_mrp_manufacturing"
|
||||
/>
|
||||
<!-- <menuitem -->
|
||||
<!-- id="sale_custom_menu" -->
|
||||
<!-- name="报价单" -->
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import custom_quality
|
||||
from . import quality
|
||||
|
||||
34
sf_quality/models/quality.py
Normal file
34
sf_quality/models/quality.py
Normal file
@@ -0,0 +1,34 @@
|
||||
import json
|
||||
import requests
|
||||
from odoo import fields, models, api
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.addons.sf_base.commons.common import Common
|
||||
|
||||
|
||||
class QualityCheck(models.Model):
|
||||
_inherit = "quality.check"
|
||||
_description = '零件特采'
|
||||
|
||||
# ==========零件特采接口==========
|
||||
def _register_tool_groups(self):
|
||||
create_url = '/AutoDeviceApi/FeedBackOut'
|
||||
sf_sync_config = self.env['res.config.settings'].get_values()
|
||||
token = sf_sync_config['token']
|
||||
sf_secret_key = sf_sync_config['sf_secret_key']
|
||||
headers = Common.get_headers(self, token, sf_secret_key)
|
||||
strurl = sf_sync_config['sf_url'] + create_url
|
||||
val = {
|
||||
'RfidCode': None,
|
||||
}
|
||||
kw = json.dumps(val, ensure_ascii=False)
|
||||
r = requests.post(strurl, json={}, data={'kw': kw, 'token': token}, headers=headers)
|
||||
ret = r.json()
|
||||
if r == 200:
|
||||
return "零件特采发送成功"
|
||||
else:
|
||||
raise ValidationError("零件特采发送失败")
|
||||
|
||||
# @api.onchange('quality_state')
|
||||
# def _onchange_quality_state(self):
|
||||
# if self.quality_state in ['pass', 'fail']:
|
||||
# self._register_tool_groups()
|
||||
@@ -7,6 +7,7 @@ from odoo.exceptions import UserError
|
||||
class ReSaleOrder(models.Model):
|
||||
_inherit = 'sale.order'
|
||||
|
||||
logistics_way = fields.Selection([('自提', '自提'), ('到付', '到付'), ('在线支付', '在线支付')], string='物流方式')
|
||||
state = fields.Selection(
|
||||
selection=[
|
||||
('draft', "报价"),
|
||||
@@ -19,7 +20,6 @@ class ReSaleOrder(models.Model):
|
||||
readonly=True, copy=False, index=True,
|
||||
tracking=3,
|
||||
default='draft')
|
||||
|
||||
deadline_of_delivery = fields.Date('订单交期', tracking=True)
|
||||
person_of_delivery = fields.Char('交货人')
|
||||
telephone_of_delivery = fields.Char('交货人电话号码')
|
||||
|
||||
@@ -10,22 +10,20 @@
|
||||
<field name="partner_id" widget="res_partner_many2one" context="{'is_supplier': True }"/>
|
||||
</field>
|
||||
<field name="currency_id" position="after">
|
||||
<field name="check_status" invisible="1"/>
|
||||
<!-- <field name="state"/>-->
|
||||
<field name="remark" attrs="{'readonly': ['&',('state', 'in', ['purchase']),('check_status','in',
|
||||
['pending','approved'])]}"/>
|
||||
</field>
|
||||
<xpath expr="//form/header/button[@name='action_rfq_send'][1]" position="after">
|
||||
<button name="sf_sale.action_purchase_order_check_wizard" string="审核" type="action"
|
||||
context="{'default_order_id':active_id}" groups="sf_base.group_purchase_director"
|
||||
attrs="{'invisible': ['&',('check_status','in', ['approved',False,'fail']),('state', 'in', ['purchase'])]}"
|
||||
attrs="{'invisible': ['&',('check_status','in', ['approved',False,'fail']),('state', 'in', ['purchase','draft'])]}"
|
||||
class="oe_highlight"/>
|
||||
|
||||
</xpath>
|
||||
<xpath expr="//form/header/button[@name='button_confirm'][2]" position="replace">
|
||||
<button name="button_confirm" type="object" context="{'validate_analytic': True}"
|
||||
string="确认订单" id="draft_confirm"
|
||||
attrs="{'invisible': ['|','&','&', ('state', 'in', ['purchase']), ('check_status', 'in', ['approved']), ('date_approve', '!=', False),'&', '&',('state', 'in', ['purchase', 'draft']),('check_status', 'in', [False, 'pending', 'fail']),('date_approve', '=', False)]}"
|
||||
attrs="{'invisible': ['|','&','&', ('state', 'in', ['purchase','draft']), ('check_status', 'in', ['approved']), ('date_approve', '!=', False),'&', '&',('state', 'in', ['purchase', 'draft']),('check_status', 'in', [False, 'pending', 'fail']),('date_approve', '=', False)]}"
|
||||
/>
|
||||
<button name="button_confirming" type="object"
|
||||
string="确认订单"
|
||||
|
||||
@@ -87,8 +87,11 @@
|
||||
attrs="{'invisible': ['|','&',('check_status', '!=', 'approved'),('state', 'in', ['draft','cancel']),'&','&',('check_status', '=', 'approved'),('state', 'in', ['sale','cancel']),('schedule_status', 'not in', False)]}"/>
|
||||
</xpath>
|
||||
<xpath expr="//form/header/button[@name='action_cancel']" position="attributes">
|
||||
<attribute name="attrs">{'invisible': ['|',('state', 'in', ['cancel']),('check_status', 'in',
|
||||
[False,'approved'])]}
|
||||
<attribute name="attrs">{'invisible': ['|','&',('state', 'in',
|
||||
['cancel','draft']),('check_status',
|
||||
'in',
|
||||
[False,'approved']),'&','&',('check_status', '=', 'approved'),('state', 'in',
|
||||
['sale','cancel','draft']),('schedule_status', 'not in', False)]}
|
||||
</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//form/header/button[@name='action_draft']" position="attributes">
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# -*-coding:utf-8-*-
|
||||
from . import models
|
||||
from . import wizard
|
||||
from . import controllers
|
||||
from odoo import api, SUPERUSER_ID
|
||||
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
'security/ir.model.access.csv',
|
||||
'wizard/wizard_view.xml',
|
||||
'views/tool_base_views.xml',
|
||||
'views/sf_maintenance_equipment.xml',
|
||||
'views/menu_view.xml',
|
||||
'views/tool_material_search.xml',
|
||||
],
|
||||
|
||||
1
sf_tool_management/controllers/__init__.py
Normal file
1
sf_tool_management/controllers/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import controllers
|
||||
56
sf_tool_management/controllers/controllers.py
Normal file
56
sf_tool_management/controllers/controllers.py
Normal file
@@ -0,0 +1,56 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import logging
|
||||
import json
|
||||
import base64
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
|
||||
|
||||
class Manufacturing_Connect(http.Controller):
|
||||
|
||||
@http.route('/AutoDeviceApi/FeedBackOut', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def get_equipment_tool_Info(self, **kw):
|
||||
"""
|
||||
机床当前刀库实时信息
|
||||
:param kw:
|
||||
:return:
|
||||
"""
|
||||
logging.info('get_equipment_tool_Info:%s' % kw)
|
||||
try:
|
||||
datas = request.httprequest.data
|
||||
ret = json.loads(datas)
|
||||
ret = json.loads(ret['result'])
|
||||
logging.info('DeviceId:%s' % ret)
|
||||
equipment = request.env['maintenance.equipment'].sudo().search([('name', '=', ret['DeviceId'])])
|
||||
|
||||
res = {'Succeed': True, 'Datas': []}
|
||||
if equipment:
|
||||
for item in equipment:
|
||||
data = []
|
||||
for equipment_tool_id in item.product_template_ids:
|
||||
functional_tool_id = self.env['sf.functional.cutting.tool.entity'].sudo().search(
|
||||
[('code', '=', equipment_tool_id.tool_code)])
|
||||
alarm_time = None
|
||||
if functional_tool_id.functional_tool_status == '报警':
|
||||
alarm_time = self.env['sf.functional.tool.warning'].sudo().search(
|
||||
[('code', '=', equipment_tool_id.tool_code)]).alarm_time
|
||||
equipment_tool = {
|
||||
'RfidCode': None,
|
||||
'ToolId': equipment_tool_id.code,
|
||||
'ToolName': equipment_tool_id.functional_tool_name_id.name,
|
||||
'MaxLife': equipment_tool_id.life_value_max,
|
||||
'UseLife': equipment_tool_id.used_value,
|
||||
'AddDatetime': equipment_tool_id.tool_install_time,
|
||||
'State': functional_tool_id.functional_tool_status,
|
||||
'WarnDate': alarm_time if alarm_time else False
|
||||
}
|
||||
data.append(equipment_tool)
|
||||
res['Datas'].append({
|
||||
'DeviceId': item.name,
|
||||
'Data': data
|
||||
})
|
||||
except Exception as e:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
|
||||
logging.info('get_equipment_tool_Info error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
@@ -1,9 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import json
|
||||
import requests
|
||||
from datetime import timedelta
|
||||
from odoo import fields, models, api
|
||||
from odoo import SUPERUSER_ID
|
||||
from odoo import fields, models, api
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.addons.sf_base.commons.common import Common
|
||||
|
||||
|
||||
class FunctionalCuttingToolEntity(models.Model):
|
||||
@@ -44,13 +47,13 @@ class FunctionalCuttingToolEntity(models.Model):
|
||||
if record.barcode_id.quant_ids:
|
||||
for quant_id in record.barcode_id.quant_ids:
|
||||
if quant_id.inventory_quantity_auto_apply > 0:
|
||||
record.current_location_id = quant_id.location_id
|
||||
record.current_location = quant_id.location_id.name
|
||||
record.sudo().current_location_id = quant_id.location_id
|
||||
record.sudo().current_location = quant_id.location_id.name
|
||||
if record.current_location_id:
|
||||
record.get_location_num()
|
||||
record.sudo().get_location_num()
|
||||
else:
|
||||
record.current_location_id = False
|
||||
record.current_location = False
|
||||
record.sudo().current_location_id = False
|
||||
record.sudo().current_location = False
|
||||
|
||||
def get_location_num(self):
|
||||
"""
|
||||
@@ -128,24 +131,24 @@ class FunctionalCuttingToolEntity(models.Model):
|
||||
print('111')
|
||||
if record.cutting_tool_integral_model_id:
|
||||
print(record.cutting_tool_integral_model_id)
|
||||
record.suitable_machining_method_ids = record.cutting_tool_integral_model_id.suitable_machining_method_ids.ids
|
||||
record.blade_tip_characteristics_id = record.cutting_tool_integral_model_id.blade_tip_characteristics_id.id
|
||||
record.handle_type_id = record.cutting_tool_integral_model_id.handle_type_id.id
|
||||
record.cutting_direction_ids = record.cutting_tool_integral_model_id.cutting_direction_ids.ids
|
||||
record.suitable_coolant_ids = record.cutting_tool_integral_model_id.suitable_coolant_ids.ids
|
||||
record.sudo().suitable_machining_method_ids = record.cutting_tool_integral_model_id.suitable_machining_method_ids.ids
|
||||
record.sudo().blade_tip_characteristics_id = record.cutting_tool_integral_model_id.blade_tip_characteristics_id.id
|
||||
record.sudo().handle_type_id = record.cutting_tool_integral_model_id.handle_type_id.id
|
||||
record.sudo().cutting_direction_ids = record.cutting_tool_integral_model_id.cutting_direction_ids.ids
|
||||
record.sudo().suitable_coolant_ids = record.cutting_tool_integral_model_id.suitable_coolant_ids.ids
|
||||
print(record.cutting_tool_integral_model_id.blade_tip_characteristics_id.ids)
|
||||
elif record.cutting_tool_blade_model_id:
|
||||
record.suitable_machining_method_ids = record.cutting_tool_blade_model_id.suitable_machining_method_ids.ids
|
||||
record.blade_tip_characteristics_id = record.cutting_tool_blade_model_id.blade_tip_characteristics_id.id
|
||||
record.handle_type_id = record.cutting_tool_blade_model_id.handle_type_id.id
|
||||
record.cutting_direction_ids = record.cutting_tool_blade_model_id.cutting_direction_ids.ids
|
||||
record.suitable_coolant_ids = record.cutting_tool_blade_model_id.suitable_coolant_ids.ids
|
||||
record.sudo().suitable_machining_method_ids = record.cutting_tool_blade_model_id.suitable_machining_method_ids.ids
|
||||
record.sudo().blade_tip_characteristics_id = record.cutting_tool_blade_model_id.blade_tip_characteristics_id.id
|
||||
record.sudo().handle_type_id = record.cutting_tool_blade_model_id.handle_type_id.id
|
||||
record.sudo().cutting_direction_ids = record.cutting_tool_blade_model_id.cutting_direction_ids.ids
|
||||
record.sudo().suitable_coolant_ids = record.cutting_tool_blade_model_id.suitable_coolant_ids.ids
|
||||
else:
|
||||
record.suitable_machining_method_ids = []
|
||||
record.blade_tip_characteristics_id = None
|
||||
record.handle_type_id = None
|
||||
record.cutting_direction_ids = []
|
||||
record.suitable_coolant_ids = []
|
||||
record.sudo().suitable_machining_method_ids = []
|
||||
record.sudo().blade_tip_characteristics_id = None
|
||||
record.sudo().handle_type_id = None
|
||||
record.sudo().cutting_direction_ids = []
|
||||
record.sudo().suitable_coolant_ids = []
|
||||
|
||||
def _get_functional_tool_model_ids(self, functional_tool_model_code):
|
||||
functional_tool_model_ids = []
|
||||
@@ -174,6 +177,34 @@ class FunctionalCuttingToolEntity(models.Model):
|
||||
('coarse_middle_thin', '=', self.coarse_middle_thin)]
|
||||
return result
|
||||
|
||||
# ==========刀具组接口==========
|
||||
def _register_functional_tool_groups(self, obj):
|
||||
create_url = '/AutoDeviceApi/FeedBackOut'
|
||||
sf_sync_config = self.env['res.config.settings'].get_values()
|
||||
token = sf_sync_config['token']
|
||||
sf_secret_key = sf_sync_config['sf_secret_key']
|
||||
headers = Common.get_headers(obj, token, sf_secret_key)
|
||||
strurl = sf_sync_config['sf_url'] + create_url
|
||||
val = {
|
||||
'ToolName': obj.name,
|
||||
'GroupName': obj.tool_groups_id.name,
|
||||
'ToolId': obj.code
|
||||
}
|
||||
kw = json.dumps(val, ensure_ascii=False)
|
||||
r = requests.post(strurl, json={}, data={'kw': kw, 'token': token}, headers=headers)
|
||||
ret = r.json()
|
||||
if r == 200:
|
||||
return "刀具组发送成功"
|
||||
else:
|
||||
raise ValidationError("刀具组发送失败")
|
||||
|
||||
# @api.model_create_multi
|
||||
# def create(self, vals):
|
||||
# obj = super(FunctionalCuttingToolEntity, self).create(vals)
|
||||
# # 调用刀具组接口
|
||||
# self._register_functional_tool_groups(obj)
|
||||
# return obj
|
||||
|
||||
|
||||
class FunctionalToolWarning(models.Model):
|
||||
_name = 'sf.functional.tool.warning'
|
||||
@@ -240,7 +271,7 @@ class FunctionalToolWarning(models.Model):
|
||||
class StockMoveLine(models.Model):
|
||||
_inherit = 'stock.move.line'
|
||||
_description = '功能刀具出入库记录'
|
||||
# _order = 'install_tool_time desc'
|
||||
_order = 'date desc'
|
||||
|
||||
functional_tool_name_id = fields.Many2one('sf.functional.tool.assembly', string='功能刀具名称')
|
||||
functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', store=True,
|
||||
@@ -310,9 +341,9 @@ class RealTimeDistributionOfFunctionalTools(models.Model):
|
||||
def _compute_name(self):
|
||||
for obj in self:
|
||||
if obj.tool_groups_id:
|
||||
obj.name = '%s-D%sR%s' % (obj.tool_groups_id.name, obj.diameter, obj.knife_tip_r_angle)
|
||||
obj.sudo().name = '%s-D%sR%s' % (obj.tool_groups_id.name, obj.diameter, obj.knife_tip_r_angle)
|
||||
else:
|
||||
obj.name = None
|
||||
obj.sudo().name = None
|
||||
|
||||
@api.constrains('min_stock_num', 'max_stock_num')
|
||||
def _check_stock_num(self):
|
||||
@@ -330,26 +361,26 @@ class RealTimeDistributionOfFunctionalTools(models.Model):
|
||||
for tool in self:
|
||||
if tool:
|
||||
# 判断功能刀具组装单是否已经完成
|
||||
tool.estimate_functional_tool_assembly_ids(tool)
|
||||
tool.get_stock_num(tool)
|
||||
tool.sudo().estimate_functional_tool_assembly_ids(tool)
|
||||
tool.sudo().get_stock_num(tool)
|
||||
# 计算当前库存量
|
||||
tool.tool_stock_total = tool.tool_stock_num + tool.side_shelf_num + tool.on_tool_stock_num
|
||||
tool.sudo().tool_stock_total = tool.tool_stock_num + tool.side_shelf_num + tool.on_tool_stock_num
|
||||
# 如果当前库存量小于最低库存量,计算批次补货量
|
||||
tool.open_batch_replenishment_num(tool)
|
||||
tool.sudo().open_batch_replenishment_num(tool)
|
||||
|
||||
def open_batch_replenishment_num(self, tool):
|
||||
"""
|
||||
计算批次补货量
|
||||
"""
|
||||
if tool.tool_stock_total < tool.min_stock_num:
|
||||
tool.batch_replenishment_num = tool.max_stock_num - tool.tool_stock_total
|
||||
tool.sudo().batch_replenishment_num = tool.max_stock_num - tool.tool_stock_total
|
||||
# 根据判断创建功能刀具组装单
|
||||
if not tool.sf_functional_tool_assembly_ids and re.match(r'^\d+$', str(tool.id)):
|
||||
for i in range(tool.batch_replenishment_num):
|
||||
tool.create_functional_tool_assembly(tool)
|
||||
tool.sudo().create_functional_tool_assembly(tool)
|
||||
print(i, ": ", tool.sf_functional_tool_assembly_ids)
|
||||
else:
|
||||
tool.batch_replenishment_num = 0
|
||||
tool.sudo().batch_replenishment_num = 0
|
||||
|
||||
def create_functional_tool_assembly(self, tool):
|
||||
"""
|
||||
@@ -369,7 +400,7 @@ class RealTimeDistributionOfFunctionalTools(models.Model):
|
||||
'whether_standard_knife': tool.whether_standard_knife,
|
||||
'reason_for_applying': '安全库存',
|
||||
})
|
||||
tool.sf_functional_tool_assembly_ids = [(4, functional_tool_assembly.id)]
|
||||
tool.sudo().sf_functional_tool_assembly_ids = [(4, functional_tool_assembly.id)]
|
||||
|
||||
def estimate_functional_tool_assembly_ids(self, tool):
|
||||
"""
|
||||
@@ -378,24 +409,24 @@ class RealTimeDistributionOfFunctionalTools(models.Model):
|
||||
for sf_functional_tool_assembly_id in tool.sf_functional_tool_assembly_ids:
|
||||
if sf_functional_tool_assembly_id.assemble_status == '0':
|
||||
return False
|
||||
tool.sf_functional_tool_assembly_ids = []
|
||||
tool.sudo().sf_functional_tool_assembly_ids = []
|
||||
|
||||
def get_stock_num(self, tool):
|
||||
"""
|
||||
计算刀具房数量、线边刀库数量、机内刀库数量
|
||||
"""
|
||||
if tool:
|
||||
tool.tool_stock_num = 0
|
||||
tool.side_shelf_num = 0
|
||||
tool.on_tool_stock_num = 0
|
||||
tool.sudo().tool_stock_num = 0
|
||||
tool.sudo().side_shelf_num = 0
|
||||
tool.sudo().on_tool_stock_num = 0
|
||||
if tool.sf_functional_cutting_tool_entity_ids:
|
||||
for cutting_tool in tool.sf_functional_cutting_tool_entity_ids:
|
||||
if cutting_tool.tool_room_num > 0:
|
||||
tool.tool_stock_num += 1
|
||||
tool.sudo().tool_stock_num += 1
|
||||
elif cutting_tool.line_edge_knife_library_num > 0:
|
||||
tool.side_shelf_num += 1
|
||||
tool.sudo().side_shelf_num += 1
|
||||
elif cutting_tool.machine_knife_library_num > 0:
|
||||
tool.on_tool_stock_num += 1
|
||||
tool.sudo().on_tool_stock_num += 1
|
||||
|
||||
def create_or_edit_safety_stock(self, vals, sf_functional_cutting_tool_entity_ids):
|
||||
"""
|
||||
@@ -480,21 +511,21 @@ class MachineTableToolChangingApply(models.Model):
|
||||
def _compute_functional_tool_status(self):
|
||||
for record in self:
|
||||
if record.alarm_value < record.used_value:
|
||||
record.functional_tool_status = '报警'
|
||||
record.sudo().functional_tool_status = '报警'
|
||||
else:
|
||||
record.functional_tool_status = '正常'
|
||||
record.sudo().functional_tool_status = '正常'
|
||||
|
||||
@api.depends('maintenance_equipment_id')
|
||||
def _compute_machine_table_type_id(self):
|
||||
for record in self:
|
||||
if record:
|
||||
record.production_line_id = record.maintenance_equipment_id.production_line_id.id
|
||||
record.machine_table_type_id = record.maintenance_equipment_id.category_id.id
|
||||
record.machine_tool_code = record.maintenance_equipment_id.code
|
||||
record.sudo().production_line_id = record.maintenance_equipment_id.production_line_id.id
|
||||
record.sudo().machine_table_type_id = record.maintenance_equipment_id.category_id.id
|
||||
record.sudo().machine_tool_code = record.maintenance_equipment_id.code
|
||||
else:
|
||||
record.production_line_id = None
|
||||
record.machine_table_type_id = None
|
||||
record.machine_tool_code = None
|
||||
record.sudo().production_line_id = None
|
||||
record.sudo().machine_table_type_id = None
|
||||
record.sudo().machine_tool_code = None
|
||||
|
||||
@api.constrains("cutter_spacing_code_id")
|
||||
def _check_cutter_spacing_code_id(self):
|
||||
@@ -594,16 +625,16 @@ class CAMWorkOrderProgramKnifePlan(models.Model):
|
||||
_name = 'sf.cam.work.order.program.knife.plan'
|
||||
_description = 'CAM工单程序用刀计划'
|
||||
|
||||
name = fields.Char(string='工单任务编号', readonly=False)
|
||||
cam_procedure_code = fields.Char(string='CAM程序编号', readonly=False)
|
||||
cam_cutter_spacing_code = fields.Char(string='CAM刀位号', readonly=False)
|
||||
name = fields.Char('工单任务编号')
|
||||
cam_procedure_code = fields.Char('程序名')
|
||||
filename = fields.Char('文件')
|
||||
cam_cutter_spacing_code = fields.Char('刀号')
|
||||
tool_position_interface_type = fields.Selection(
|
||||
[('BT刀柄式', 'BT刀柄式'), ('SK刀柄式', 'SK刀柄式'), ('HSK刀柄式', 'HSK刀柄式'),
|
||||
('CAT刀柄式', 'CAT刀柄式'), ('ISO刀盘式', 'ISO刀盘式'), ('DIN刀盘式', 'DIN刀盘式'),
|
||||
('直装固定式', '直装固定式')], string='刀位接口型号')
|
||||
production_line_id = fields.Many2one('sf.production.line', string='生产线', readonly=False,
|
||||
group_expand='_read_group_names')
|
||||
machine_table_name_id = fields.Many2one('maintenance.equipment', string='机床名称', readonly=False,
|
||||
production_line_id = fields.Many2one('sf.production.line', string='生产线', group_expand='_read_group_names')
|
||||
machine_table_name_id = fields.Many2one('maintenance.equipment', string='机床名称',
|
||||
domain="[('production_line_id', '=', production_line_id)]")
|
||||
machine_table_name = fields.Char(string='机台号', readonly=True, related='machine_table_name_id.name')
|
||||
cutter_spacing_code_id = fields.Many2one('maintenance.equipment.tool', string='刀位号', required=True,
|
||||
@@ -616,8 +647,9 @@ class CAMWorkOrderProgramKnifePlan(models.Model):
|
||||
|
||||
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号',
|
||||
domain=[('product_id.name', '=', '功能刀具')])
|
||||
functional_tool_name = fields.Char(string='功能刀具名称', required=True)
|
||||
functional_tool_name = fields.Char(string='功能刀具名称', compute='_compute_functional_tool_name')
|
||||
functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', readonly=False)
|
||||
tool_groups_id = fields.Many2one('sf.tool.groups', '刀具组')
|
||||
diameter = fields.Integer(string='刀具直径(mm)', readonly=False)
|
||||
tool_included_angle = fields.Float(string='刀尖R角(mm)', readonly=False)
|
||||
tool_loading_length = fields.Float(string='总长度(mm)', readonly=False)
|
||||
@@ -629,12 +661,28 @@ class CAMWorkOrderProgramKnifePlan(models.Model):
|
||||
L_D = fields.Float(string='L/D值', readonly=False)
|
||||
clearance_length = fields.Float(string='避空长(mm)', readonly=False)
|
||||
required_cutting_time = fields.Integer(string='需切削时长', readonly=False)
|
||||
process_type = fields.Char('加工类型')
|
||||
margin_x_y = fields.Float('余量_X/Y')
|
||||
margin_z = fields.Float('余量_Z')
|
||||
finish_depth = fields.Float('加工深度')
|
||||
shank_model = fields.Char('刀柄型号')
|
||||
estimated_processing_time = fields.Char('预计加工时间')
|
||||
|
||||
plan_execute_status = fields.Selection([('0', '待下发'), ('1', '执行中'), ('2', '已完成')],
|
||||
string='计划执行状态', default='0', readonly=False)
|
||||
|
||||
sf_functional_tool_assembly_id = fields.Many2one('sf.functional.tool.assembly', '功能刀具组装', readonly=True)
|
||||
|
||||
@api.depends('diameter', 'tool_included_angle', 'tool_groups_id')
|
||||
def _compute_functional_tool_name(self):
|
||||
for obj in self:
|
||||
if obj.tool_groups_id:
|
||||
obj.functional_tool_name = '%s-D%sR%s' % (
|
||||
obj.tool_groups_id.name, obj.diameter,
|
||||
obj.tool_included_angle)
|
||||
else:
|
||||
obj.functional_tool_name = None
|
||||
|
||||
@api.model
|
||||
def _read_group_names(self, categories, domain, order):
|
||||
names = categories._search([], order=order, access_rights_uid=SUPERUSER_ID)
|
||||
@@ -646,27 +694,34 @@ class CAMWorkOrderProgramKnifePlan(models.Model):
|
||||
:return:
|
||||
"""
|
||||
record = self.env['sf.functional.tool.assembly'].create({
|
||||
'barcode_id': self.barcode_id.id,
|
||||
'functional_tool_name_id': self.functional_tool_name_id.id,
|
||||
'functional_tool_name': self.functional_tool_name,
|
||||
'functional_tool_type_id': self.functional_tool_type_id.id,
|
||||
'tool_groups_id': self.tool_groups_id.id,
|
||||
'functional_tool_diameter': self.diameter,
|
||||
'functional_tool_length': self.tool_loading_length,
|
||||
'loading_task_source': '0',
|
||||
'coarse_middle_thin': None,
|
||||
'tool_loading_length': None,
|
||||
'applicant': self.env.user.name,
|
||||
'reason_for_applying': self.reason_for_applying,
|
||||
'use_tool_time': self.need_knife_time,
|
||||
'knife_tip_r_angle': self.tool_included_angle,
|
||||
'tool_loading_length': self.tool_loading_length,
|
||||
'functional_tool_length': self.extension_length,
|
||||
'effective_length': self.effective_length,
|
||||
'whether_standard_knife': self.whether_standard_knife,
|
||||
'coarse_middle_thin': self.coarse_middle_thin,
|
||||
'new_former': self.new_former,
|
||||
'production_line_name_id': self.production_line_id.id,
|
||||
'machine_tool_name_id': self.machine_table_name_id.id,
|
||||
'machine_tool_code': self.cam_procedure_code,
|
||||
'cutter_spacing_code': self.cam_cutter_spacing_code,
|
||||
'cutter_spacing_code_id': self.env['maintenance.equipment.tool'].sudo().search(
|
||||
[('code', '=', self.cam_cutter_spacing_code), ('equipment_id', '=', self.machine_table_name_id.id)]).id,
|
||||
|
||||
'loading_task_source': '0',
|
||||
'applicant': self.env.user.name,
|
||||
'use_tool_time': self.need_knife_time,
|
||||
'reason_for_applying': '工单用刀',
|
||||
|
||||
'sf_cam_work_order_program_knife_plan_id': self.id
|
||||
})
|
||||
self.sf_functional_tool_assembly_id = record.id
|
||||
|
||||
# 将计划执行状态改为执行中
|
||||
self.env['sf.cam.work.order.program.knife.plan'].search(
|
||||
[('barcode_id', '=', self.barcode_id.id)]).write(
|
||||
[('name', '=', self.name), ('functional_tool_name', '=', self.functional_tool_name)]).write(
|
||||
{'plan_execute_status': '1',
|
||||
'applicant': self.env.user.name})
|
||||
|
||||
@@ -676,16 +731,50 @@ class CAMWorkOrderProgramKnifePlan(models.Model):
|
||||
:return:
|
||||
"""
|
||||
self.env['sf.functional.tool.assembly'].search(
|
||||
[('barcode_id', '=', self.barcode_id.id),
|
||||
[('assembly_order_code', '=', self.sf_functional_tool_assembly_id.assembly_order_code),
|
||||
('loading_task_source', '=', '0')]).unlink()
|
||||
|
||||
# 将计划执行状态改为待执行,同时清除申请人、功能刀具组装字段数据
|
||||
self.env['sf.cam.work.order.program.knife.plan'].search(
|
||||
[('barcode_id', '=', self.barcode_id.id)]).write(
|
||||
[('name', '=', self.name), ('functional_tool_name', '=', self.functional_tool_name)]).write(
|
||||
{'plan_execute_status': '0',
|
||||
'applicant': None,
|
||||
'sf_functional_tool_assembly_id': None})
|
||||
|
||||
def create_cam_work_plan(self, cnc_processing):
|
||||
"""
|
||||
根据传入的工单信息,查询是否有需要的功能刀具,如果没有则生成CAM工单程序用刀计划
|
||||
"""
|
||||
status = False
|
||||
if cnc_processing.functional_tool_type_id and cnc_processing.cutting_tool_name:
|
||||
functional_tools = self.env['sf.real.time.distribution.of.functional.tools'].sudo().search(
|
||||
[('sf_cutting_tool_type_id', '=', cnc_processing.functional_tool_type_id.id),
|
||||
('name', '=', cnc_processing.cutting_tool_name)])
|
||||
if functional_tools:
|
||||
for functional_tool in functional_tools:
|
||||
if functional_tool.on_tool_stock_num == 0:
|
||||
# self.env['sf.cnc.processing'].register_cnc_processing(cnc_processing)
|
||||
if functional_tool.tool_stock_num == 0 and functional_tool.side_shelf_num == 0:
|
||||
status = True
|
||||
else:
|
||||
status = True
|
||||
if status:
|
||||
self.env['sf.cam.work.order.program.knife.plan'].sudo().create({
|
||||
'name': cnc_processing.workorder_id.production_id.name,
|
||||
'cam_procedure_code': cnc_processing.program_name,
|
||||
'filename': cnc_processing.cnc_id.name,
|
||||
'functional_tool_type_id': cnc_processing.functional_tool_type_id.id,
|
||||
'functional_tool_name': cnc_processing.cutting_tool_name,
|
||||
'cam_cutter_spacing_code': cnc_processing.cutting_tool_no,
|
||||
'process_type': cnc_processing.processing_type,
|
||||
'margin_x_y': float(cnc_processing.margin_x_y),
|
||||
'margin_z': float(cnc_processing.margin_z),
|
||||
'finish_depth': float(cnc_processing.depth_of_processing_z),
|
||||
'extension_length': float(cnc_processing.cutting_tool_extension_length),
|
||||
'shank_model': cnc_processing.cutting_tool_handle_type,
|
||||
'estimated_processing_time': cnc_processing.estimated_processing_time,
|
||||
})
|
||||
|
||||
|
||||
class FunctionalToolAssembly(models.Model):
|
||||
_name = 'sf.functional.tool.assembly'
|
||||
|
||||
@@ -1,9 +1,22 @@
|
||||
from odoo import models, api
|
||||
from odoo import models, api, fields
|
||||
|
||||
|
||||
class SfMaintenanceEquipmentTool(models.Model):
|
||||
_inherit = 'maintenance.equipment.tool'
|
||||
|
||||
functional_tool_name_id = fields.Many2one('sf.functional.cutting.tool.entity', '功能刀具名称')
|
||||
|
||||
image = fields.Binary('图片', related='functional_tool_name_id.image')
|
||||
tool_code = fields.Char('功能刀具编码', related='functional_tool_name_id.code')
|
||||
functional_tool_type = fields.Char('功能刀具类型', related='functional_tool_name_id.sf_cutting_tool_type_id.name')
|
||||
tool_groups = fields.Char('刀具组', related='functional_tool_name_id.tool_groups_id.name')
|
||||
diameter = fields.Integer('直径(mm)', related='functional_tool_name_id.functional_tool_diameter')
|
||||
knife_tip_r_angle = fields.Float('刀尖R角(mm)', related='functional_tool_name_id.knife_tip_r_angle')
|
||||
life_value_max = fields.Integer('最大寿命值(min)', related='functional_tool_name_id.max_lifetime_value')
|
||||
alarm_value = fields.Integer('报警值(min)', related='functional_tool_name_id.alarm_value')
|
||||
used_value = fields.Integer('已使用值(min)', related='functional_tool_name_id.used_value')
|
||||
tool_install_time = fields.Datetime('机内装刀时间')
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
tools = super().create(vals_list)
|
||||
|
||||
38
sf_tool_management/models/mrp_workorder.py
Normal file
38
sf_tool_management/models/mrp_workorder.py
Normal file
@@ -0,0 +1,38 @@
|
||||
import json
|
||||
import requests
|
||||
from odoo import fields, models, api
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.addons.sf_base.commons.common import Common
|
||||
|
||||
|
||||
class CNCprocessing(models.Model):
|
||||
_inherit = 'sf.cnc.processing'
|
||||
_description = 'CNC加工用刀检测'
|
||||
|
||||
# ==========MES装刀指令接口==========
|
||||
def register_cnc_processing(self, cnc_processing):
|
||||
create_url = '/AutoDeviceApi/FeedBackOut'
|
||||
sf_sync_config = self.env['res.config.settings'].get_values()
|
||||
token = sf_sync_config['token']
|
||||
sf_secret_key = sf_sync_config['sf_secret_key']
|
||||
headers = Common.get_headers(self, token, sf_secret_key)
|
||||
strurl = sf_sync_config['sf_url'] + create_url
|
||||
val = {
|
||||
'DeviceId': cnc_processing.workorder_id.machine_tool_name,
|
||||
'RfidCode': None,
|
||||
'ToolId': cnc_processing.cutting_tool_no
|
||||
}
|
||||
kw = json.dumps(val, ensure_ascii=False)
|
||||
r = requests.post(strurl, json={}, data={'kw': kw, 'token': token}, headers=headers)
|
||||
ret = r.json()
|
||||
if r == 200:
|
||||
return "MES装刀指令发送成功"
|
||||
else:
|
||||
raise ValidationError("MES装刀指令发送失败")
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals):
|
||||
obj = super(CNCprocessing, self).create(vals)
|
||||
# 调用CAM工单程序用刀计划创建方法
|
||||
self.env['sf.cam.work.order.program.knife.plan'].create_cam_work_plan(obj)
|
||||
return obj
|
||||
@@ -1,20 +1,34 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_sf_functional_cutting_tool_entity,sf.functional.cutting.tool.entity,model_sf_functional_cutting_tool_entity,base.group_user,1,1,1,1
|
||||
access_sf_functional_tool_warning,sf.functional.tool.warning,model_sf_functional_tool_warning,base.group_user,1,1,1,1
|
||||
access_sf_real_time_distribution_of_functional_tools,sf.real.time.distribution.of.functional.tools,model_sf_real_time_distribution_of_functional_tools,base.group_user,1,1,1,1
|
||||
access_sf_functional_cutting_tool_entity,sf.functional.cutting.tool.entity,model_sf_functional_cutting_tool_entity,sf_base.group_sf_tool_user,1,1,1,1
|
||||
access_sf_functional_tool_warning,sf.functional.tool.warning,model_sf_functional_tool_warning,sf_base.group_sf_tool_user,1,1,1,1
|
||||
access_sf_real_time_distribution_of_functional_tools,sf.real.time.distribution.of.functional.tools,model_sf_real_time_distribution_of_functional_tools,sf_base.group_sf_tool_user,1,1,1,1
|
||||
|
||||
access_sf_cam_work_order_program_knife_plan,sf.cam.work.order.program.knife.plan,model_sf_cam_work_order_program_knife_plan,base.group_user,1,1,1,1
|
||||
access_sf_machine_table_tool_changing_apply,sf.machine.table.tool.changing.apply,model_sf_machine_table_tool_changing_apply,base.group_user,1,1,1,1
|
||||
access_sf_cam_work_order_program_knife_plan,sf.cam.work.order.program.knife.plan,model_sf_cam_work_order_program_knife_plan,sf_base.group_sf_tool_user,1,1,1,1
|
||||
access_sf_machine_table_tool_changing_apply,sf.machine.table.tool.changing.apply,model_sf_machine_table_tool_changing_apply,sf_base.group_sf_tool_user,1,1,1,1
|
||||
|
||||
|
||||
access_sf_tool_change_requirement_information,sf.tool.change.requirement.information,model_sf_tool_change_requirement_information,base.group_user,1,1,1,1
|
||||
access_sf_tool_transfer_request_information,sf.tool.transfer.request.information,model_sf_tool_transfer_request_information,base.group_user,1,1,1,1
|
||||
|
||||
access_sf_functional_tool_assembly,sf.functional.tool.assembly,model_sf_functional_tool_assembly,base.group_user,1,1,1,1
|
||||
access_sf_functional_tool_assembly_order,sf.functional.tool.assembly.order,model_sf_functional_tool_assembly_order,base.group_user,1,1,1,1
|
||||
access_sf_tool_material_search,sf.tool.material.search,model_sf_tool_material_search,base.group_user,1,1,1,1
|
||||
|
||||
access_sf_tool_change_requirement_information,sf.tool.change.requirement.information,model_sf_tool_change_requirement_information,sf_base.group_sf_tool_user,1,1,1,1
|
||||
access_sf_tool_transfer_request_information,sf.tool.transfer.request.information,model_sf_tool_transfer_request_information,sf_base.group_sf_tool_user,1,1,1,1
|
||||
|
||||
access_sf_functional_tool_assembly,sf.functional.tool.assembly,model_sf_functional_tool_assembly,sf_base.group_sf_tool_user,1,1,1,1
|
||||
access_sf_functional_tool_assembly_order,sf.functional.tool.assembly.order,model_sf_functional_tool_assembly_order,sf_base.group_sf_tool_user,1,1,1,1
|
||||
access_sf_tool_material_search,sf.tool.material.search,model_sf_tool_material_search,sf_base.group_sf_tool_user,1,1,1,1
|
||||
|
||||
|
||||
access_sf_functional_cutting_tool_entity_group_plan_dispatch,sf.functional.cutting.tool.entity,model_sf_functional_cutting_tool_entity,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_sf_functional_tool_warning_group_plan_dispatch,sf.functional.tool.warning,model_sf_functional_tool_warning,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_sf_real_time_distribution_of_functional_tools_group_plan_dispatch,sf.real.time.distribution.of.functional.tools,model_sf_real_time_distribution_of_functional_tools,sf_base.group_plan_dispatch,1,0,0,0
|
||||
|
||||
access_sf_cam_work_order_program_knife_plan_group_plan_dispatch,sf.cam.work.order.program.knife.plan,model_sf_cam_work_order_program_knife_plan,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_sf_machine_table_tool_changing_apply_group_plan_dispatch,sf.machine.table.tool.changing.apply,model_sf_machine_table_tool_changing_apply,sf_base.group_plan_dispatch,1,0,0,0
|
||||
|
||||
|
||||
access_sf_tool_change_requirement_information_group_plan_dispatch,sf.tool.change.requirement.information,model_sf_tool_change_requirement_information,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_sf_tool_transfer_request_information_group_plan_dispatch,sf.tool.transfer.request.information,model_sf_tool_transfer_request_information,sf_base.group_plan_dispatch,1,0,0,0
|
||||
|
||||
access_sf_functional_tool_assembly_group_plan_dispatch,sf.functional.tool.assembly,model_sf_functional_tool_assembly,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_sf_functional_tool_assembly_order_group_plan_dispatch,sf.functional.tool.assembly.order,model_sf_functional_tool_assembly_order,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_sf_tool_material_search_group_plan_dispatch,sf.tool.material.search,model_sf_tool_material_search,sf_base.group_plan_dispatch,1,0,0,0
|
||||
|
||||
|
||||
|
||||
|
||||
|
32
sf_tool_management/views/sf_maintenance_equipment.xml
Normal file
32
sf_tool_management/views/sf_maintenance_equipment.xml
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<!-- 设备增加刀具库位table-->
|
||||
<record id="sf_maintenance_equipment_tool_view_form" model="ir.ui.view">
|
||||
<field name="name">sf_manufacturing_equipment.form</field>
|
||||
<field name="model">maintenance.equipment</field>
|
||||
<field name="inherit_id" ref="sf_manufacturing.sf_manufacturing_hr_equipment_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//page[@name='sf_equipment_product_template']" position="replace">
|
||||
<page string="标准刀库" name="sf_equipment_product_template"
|
||||
attrs="{'invisible': [('equipment_type', '!=', '机床')]}">
|
||||
<field name='product_template_ids'>
|
||||
<tree editable='bottom'>
|
||||
<field name="code"/>
|
||||
<field name="tool_code"/>
|
||||
<field name="functional_tool_type"/>
|
||||
<field name="functional_tool_name_id"/>
|
||||
<field name="image" widget="image"/>
|
||||
<field name="tool_groups"/>
|
||||
<field name="diameter"/>
|
||||
<field name="knife_tip_r_angle"/>
|
||||
<field name="life_value_max"/>
|
||||
<field name="alarm_value"/>
|
||||
<field name="used_value"/>
|
||||
<field name="tool_install_time"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -43,7 +43,7 @@
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button class="oe_stat_button"
|
||||
<button class="oe_stat_button" groups="sf_base.group_sf_mrp_user"
|
||||
name="open_functional_tool_warning"
|
||||
icon="fa-list-ul"
|
||||
type="object">
|
||||
@@ -53,7 +53,7 @@
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
<button class="oe_stat_button"
|
||||
<button class="oe_stat_button" groups="sf_base.group_sf_mrp_user"
|
||||
name="open_stock_move_line"
|
||||
icon="fa-list-ul"
|
||||
type="object">
|
||||
@@ -63,7 +63,7 @@
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
<button class="oe_stat_button"
|
||||
<button class="oe_stat_button" groups="sf_base.group_sf_mrp_user"
|
||||
name="open_safety_stock"
|
||||
icon="fa-list-ul"
|
||||
type="object">
|
||||
@@ -287,7 +287,7 @@
|
||||
<field name="name">功能刀具安全库存</field>
|
||||
<field name="model">sf.real.time.distribution.of.functional.tools</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree create="1" edit="1" delete="0">
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="sf_cutting_tool_type_id" invisible="True"/>
|
||||
<field name="tool_groups_id"/>
|
||||
@@ -310,7 +310,7 @@
|
||||
<field name="name">功能刀具安全库存</field>
|
||||
<field name="model">sf.real.time.distribution.of.functional.tools</field>
|
||||
<field name="arch" type="xml">
|
||||
<form create="0" edit="1" delete="0">
|
||||
<form>
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<h1>
|
||||
@@ -552,7 +552,7 @@
|
||||
'default_replacement_effective_length': effective_length,
|
||||
}"
|
||||
attrs="{'invisible': [('status', '!=', '0')]}"
|
||||
class="btn-primary"
|
||||
class="btn-primary" groups="sf_base.group_sf_mrp_user"
|
||||
/>
|
||||
<button string="转移"
|
||||
name="%(sf_tool_management.sf_tool_transfer_request_information_act)d"
|
||||
@@ -578,13 +578,13 @@
|
||||
'default_extension_length': extension_length,
|
||||
'default_effective_length': effective_length,
|
||||
}"
|
||||
class="btn-primary"
|
||||
class="btn-primary" groups="sf_base.group_sf_mrp_user"
|
||||
attrs="{'invisible': ['|',('status', '!=', '0'), ('functional_tool_name_id', '=', False)]}"
|
||||
/>
|
||||
<button string="撤回换刀申请" name="revocation_1" type="object" class="btn-primary"
|
||||
attrs="{'invisible': [('status', '!=', '1')]}" confirm="是否确认撤回换刀申请"/>
|
||||
attrs="{'invisible': [('status', '!=', '1')]}" groups="sf_base.group_sf_mrp_user" confirm="是否确认撤回换刀申请"/>
|
||||
<button string="撤回转移" name="revocation_2" type="object" class="btn-primary"
|
||||
attrs="{'invisible': [('status', '!=', '2')]}" confirm="是否确认撤回转移"/>
|
||||
attrs="{'invisible': [('status', '!=', '2')]}" groups="sf_base.group_sf_mrp_user" confirm="是否确认撤回转移"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -630,7 +630,7 @@
|
||||
'default_replacement_effective_length': effective_length,
|
||||
}"
|
||||
attrs="{'invisible': [('status', '!=', '0')]}"
|
||||
class="btn-primary"
|
||||
class="btn-primary" groups="sf_base.group_sf_mrp_user"
|
||||
/>
|
||||
<button string="转移"
|
||||
name="%(sf_tool_management.sf_tool_transfer_request_information_act)d"
|
||||
@@ -654,11 +654,11 @@
|
||||
'default_extension_length': extension_length,
|
||||
'default_effective_length': effective_length,
|
||||
}"
|
||||
class="btn-primary"
|
||||
class="btn-primary" groups="sf_base.group_sf_mrp_user"
|
||||
attrs="{'invisible': ['|',('status', '!=', '0'),('functional_tool_name_id', '=', False)]}"/>
|
||||
<button string="撤回换刀申请" name="revocation_1" type="object" class="btn-primary"
|
||||
attrs="{'invisible': [('status', '!=', '1')]}" confirm="是否确认撤回换刀申请"/>
|
||||
<button string="撤回转移" name="revocation_2" type="object" class="btn-primary"
|
||||
attrs="{'invisible': [('status', '!=', '1')]}" groups="sf_base.group_sf_mrp_user" confirm="是否确认撤回换刀申请"/>
|
||||
<button string="撤回转移" name="revocation_2" type="object" groups="sf_base.group_sf_mrp_user" class="btn-primary"
|
||||
attrs="{'invisible': [('status', '!=', '2')]}" confirm="是否确认撤回转移"/>
|
||||
</header>
|
||||
<field name="functional_tool_status" string="状态" invisible="True"/>
|
||||
@@ -756,21 +756,29 @@
|
||||
<tree>
|
||||
<field name="name" string="工单编码"/>
|
||||
<field name="cam_procedure_code"/>
|
||||
<field name="filename"/>
|
||||
<field name="functional_tool_name" string="刀具名称"/>
|
||||
<field name="cam_cutter_spacing_code"/>
|
||||
<field name="diameter" optional="hide"/>
|
||||
<field name="tool_included_angle" optional="hide"/>
|
||||
<field name="process_type"/>
|
||||
<field name="margin_x_y"/>
|
||||
<field name="margin_z"/>
|
||||
<field name="finish_depth"/>
|
||||
<field name="extension_length" string="刀具伸出长度(mm)"/>
|
||||
<field name="shank_model"/>
|
||||
<field name="estimated_processing_time"/>
|
||||
<field name="need_knife_time"/>
|
||||
<field name="applicant_time"/>
|
||||
<field name="plan_execute_status"/>
|
||||
|
||||
<field name="production_line_id" invisible="1"/>
|
||||
<field name="machine_table_name_id" invisible="1"/>
|
||||
<field name="machine_table_name"/>
|
||||
<field name="functional_tool_name"/>
|
||||
<field name="diameter"/>
|
||||
<field name="tool_included_angle"/>
|
||||
<field name="need_knife_time"/>
|
||||
<field name="applicant"/>
|
||||
<field name="applicant_time"/>
|
||||
<field name="plan_execute_status" invisible="0"/>
|
||||
<!-- <button string="申请装刀" name="apply_for_tooling" type="object" class="btn-primary"-->
|
||||
<!-- attrs="{'invisible': [('plan_execute_status', '!=', '0')]}" confirm="是否确认申请装刀"/>-->
|
||||
<!-- <button string="撤回" name="revocation" type="object" class="btn-primary"-->
|
||||
<!-- attrs="{'invisible': [('plan_execute_status', '!=', '1')]}" confirm="是否确认撤回装刀"/>-->
|
||||
<field name="machine_table_name" invisible="1"/>
|
||||
<button string="申请装刀" name="apply_for_tooling" type="object" class="btn-primary"
|
||||
attrs="{'invisible': [('plan_execute_status', '!=', '0')]}" confirm="是否确认申请装刀"/>
|
||||
<button string="撤回" name="revocation" type="object" class="btn-primary"
|
||||
attrs="{'invisible': [('plan_execute_status', '!=', '1')]}" confirm="是否确认撤回装刀"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -780,13 +788,13 @@
|
||||
<field name="model">sf.cam.work.order.program.knife.plan</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<!-- <header>-->
|
||||
<!-- <button string="申请装刀" name="apply_for_tooling" type="object" class="btn-primary"-->
|
||||
<!-- attrs="{'invisible': [('plan_execute_status', '!=', '0')]}" confirm="是否确认申请装刀"/>-->
|
||||
<!-- <button string="撤回" name="revocation" type="object" class="btn-primary"-->
|
||||
<!-- attrs="{'invisible': [('plan_execute_status', '!=', '1')]}" confirm="是否确认撤回装刀"/>-->
|
||||
<!-- <field name="plan_execute_status" widget="statusbar" statusbar_visible="0,1,2"/>-->
|
||||
<!-- </header>-->
|
||||
<header>
|
||||
<button string="申请装刀" name="apply_for_tooling" type="object" class="btn-primary"
|
||||
attrs="{'invisible': [('plan_execute_status', '!=', '0')]}" confirm="是否确认申请装刀"/>
|
||||
<button string="撤回" name="revocation" type="object" class="btn-primary"
|
||||
attrs="{'invisible': [('plan_execute_status', '!=', '1')]}" confirm="是否确认撤回装刀"/>
|
||||
<field name="plan_execute_status" widget="statusbar" statusbar_visible="0,1,2"/>
|
||||
</header>
|
||||
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
@@ -797,35 +805,48 @@
|
||||
<group>
|
||||
<group>
|
||||
<field name="cam_procedure_code"/>
|
||||
<field name="filename"/>
|
||||
<field name="production_line_id"/>
|
||||
<field name="machine_table_name_id" string="机台号"/>
|
||||
<field name="cam_cutter_spacing_code"/>
|
||||
<field name="tool_position_interface_type" placeholder="请选择"/>
|
||||
<field name="production_line_id" placeholder="请选择"/>
|
||||
<field name="machine_table_name_id" placeholder="请选择"/>
|
||||
<field name="machine_table_name"/>
|
||||
<field name="cutter_spacing_code_id" placeholder="请选择"/>
|
||||
<field name="whether_standard_knife"/>
|
||||
<field name="need_knife_time"/>
|
||||
<field name="applicant"/>
|
||||
<field name="applicant_time"/>
|
||||
<field name="reason_for_applying"/>
|
||||
<field name="tool_position_interface_type"/>
|
||||
<field name="sf_functional_tool_assembly_id" string="组装单"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="barcode_id" invisible="1"/>
|
||||
<field name="process_type"/>
|
||||
<field name="margin_x_y"/>
|
||||
<field name="margin_z"/>
|
||||
<field name="finish_depth"/>
|
||||
<field name="estimated_processing_time"/>
|
||||
<field name="need_knife_time"/>
|
||||
<field name="applicant_time"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="刀具信息">
|
||||
<group>
|
||||
<group>
|
||||
<field name="functional_tool_name"/>
|
||||
<field name="functional_tool_type_id" placeholder="请选择"/>
|
||||
<field name="functional_tool_type_id"/>
|
||||
<field name="tool_groups_id"/>
|
||||
<field name="diameter"/>
|
||||
<field name="tool_included_angle"/>
|
||||
<field name="new_former"/>
|
||||
<field name="coarse_middle_thin"/>
|
||||
<field name="whether_standard_knife"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="shank_model"/>
|
||||
<field name="tool_loading_length"/>
|
||||
<field name="extension_length"/>
|
||||
<field name="effective_length"/>
|
||||
<field name="new_former"/>
|
||||
<field name="coarse_middle_thin"/>
|
||||
<field name="required_cutting_time"/>
|
||||
<field name="L_D"/>
|
||||
<field name="clearance_length"/>
|
||||
<field name="required_cutting_time"/>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
@@ -837,20 +858,25 @@
|
||||
<search>
|
||||
<field name="name" string="工单编码"/>
|
||||
<field name="cam_procedure_code"/>
|
||||
<field name="filename"/>
|
||||
<field name="functional_tool_name" string="刀具名称"/>
|
||||
<field name="cam_cutter_spacing_code"/>
|
||||
<field name="machine_table_name_id" invisible="1"/>
|
||||
<field name="production_line_id" invisible="1"/>
|
||||
<field name="machine_table_name"/>
|
||||
<field name="functional_tool_name"/>
|
||||
<field name="diameter"/>
|
||||
<field name="tool_included_angle"/>
|
||||
<field name="diameter" optional="hide"/>
|
||||
<field name="tool_included_angle" optional="hide"/>
|
||||
<field name="process_type"/>
|
||||
<field name="margin_x_y"/>
|
||||
<field name="margin_z"/>
|
||||
<field name="finish_depth"/>
|
||||
<field name="extension_length" string="刀具伸出长度(mm)"/>
|
||||
<field name="shank_model"/>
|
||||
<field name="estimated_processing_time"/>
|
||||
<field name="need_knife_time"/>
|
||||
<field name="applicant"/>
|
||||
<field name="applicant_time"/>
|
||||
<field name="plan_execute_status" invisible="0"/>
|
||||
<field name="plan_execute_status"/>
|
||||
<searchpanel>
|
||||
<field name="production_line_id" string="生产线" enable_counters="1" icon="fa-filter"/>
|
||||
<field name="machine_table_name_id" string="CNC机床" enable_counters="1" icon="fa-filter"/>
|
||||
<field name="functional_tool_type_id" string="功能刀具类型" enable_counters="1"
|
||||
icon="fa-filter"/>
|
||||
</searchpanel>
|
||||
</search>
|
||||
</field>
|
||||
@@ -920,9 +946,9 @@
|
||||
'default_use_tool_time':use_tool_time,
|
||||
'default_reason_for_applying':reason_for_applying,
|
||||
}"
|
||||
attrs="{'invisible': [('assemble_status', '!=', '0')]}"
|
||||
attrs="{'invisible': [('assemble_status', '!=', '0')]}" groups="sf_base.group_sf_mrp_user"
|
||||
class="btn-primary"/>
|
||||
<button string="组装单打印" name="assemble_single_print" type="object"
|
||||
<button string="组装单打印" name="assemble_single_print" type="object" groups="sf_base.group_sf_mrp_user"
|
||||
attrs="{'invisible': [('assemble_status', '=', '0')]}" class="btn-primary"
|
||||
confirm="是否确认打印组装单"/>
|
||||
</tree>
|
||||
@@ -937,7 +963,7 @@
|
||||
<header>
|
||||
<button string="组装"
|
||||
name="%(sf_tool_management.sf_functional_tool_assembly_order_act)d"
|
||||
type="action"
|
||||
type="action" groups="sf_base.group_sf_mrp_user"
|
||||
context="{'default_name':name,
|
||||
'default_assembly_order_code':assembly_order_code,
|
||||
'default_production_line_name_id':production_line_name_id,
|
||||
@@ -960,10 +986,10 @@
|
||||
attrs="{'invisible': [('assemble_status', '!=', '0')]}"
|
||||
class="btn-primary"/>
|
||||
|
||||
<button string="打印二维码" name="automatic_printing_of_QR_code" type="object"
|
||||
<button string="打印二维码" name="automatic_printing_of_QR_code" type="object" groups="sf_base.group_sf_mrp_user"
|
||||
attrs="{'invisible': [('assemble_status', '=', '0')]}" class="btn-primary"
|
||||
confirm="是否确认打印二维码"/>
|
||||
<button string="组装单打印" name="assemble_single_print" type="object"
|
||||
<button string="组装单打印" name="assemble_single_print" type="object" groups="sf_base.group_sf_mrp_user"
|
||||
attrs="{'invisible': [('assemble_status', '=', '0')]}" class="btn-primary"
|
||||
confirm="是否确认打印组装单"/>
|
||||
<field name="assemble_status" widget="statusbar" statusbar_visible="0,1"/>
|
||||
|
||||
@@ -41,7 +41,7 @@ class ToolChangeRequirementInformation(models.TransientModel):
|
||||
replacement_tool_setting_length = fields.Float(string='待换刀具总长度(mm)', required=True)
|
||||
replacement_extension_length = fields.Float(string='待换刀具伸出长(mm)')
|
||||
replacement_effective_length = fields.Float(string='待换刀具有效长(mm)')
|
||||
replacement_tool_coarse_middle_thin = fields.Selection([("1", "粗"), ('2', '中'), ('3', '精')], requirded=True,
|
||||
replacement_tool_coarse_middle_thin = fields.Selection([("1", "粗"), ('2', '中'), ('3', '精')], required=True,
|
||||
string='待换刀具粗/中/精', default='3')
|
||||
|
||||
replacement_max_lifetime_value = fields.Integer(string='待换刀具最大寿命值(min)')
|
||||
|
||||
@@ -305,8 +305,8 @@ class ShelfLocation(models.Model):
|
||||
"""
|
||||
for record in self:
|
||||
if record.product_sn_id:
|
||||
record.product_id = record.product_sn_id.product_id
|
||||
record.location_status = '占用'
|
||||
record.sudo().product_id = record.product_sn_id.product_id
|
||||
record.sudo().location_status = '占用'
|
||||
else:
|
||||
record.product_id = False
|
||||
# record.location_status = '空闲'
|
||||
@@ -318,12 +318,12 @@ class ShelfLocation(models.Model):
|
||||
:return:
|
||||
"""
|
||||
for record in self:
|
||||
record.hide_shelf = False
|
||||
record.hide_location = False
|
||||
record.sudo().hide_shelf = False
|
||||
record.sudo().hide_location = False
|
||||
if record.location_type and record.location_type == '货架':
|
||||
record.hide_shelf = True
|
||||
record.sudo().hide_shelf = True
|
||||
elif record.location_type and record.location_type == '货位':
|
||||
record.hide_location = True
|
||||
record.sudo().hide_location = True
|
||||
else:
|
||||
pass
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ access_stock_lot_label_layout_user,lot.label.layout.user,stock.model_lot_label_l
|
||||
access_stock_replenish_option,stock.replenishment.option,stock.model_stock_replenishment_option,sf_warehouse.group_sf_stock_user,1,1,1,0
|
||||
access_mrp_production,mrp.production,mrp.model_mrp_production,sf_warehouse.group_sf_stock_user,1,1,1,0
|
||||
|
||||
access_sf_shelf_location_group_plan_dispatch,sf.shelf.location,model_sf_shelf_location,sf_base.group_plan_dispatch,1,1,0,0
|
||||
access_sf_shelf_location_group_plan_dispatch,sf.shelf.location,model_sf_shelf_location,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_stock_move,stock.move,stock.model_stock_move,sf_base.group_plan_dispatch,1,1,1,0
|
||||
access_stock_picking,stock.picking,stock.model_stock_picking,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_stock_lot_group_plan_dispatch,stock.lot,stock.model_stock_lot,sf_base.group_plan_dispatch,1,0,0,0
|
||||
|
||||
|
@@ -52,7 +52,7 @@
|
||||
}
|
||||
|
||||
.green {
|
||||
background-color: #fff !important;
|
||||
background-color: #27FEA9 !important;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
|
||||
@@ -91,5 +91,19 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="sf_vpicktree" model="ir.ui.view">
|
||||
<field name="name">sf.vpicktree</field>
|
||||
<field name="model">stock.picking</field>
|
||||
<field name="inherit_id" ref="stock.vpicktree"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//header//button[@name='do_unreserve']" position="replace">
|
||||
<button name="do_unreserve" type="object" string="取消保留" groups="sf_warehouse.group_sf_stock_user"/>
|
||||
</xpath>
|
||||
<xpath expr="//header//button[@name='action_assign']" position="replace">
|
||||
<button name="action_assign" type="object" string="检查可用量" groups="sf_warehouse.group_sf_stock_user"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
Reference in New Issue
Block a user