Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/优化工件配送
This commit is contained in:
@@ -47,7 +47,7 @@ class Manufacturing_Connect(http.Controller):
|
||||
logging.info('get_Work_Info error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
|
||||
@http.route('/AutoDeviceApi/GetShiftPlan', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||
@http.route('/AutoDeviceApi/GetShiftPlan', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def get_ShiftPlan(self, **kw):
|
||||
"""
|
||||
@@ -65,6 +65,7 @@ class Manufacturing_Connect(http.Controller):
|
||||
else:
|
||||
ProductionLine = False
|
||||
workorder_ids = request.env['mrp.workorder'].sudo().get_plan_workorder(ProductionLine)
|
||||
# todo 需要筛选出CNC工单
|
||||
logging.info('RfidCode:%s' % ret)
|
||||
logging.info('workorder_ids:%s' % workorder_ids)
|
||||
workorder = request.env['mrp.workorder'].sudo().search(workorder_ids)
|
||||
@@ -136,7 +137,7 @@ class Manufacturing_Connect(http.Controller):
|
||||
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,
|
||||
@http.route('/AutoDeviceApi/FeedBackStart', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def button_Work_START(self, **kw):
|
||||
"""
|
||||
@@ -179,7 +180,7 @@ class Manufacturing_Connect(http.Controller):
|
||||
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,
|
||||
@http.route('/AutoDeviceApi/FeedBackEnd', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def button_Work_End(self, **kw):
|
||||
"""
|
||||
@@ -203,6 +204,8 @@ class Manufacturing_Connect(http.Controller):
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '该工单未开始'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
workorder.button_finish()
|
||||
workorder.process_state = '待解除装夹'
|
||||
workorder.sudo().production_id.process_state = '待解除装夹'
|
||||
|
||||
# 根据工单的实际结束时间修改排程单的结束时间、状态,同时修改销售订单的状态
|
||||
if workorder.date_finished:
|
||||
@@ -221,7 +224,7 @@ class Manufacturing_Connect(http.Controller):
|
||||
logging.info('button_Work_End error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
|
||||
@http.route('/AutoDeviceApi/PartQualityInspect', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||
@http.route('/AutoDeviceApi/PartQualityInspect', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def PartQualityInspect(self, **kw):
|
||||
"""
|
||||
@@ -354,7 +357,7 @@ class Manufacturing_Connect(http.Controller):
|
||||
logging.info('NCProgDolod error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
|
||||
@http.route('/AutoDeviceApi/LocationChange', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||
@http.route('/AutoDeviceApi/LocationChange', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def LocationChange(self, **kw):
|
||||
"""
|
||||
@@ -375,47 +378,35 @@ class Manufacturing_Connect(http.Controller):
|
||||
NewPosition = ret['NewPosition']
|
||||
OldDeciveStart = ret['OldDeciveStart']
|
||||
OldDeciveEnd = ret['OldDeciveEnd']
|
||||
# Part、Tool
|
||||
if ChangeType == 'Part':
|
||||
workorder = request.env['mrp.workorder'].sudo().search(
|
||||
[('rfid_code', '=', RfidCode)], limit=1)
|
||||
if not workorder:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '未根据RfidCode找到该工单'}
|
||||
|
||||
temp_val_sn_id = None
|
||||
old_localtion = None
|
||||
if ChangeType == 'Part' or ChangeType == 'Tool':
|
||||
stock_lot_obj = request.env['stock.lot'].sudo().search(
|
||||
[('rfid', '=', RfidCode)], limit=1)
|
||||
if not stock_lot_obj:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '未根据RfidCode找到该产品'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
old_localtion = request.env['sf.shelf.location'].sudo().search(
|
||||
[('barcode', '=', OldPosition)], limit=1)
|
||||
if OldPosition:
|
||||
old_localtion = request.env['sf.shelf.location'].sudo().search(
|
||||
[('barcode', '=', OldPosition)], limit=1)
|
||||
new_localtion = request.env['sf.shelf.location'].sudo().search(
|
||||
[('barcode', '=', NewPosition)], limit=1)
|
||||
if not new_localtion:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '没有该目标位置'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
if old_localtion:
|
||||
old_localtion.location_status = '空闲'
|
||||
old_localtion.production_id = False
|
||||
new_localtion.location_status = '占用'
|
||||
new_localtion.production_id = workorder.production_id.id
|
||||
if ChangeType == 'Tool':
|
||||
old_localtion = request.env['sf.shelf.location'].sudo().search(
|
||||
[('barcode', '=', OldPosition)], limit=1)
|
||||
equipment_id = request.env['maintenance.equipment'].sudo().search(
|
||||
[('name', '=', NewPosition)], limit=1)
|
||||
equipment_id.register_equipment_tool()
|
||||
if not equipment_id:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '没有该目标位置'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
if old_localtion:
|
||||
old_localtion.location_status = '空闲'
|
||||
old_localtion.production_id = False
|
||||
|
||||
# return json.JSONEncoder().encode(res)
|
||||
# else:
|
||||
# res = {'Succeed': False, 'ErrorCode': 201, 'Error': '未传RfidCode字段'}
|
||||
temp_val_sn_id = old_localtion.product_sn_id
|
||||
old_localtion.product_sn_id = None
|
||||
new_localtion.product_sn_id = temp_val_sn_id
|
||||
else:
|
||||
new_localtion.product_sn_id = stock_lot_obj.id
|
||||
except Exception as e:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
|
||||
logging.info('LocationChange error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
|
||||
@http.route('/AutoDeviceApi/AGVToProduct', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||
@http.route('/AutoDeviceApi/AGVToProduct', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def AGVToProduct(self, **kw):
|
||||
"""
|
||||
@@ -456,7 +447,7 @@ class Manufacturing_Connect(http.Controller):
|
||||
logging.info('AGVToProduct error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
|
||||
@http.route('/AutoDeviceApi/AGVDownProduct', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||
@http.route('/AutoDeviceApi/AGVDownProduct', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def AGVDownProduct(self, **kw):
|
||||
"""
|
||||
@@ -496,7 +487,7 @@ class Manufacturing_Connect(http.Controller):
|
||||
logging.info('AGVDownProduct error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
|
||||
@http.route('/AutoDeviceApi/EquipmentBaseCoordinate', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||
@http.route('/AutoDeviceApi/EquipmentBaseCoordinate', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def PutEquipmentBaseCoordinate(self, **kw):
|
||||
"""
|
||||
|
||||
@@ -32,7 +32,9 @@ class MrpProduction(models.Model):
|
||||
('draft', 'Draft'),
|
||||
('confirmed', 'Confirmed'),
|
||||
('progress', '待排程'),
|
||||
('pending_cam', '待装夹'),
|
||||
('pending_processing', '待加工'),
|
||||
('pending_era_cam', '待解除装夹'),
|
||||
('completed', '已完工'),
|
||||
('to_close', 'To Close'),
|
||||
('done', 'Done'),
|
||||
@@ -54,15 +56,29 @@ class MrpProduction(models.Model):
|
||||
glb_file = fields.Binary("glb模型文件")
|
||||
production_line_id = fields.Many2one('sf.production.line', string='生产线')
|
||||
plan_start_processing_time = fields.Datetime('计划开始加工时间')
|
||||
production_line_state = fields.Selection(
|
||||
[('待上产线', '待上产线'), ('已上产线', '已上产线'), ('已下产线', '已下产线')],
|
||||
string='上/下产线', default='待上产线')
|
||||
production_line_state = fields.Selection([('待上产线', '待上产线'), ('已上产线', '已上产线'), ('已下产线', '已下产线')],
|
||||
string='上/下产线', default='待上产线')
|
||||
# 工序状态
|
||||
# Todo 研究下用法
|
||||
process_state = fields.Selection([
|
||||
('待装夹', '待装夹'),
|
||||
('待检测', '待检测'),
|
||||
('待加工', '待加工'),
|
||||
('待解除装夹', '待解除装夹'),
|
||||
('已完工', '已完工'),
|
||||
], string='工序状态', related='workorder_ids.process_state', store=True)
|
||||
|
||||
# 零件图号
|
||||
part_number = fields.Char('零件图号')
|
||||
|
||||
# 上传零件图纸
|
||||
part_drawing = fields.Binary('零件图纸')
|
||||
|
||||
manual_quotation = fields.Boolean('人工编程', default=False, readonly=True)
|
||||
|
||||
@api.depends(
|
||||
'move_raw_ids.state', 'move_raw_ids.quantity_done', 'move_finished_ids.state',
|
||||
'workorder_ids.state', 'product_qty', 'qty_producing', 'schedule_state')
|
||||
'workorder_ids.state', 'product_qty', 'qty_producing', 'schedule_state', 'process_state')
|
||||
def _compute_state(self):
|
||||
for production in self:
|
||||
if not production.state or not production.product_uom_id:
|
||||
@@ -94,11 +110,15 @@ class MrpProduction(models.Model):
|
||||
production.state = 'progress'
|
||||
|
||||
# 新添加的状态逻辑
|
||||
if production.state == 'progress' and production.schedule_state == '已排':
|
||||
if production.state == 'progress' and production.schedule_state == '已排' and production.process_state == '待装夹':
|
||||
# production.state = 'pending_processing'
|
||||
production.state = 'pending_cam'
|
||||
if production.state == 'progress' and production.schedule_state == '已排' and production.process_state == '待加工':
|
||||
# if production.state == 'pending_cam' and production.process_state == '待加工':
|
||||
production.state = 'pending_processing'
|
||||
# elif production.state == 'progress' and production.schedule_state == '已完成':
|
||||
# production.state = 'completed'
|
||||
elif production.state == 'pending_processing' and production.work_order_state == '已完成':
|
||||
elif production.state == 'progress' and production.process_state == '待解除装夹':
|
||||
production.state = 'pending_era_cam'
|
||||
elif production.state == 'progress' and production.process_state == '已完工':
|
||||
production.state = 'completed'
|
||||
elif production.state == 'progress' and production.work_order_state == '已完成':
|
||||
production.state = 'completed'
|
||||
|
||||
@@ -123,6 +123,23 @@ class ResMrpWorkOrder(models.Model):
|
||||
# 获取数据状态
|
||||
data_state = fields.Boolean(string='获取数据状态', default=False)
|
||||
|
||||
# 坯料长宽高
|
||||
material_length = fields.Float(string='长')
|
||||
material_width = fields.Float(string='宽')
|
||||
material_height = fields.Float(string='高')
|
||||
# 零件图号
|
||||
part_number = fields.Char(string='零件图号')
|
||||
# 工序状态
|
||||
process_state = fields.Selection([
|
||||
('待装夹', '待装夹'),
|
||||
('待检测', '待检测'),
|
||||
('待加工', '待加工'),
|
||||
('待解除装夹', '待解除装夹'),
|
||||
('已完工', '已完工'),
|
||||
], string='工序状态', default='待装夹')
|
||||
# 加工图纸
|
||||
processing_drawing = fields.Binary(string='加工图纸', related='production_id.part_drawing')
|
||||
|
||||
@api.depends('production_id')
|
||||
def _compute_save_name(self):
|
||||
"""
|
||||
@@ -390,7 +407,10 @@ class ResMrpWorkOrder(models.Model):
|
||||
work = workorder.production_id.workorder_ids
|
||||
work.compensation_value_x = eval(self.material_center_point)[0]
|
||||
work.compensation_value_y = eval(self.material_center_point)[1]
|
||||
work.process_state = '待加工'
|
||||
self.sudo().production_id.state = 'pending_processing'
|
||||
workorder.button_finish()
|
||||
|
||||
except Exception as e:
|
||||
# 重新抛出捕获到的异常信息
|
||||
raise UserError(str(e))
|
||||
@@ -696,6 +716,11 @@ class ResMrpWorkOrder(models.Model):
|
||||
'materiel_width': self.move_raw_ids[0].product_id.width,
|
||||
'materiel_height': self.move_raw_ids[0].product_id.height
|
||||
})
|
||||
self.write({
|
||||
'material_length': self.move_raw_ids[0].product_id.length,
|
||||
'material_width': self.move_raw_ids[0].product_id.width,
|
||||
'material_height': self.move_raw_ids[0].product_id.height
|
||||
})
|
||||
|
||||
self.ensure_one()
|
||||
if any(not time.date_end for time in self.time_ids.filtered(lambda t: t.user_id.id == self.env.user.id)):
|
||||
@@ -782,6 +807,7 @@ class ResMrpWorkOrder(models.Model):
|
||||
workorder.rfid_code = None
|
||||
for move_raw_id in self.production_id.move_raw_ids:
|
||||
move_raw_id.quantity_done = move_raw_id.product_uom_qty
|
||||
self.process_state = '已完工'
|
||||
self.production_id.button_mark_done1()
|
||||
# self.production_id.state = 'done'
|
||||
|
||||
@@ -1006,6 +1032,7 @@ class SfWorkOrderBarcodes(models.Model):
|
||||
for item in workorder_rfid:
|
||||
item.write({'rfid_code': barcode})
|
||||
logging.info("Rfid绑定成功!!!")
|
||||
self.process_state = '待检测'
|
||||
else:
|
||||
raise UserError('该托盘信息不存在!!!')
|
||||
# stock_move_line = self.env['stock.move.line'].search([('lot_name', '=', barcode)])
|
||||
|
||||
@@ -269,6 +269,13 @@ class ProductionLot(models.Model):
|
||||
rfid = fields.Char('Rfid', readonly=True)
|
||||
product_specification = fields.Char('规格', compute='_compute_product_specification', store=True)
|
||||
|
||||
def search_lot_put_rfid(self):
|
||||
# 使用SQL将所有刀柄Rfid不满十位的值在前方补零
|
||||
self.env.cr.execute(
|
||||
'''UPDATE stock_lot SET rfid = LPAD(rfid, 10, '0') WHERE rfid IS NOT NULL AND LENGTH(rfid) < 10'''
|
||||
)
|
||||
self.env.cr.commit()
|
||||
|
||||
@api.depends('product_id')
|
||||
def _compute_product_specification(self):
|
||||
for stock in self:
|
||||
|
||||
@@ -62,17 +62,32 @@
|
||||
<field name="inherit_id" ref="mrp.mrp_production_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='state']" position="attributes">
|
||||
<attribute name="statusbar_visible">draft,confirmed,progress,pending_processing,completed,done
|
||||
<!-- <attribute name="statusbar_visible">draft,confirmed,progress,pending_processing,completed,done -->
|
||||
<!-- </attribute> -->
|
||||
<attribute name="statusbar_visible">progress,pending_cam,pending_processing,pending_era_cam,completed,done
|
||||
</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='user_id']" position="after">
|
||||
|
||||
<xpath expr="//sheet//group//group[2]//label" position="before">
|
||||
<!-- <field name="process_state"/> -->
|
||||
<field name="state"/>
|
||||
<!-- <field name="process_state"/> -->
|
||||
|
||||
</xpath>
|
||||
<xpath expr="//sheet//group//group//div[3]" position="after">
|
||||
<field name="programming_no" readonly="1"/>
|
||||
<field name="work_state" invisible="1"/>
|
||||
<field name="schedule_state" invisible='1'/>
|
||||
<field name="programming_state" readonly="1"/>
|
||||
<field name="production_line_id" readonly="1"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='user_id']" position="before">
|
||||
<field name="plan_start_processing_time" readonly="1"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='user_id']" position="after">
|
||||
<field name="production_line_state" readonly="1"/>
|
||||
<field name="part_number"/>
|
||||
<field name="part_drawing"/>
|
||||
</xpath>
|
||||
<xpath expr="//header//button[@name='action_cancel']" position="replace">
|
||||
<button name="action_cancel" type="object" string="取消" data-hotkey="z"
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
<field name="product_id" position="after">
|
||||
<field name="equipment_id" optional="hide"/>
|
||||
</field>
|
||||
<xpath expr="//field[@name='qty_remaining']" position="after">
|
||||
<field name="manual_quotation" optional="show"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='date_planned_start']" position="replace">
|
||||
<field name="date_planned_start" string="计划开始日期" optional="show"/>
|
||||
</xpath>
|
||||
@@ -147,6 +150,7 @@
|
||||
</xpath>
|
||||
<xpath expr="//label[1]" position="before">
|
||||
<field name='routing_type'/>
|
||||
<field name='process_state'/>
|
||||
</xpath>
|
||||
<xpath expr="//label[1]" position="attributes">
|
||||
<attribute name="string">计划加工时间</attribute>
|
||||
@@ -173,6 +177,8 @@
|
||||
attrs="{'invisible': [('production_state','=', 'draft')], 'readonly': [('is_user_working', '=', True)]}"
|
||||
sum="real duration"/>
|
||||
<field name="glb_file" readonly="1" widget="Viewer3D" string="加工模型"/>
|
||||
<field name="manual_quotation" readonly="1"
|
||||
attrs="{'invisible': [('routing_type', '!=', 'CNC加工')]}"/>
|
||||
<field name="processing_panel" readonly="1"
|
||||
attrs='{"invisible": [("routing_type","in",("获取CNC加工程序","切割"))]}'/>
|
||||
<field name="equipment_id"
|
||||
@@ -262,6 +268,10 @@
|
||||
<field name="preset_program_information" colspan="2" nolabel="1"
|
||||
placeholder="如有预调程序信息请在此处输入....."/>
|
||||
</group>
|
||||
<group string="加工图纸">
|
||||
<!-- 隐藏加工图纸字段名 -->
|
||||
<field name="processing_drawing" widget="pdf_viewer" string=""/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="前置三元检测定位参数" attrs='{"invisible": [("routing_type","!=","装夹预调")]}'>
|
||||
|
||||
@@ -525,8 +535,19 @@
|
||||
<field name="is_ok"/>
|
||||
<field name="processing_user_id"/>
|
||||
<field name="inspection_user_id"/>
|
||||
<field name="save_name" widget="CopyClipboardChar"
|
||||
attrs="{'invisible':[('routing_type','!=','装夹预调')]}"/>
|
||||
<field name="save_name" widget="CopyClipboardChar" attrs="{'invisible':[('routing_type','!=','装夹预调')]}"/>
|
||||
<label for="material_length" string="物料尺寸"/>
|
||||
<div class="o_address_format">
|
||||
<label for="material_length" string="长"/>
|
||||
<field name="material_length" class="o_address_zip"/>
|
||||
<span>&nbsp;</span>
|
||||
<label for="material_width" string="宽"/>
|
||||
<field name="material_width" class="o_address_zip"/>
|
||||
<span>&nbsp;</span>
|
||||
<label for="material_height" string="高"/>
|
||||
<field name="material_height" class="o_address_zip"/>
|
||||
</div>
|
||||
<field name="part_number"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -19,6 +19,31 @@
|
||||
<xpath expr="//field[@name='product_id']" position="after">
|
||||
<field name="product_specification"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='qr_code_image']" position="after">
|
||||
<button name="search_lot_put_rfid" string="Rfid补零" type="object" invisible="1"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="search_product_lot_view" model="ir.ui.view">
|
||||
<field name="name">stock.production.lot.view</field>
|
||||
<field name="model">stock.lot</field>
|
||||
<field name="inherit_id" ref="stock.search_product_lot_filter"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='product_id']" position="after">
|
||||
<field name="rfid"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_production_lot_view_tree_tree" model="ir.ui.view">
|
||||
<field name="name">stock.production.lot.tree.inherit.product.expiry</field>
|
||||
<field name="model">stock.lot</field>
|
||||
<field name="inherit_id" ref="stock.view_production_lot_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='create_date']" position="after">
|
||||
<field name="rfid" invisible="1"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user