Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/优化agv和ftp
# Conflicts: # sf_manufacturing/models/mrp_production.py # sf_manufacturing/models/mrp_workorder.py # sf_mrs_connect/models/ftp_operate.py # sf_sale/models/quick_easy_order_old.py
This commit is contained in:
@@ -57,6 +57,8 @@ class MrpProduction(models.Model):
|
||||
production_line_state = fields.Selection([('待上产线', '待上产线'), ('已上产线', '已上产线'), ('已下产线', '已下产线')],
|
||||
string='上/下产线', default='待上产线')
|
||||
|
||||
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')
|
||||
@@ -132,6 +134,14 @@ class MrpProduction(models.Model):
|
||||
# cnc程序获取
|
||||
def fetchCNC(self):
|
||||
cnc = self.env['mrp.production'].search([('id', '=', self.id)])
|
||||
quick_order = self.env['quick.easy.order'].search([('id', '=', cnc.product_id.id)])
|
||||
programme_way = False
|
||||
if cnc.manual_quotation is True:
|
||||
programme_way = 'manual operation'
|
||||
else:
|
||||
programme_way = 'auto'
|
||||
if quick_order:
|
||||
programme_way = 'manual operation'
|
||||
try:
|
||||
res = {'model_code': '' if not cnc.product_id.model_code else cnc.product_id.model_code,
|
||||
'production_no': cnc.name,
|
||||
@@ -146,8 +156,9 @@ class MrpProduction(models.Model):
|
||||
'embryo_height': cnc.product_id.bom_ids.bom_line_ids.product_id.height,
|
||||
'embryo_width': cnc.product_id.bom_ids.bom_line_ids.product_id.width,
|
||||
'order_no': cnc.origin,
|
||||
'model_order_no': '-'.join(cnc.product_id.default_code.split('-')[:4]),
|
||||
'model_order_no': cnc.product_id.default_code,
|
||||
'user': cnc.env.user.name,
|
||||
'programme_way': programme_way,
|
||||
'model_file': '' if not cnc.product_id.model_file else base64.b64encode(
|
||||
cnc.product_id.model_file).decode('utf-8')
|
||||
}
|
||||
|
||||
@@ -46,6 +46,8 @@ class ResMrpWorkOrder(models.Model):
|
||||
], string="工序类型")
|
||||
results = fields.Char('结果')
|
||||
|
||||
manual_quotation = fields.Boolean('人工编程', default=False, readonly=True)
|
||||
|
||||
@api.onchange('users_ids')
|
||||
def get_user_permissions(self):
|
||||
uid = self.env.uid
|
||||
@@ -364,6 +366,7 @@ class ResMrpWorkOrder(models.Model):
|
||||
y7 = self.Y7_axis
|
||||
y8 = self.Y8_axis
|
||||
z1 = self.Z9_axis
|
||||
z2 = self.Z10_axis
|
||||
x0 = ((x3 - x4) * (x2 * y1 - x1 * y2) - (x1 - x2) * (x4 * y3 - x3 * y4)) / (
|
||||
(x3 - x4) * (y1 - y2) - (x1 - x2) * (y3 - y4))
|
||||
y0 = ((y3 - y4) * (y2 * x1 - y1 * x2) - (y1 - y2) * (y4 * x3 - y3 * x4)) / (
|
||||
@@ -374,7 +377,7 @@ class ResMrpWorkOrder(models.Model):
|
||||
(y7 - y8) * (x5 - x6) - (y5 - y6) * (x7 - x8))
|
||||
x = (x0 + x1) / 2
|
||||
y = (y0 + y1) / 2
|
||||
z = z1 / 2
|
||||
z = (z1 + z2) / 2
|
||||
|
||||
jd = math.atan2((x5 - x6), (y5 - y6))
|
||||
jdz = jd * 180 / math.pi
|
||||
@@ -815,7 +818,7 @@ class ResMrpWorkOrder(models.Model):
|
||||
production_no_ftp = reportpath.split('/')
|
||||
production_no = workorder.production_id.name.replace('/', '_')
|
||||
# ftp地址
|
||||
remotepath = os.path.join('/NC/', production_no_ftp[1], 'detection')
|
||||
remotepath = os.path.join('/NC', production_no_ftp[1], 'detection')
|
||||
logging.info('ftp地址:%s' % remotepath)
|
||||
if reportpath.find(production_no) != -1:
|
||||
# 服务器内临时地址
|
||||
@@ -894,7 +897,7 @@ class CNCprocessing(models.Model):
|
||||
'cutting_tool_handle_type': obj['cutting_tool_handle_type'],
|
||||
'estimated_processing_time': obj['estimated_processing_time'],
|
||||
'remark': obj['remark'],
|
||||
'program_path': program_path.replace('/tmp', '')
|
||||
'program_path': program_path.replace('/tmp', '/home/ftp/ftp_root/NC')
|
||||
})
|
||||
cnc_processing.get_cnc_processing_file(program_path_tmp, cnc_processing, program_path)
|
||||
# cnc_workorder.state = 'done'
|
||||
@@ -933,7 +936,7 @@ class CNCprocessing(models.Model):
|
||||
|
||||
# 将FTP的nc文件下载到临时目录
|
||||
def download_file_tmp(self, production_no, processing_panel):
|
||||
remotepath = os.path.join('/NC/', production_no, 'return', processing_panel)
|
||||
remotepath = os.path.join('/NC', production_no, 'return', processing_panel)
|
||||
serverdir = os.pat.join('/tmp', production_no, 'return', processing_panel)
|
||||
ftp_resconfig = self.env['res.config.settings'].get_values()
|
||||
ftp = FtpController(str(ftp_resconfig['ftp_host']), int(ftp_resconfig['ftp_port']), ftp_resconfig['ftp_user'],
|
||||
@@ -986,15 +989,16 @@ class SfWorkOrderBarcodes(models.Model):
|
||||
workorder = self.env['mrp.workorder'].browse(self.ids)
|
||||
# workorder = self.env['mrp.workorder'].search(
|
||||
# [('routing_type', '=', '装夹预调'), ('production_id', '=', self.production_id.id)])
|
||||
# workorder_old = self.env['mrp.workorder'].search([('rfid_code', '=', barcode)])
|
||||
# if workorder_old:
|
||||
# raise UserError('该托盘已绑定工件,请先解除绑定!!!')
|
||||
workorder_old = self.env['mrp.workorder'].search([('rfid_code', '=', barcode)])
|
||||
if workorder_old:
|
||||
raise UserError('该托盘已绑定工件,请先解除绑定!!!')
|
||||
if workorder:
|
||||
if workorder.routing_type == '装夹预调':
|
||||
if workorder.state in ['progress', 'done']:
|
||||
work_state = {'progress': '进行中', 'done': '已完工'}
|
||||
raise UserError('该工单%s,不能重新绑定托盘' % work_state.get(workorder.state))
|
||||
if workorder.state in ['done']:
|
||||
work_state = {'done': '已完工'}
|
||||
raise UserError('装夹%s,请勿重复扫码' % work_state.get(workorder.state))
|
||||
lots = self.env['stock.lot'].sudo().search([('rfid', '=', barcode)])
|
||||
logging.info("托盘信息:%s" % lots)
|
||||
if lots:
|
||||
for lot in lots:
|
||||
if lot.product_id.categ_type == '夹具':
|
||||
@@ -1013,6 +1017,7 @@ class SfWorkOrderBarcodes(models.Model):
|
||||
if workorder_rfid:
|
||||
for item in workorder_rfid:
|
||||
item.write({'rfid_code': barcode})
|
||||
logging.info("Rfid绑定成功!!!")
|
||||
else:
|
||||
embryo_stock_lot = self.env['stock.lot'].search([('name', '=', barcode)])
|
||||
if embryo_stock_lot:
|
||||
|
||||
@@ -10,7 +10,6 @@ from odoo.modules import get_resource_path
|
||||
# from OCC.Extend.DataExchange import write_stl_file
|
||||
|
||||
|
||||
|
||||
class ResProductMo(models.Model):
|
||||
_inherit = 'product.template'
|
||||
|
||||
@@ -522,6 +521,9 @@ class ResProductMo(models.Model):
|
||||
string='注册状态', default='未注册')
|
||||
industry_code = fields.Char('行业编码', readonly=True)
|
||||
|
||||
# bfm下单
|
||||
manual_quotation = fields.Boolean('人工编程', default=False, readonly=True)
|
||||
|
||||
@api.constrains('tool_length')
|
||||
def _check_tool_length_size(self):
|
||||
if self.tool_length > 1000000:
|
||||
@@ -616,6 +618,7 @@ class ResProductMo(models.Model):
|
||||
'process_parameters_code') else self.get_process_parameters_id(item['process_parameters_code']),
|
||||
'model_remark': item['remark'],
|
||||
'default_code': '%s-%s' % (order_number, i),
|
||||
'manual_quotation': item['manual_quotation'] or False,
|
||||
'active': True,
|
||||
}
|
||||
copy_product_id.sudo().write(vals)
|
||||
|
||||
@@ -317,13 +317,15 @@ class ProductionLot(models.Model):
|
||||
"""
|
||||
now = datetime.now().strftime("%Y%m%d")
|
||||
last_serial = self.env['stock.lot'].search(
|
||||
[('company_id', '=', company.id), ('product_id', '=', product.id), ('name', 'like', now)],
|
||||
[('company_id', '=', company.id), ('product_id', '=', product.id)],
|
||||
limit=1, order='id DESC')
|
||||
if product.cutting_tool_model_id:
|
||||
split_codes = product.cutting_tool_model_id.code.split('-')
|
||||
if not last_serial:
|
||||
return "%s-%s%03d" % (product.cutting_tool_model_id.code[:-12], now, 1)
|
||||
return "%s-T-%s-%s-%03d" % (split_codes[0], now, product.specification_id.name, 1)
|
||||
else:
|
||||
return "%s-%s%03d" % (product.cutting_tool_model_id.code[:-12], now, int(last_serial.name[-3:]) + 1)
|
||||
return "%s-T-%s-%s-%03d" % (
|
||||
split_codes[0], now, product.specification_id.name, int(last_serial.name[-3:]) + 1)
|
||||
else:
|
||||
raise ValidationError('该刀具物料产品的型号字段为空,请补充完整!!!')
|
||||
|
||||
@@ -341,7 +343,8 @@ class ProductionLot(models.Model):
|
||||
return self.env['stock.lot'].generate_lot_names1(product.name, last_serial.name, 2)[1]
|
||||
now = datetime.now().strftime("%Y%m%d")
|
||||
if product.cutting_tool_model_id:
|
||||
return "%s-%s%03d" % (product.cutting_tool_model_id.code[:-12], now, 1)
|
||||
split_codes = product.cutting_tool_model_id.code.split('-')
|
||||
return "%s-T-%s-%s-%03d" % (split_codes[0], now, product.specification_id.name, 1)
|
||||
return "%s-%03d" % (product.name, 1)
|
||||
|
||||
qr_code_image = fields.Binary(string='二维码', compute='_generate_qr_code')
|
||||
@@ -539,6 +542,65 @@ class ReStockMove(models.Model):
|
||||
else:
|
||||
raise UserError(_("没有可打印的标签数据"))
|
||||
|
||||
def action_show_details(self):
|
||||
""" Returns an action that will open a form view (in a popup) allowing to work on all the
|
||||
move lines of a particular move. This form view is used when "show operations" is not
|
||||
checked on the picking type.
|
||||
"""
|
||||
self.ensure_one()
|
||||
|
||||
# If "show suggestions" is not checked on the picking type, we have to filter out the
|
||||
# reserved move lines. We do this by displaying `move_line_nosuggest_ids`. We use
|
||||
# different views to display one field or another so that the webclient doesn't have to
|
||||
# fetch both.
|
||||
if self.picking_type_id.show_reserved:
|
||||
view = self.env.ref('stock.view_stock_move_operations')
|
||||
else:
|
||||
view = self.env.ref('stock.view_stock_move_nosuggest_operations')
|
||||
|
||||
if self.product_id.tracking == "serial" and self.state == "assigned":
|
||||
print(self.origin)
|
||||
if self.product_id.categ_id.name == '刀具':
|
||||
self.next_serial = self._get_tool_next_serial(self.company_id, self.product_id, self.origin)
|
||||
else:
|
||||
self.next_serial = self.env['stock.lot']._get_next_serial(self.company_id, self.product_id)
|
||||
|
||||
return {
|
||||
'name': _('Detailed Operations'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'stock.move',
|
||||
'views': [(view.id, 'form')],
|
||||
'view_id': view.id,
|
||||
'target': 'new',
|
||||
'res_id': self.id,
|
||||
'context': dict(
|
||||
self.env.context,
|
||||
show_owner=self.picking_type_id.code != 'incoming',
|
||||
show_lots_m2o=self.has_tracking != 'none' and (
|
||||
self.picking_type_id.use_existing_lots or self.state == 'done' or self.origin_returned_move_id.id),
|
||||
# able to create lots, whatever the value of ` use_create_lots`.
|
||||
show_lots_text=self.has_tracking != 'none' and self.picking_type_id.use_create_lots and not self.picking_type_id.use_existing_lots and self.state != 'done' and not self.origin_returned_move_id.id,
|
||||
show_source_location=self.picking_type_id.code != 'incoming',
|
||||
show_destination_location=self.picking_type_id.code != 'outgoing',
|
||||
show_package=not self.location_id.usage == 'supplier',
|
||||
show_reserved_quantity=self.state != 'done' and not self.picking_id.immediate_transfer and self.picking_type_id.code != 'incoming'
|
||||
),
|
||||
}
|
||||
|
||||
def _get_tool_next_serial(self, company, product, origin):
|
||||
"""Return the next serial number to be attributed to the product."""
|
||||
if product.tracking == "serial":
|
||||
last_serial = self.env['stock.lot'].search(
|
||||
[('company_id', '=', company.id), ('product_id', '=', product.id), ('name', 'ilike', origin)],
|
||||
limit=1, order='id DESC')
|
||||
split_codes = product.cutting_tool_model_id.code.split('-')
|
||||
if last_serial:
|
||||
return "%s-T-%s-%s-%03d" % (
|
||||
split_codes[0], origin, product.specification_id.name, int(last_serial.name[-3:]) + 1)
|
||||
else:
|
||||
return "%s-T-%s-%s-%03d" % (split_codes[0], origin, product.specification_id.name, 1)
|
||||
|
||||
|
||||
class ReStockQuant(models.Model):
|
||||
_inherit = 'stock.quant'
|
||||
|
||||
Reference in New Issue
Block a user