合并工单优化

This commit is contained in:
gqh
2023-01-11 11:13:52 +08:00
parent 01cf30b03f
commit eb162cb416
17 changed files with 350 additions and 386 deletions

View File

@@ -359,7 +359,7 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="机床"> <form string="机床">
<header> <header>
<button type="object" class="oe_highlight" name='enroll_machine_tool' string="机床注册"/> <button type="object" class="oe_highlight" name='enroll_machine_tool' string="机床注册" attrs="{'invisible': [('code','!=',False)]}"/>
</header> </header>
<group string="基本信息"> <group string="基本信息">
<group> <group>

View File

@@ -60,7 +60,7 @@ class Sf_Bf_Connect(http.Controller):
self_machining_embryo = request.env['product.template'].sudo().no_bom_product_create( self_machining_embryo = request.env['product.template'].sudo().no_bom_product_create(
self_machining_id, self_machining_id,
item, item,
order_id, 'self_machining', i) order_id, 'self_machining')
# 创建胚料的bom # 创建胚料的bom
self_machining_bom = request.env['mrp.bom'].with_user( self_machining_bom = request.env['mrp.bom'].with_user(
request.env.ref("base.user_admin")).bom_create( request.env.ref("base.user_admin")).bom_create(
@@ -79,8 +79,7 @@ class Sf_Bf_Connect(http.Controller):
outsource_embryo = request.env['product.template'].sudo().no_bom_product_create(outsource_id, outsource_embryo = request.env['product.template'].sudo().no_bom_product_create(outsource_id,
item, item,
order_id, order_id,
'subcontract', 'subcontract')
i)
# 创建胚料的bom # 创建胚料的bom
outsource_bom = request.env['mrp.bom'].with_user(request.env.ref("base.user_admin")).bom_create( outsource_bom = request.env['mrp.bom'].with_user(request.env.ref("base.user_admin")).bom_create(
outsource_embryo, outsource_embryo,
@@ -96,14 +95,14 @@ class Sf_Bf_Connect(http.Controller):
purchase_embryo = request.env['product.template'].sudo().no_bom_product_create(purchase_id, purchase_embryo = request.env['product.template'].sudo().no_bom_product_create(purchase_id,
item, item,
order_id, order_id,
'purchase', i) 'purchase')
# 产品配置bom # 产品配置bom
product_bom_purchase = request.env['mrp.bom'].with_user( product_bom_purchase = request.env['mrp.bom'].with_user(
request.env.ref("base.user_admin")).bom_create(product, 'normal', False) request.env.ref("base.user_admin")).bom_create(product, 'normal', False)
product_bom_purchase.with_user(request.env.ref("base.user_admin")).bom_create_line_has( product_bom_purchase.with_user(request.env.ref("base.user_admin")).bom_create_line_has(
purchase_embryo) purchase_embryo)
i += 1
order_id.with_user(request.env.ref("base.user_admin")).sale_order_create_line(product, item) order_id.with_user(request.env.ref("base.user_admin")).sale_order_create_line(product, item)
i += 1
res['factory_order_no'] = order_id.name res['factory_order_no'] = order_id.name
except Exception as e: except Exception as e:
logging.info('get_bfm_process_order_list error:%s' % e) logging.info('get_bfm_process_order_list error:%s' % e)

View File

@@ -10,10 +10,9 @@
""", """,
'category': 'sf', 'category': 'sf',
'website': 'https://www.sf.jikimo.com', 'website': 'https://www.sf.jikimo.com',
'depends': ['mrp', 'base', 'sf_manufacturing', 'purchase', 'mrp_subcontracting', 'uom'], 'depends': ['mrp', 'base', 'sf_manufacturing'],
'data': [ 'data': [
'data/product_data.xml', 'data/product_data.xml',
'data/uom_data.xml',
'views/product_template_view.xml' 'views/product_template_view.xml'
], ],
'demo': [ 'demo': [

View File

@@ -3,10 +3,9 @@ from odoo.exceptions import ValidationError
import logging import logging
import base64 import base64
import os import os
# from OCC.Extend.DataExchange import read_step_file, write_stl_file from OCC.Extend.DataExchange import read_step_file, write_stl_file
from odoo.modules import get_resource_path from odoo.modules import get_resource_path
class ResProductTemplate(models.Model): class ResProductTemplate(models.Model):
_inherit = 'product.template' _inherit = 'product.template'
@@ -17,11 +16,11 @@ class ResProductTemplate(models.Model):
model_height = fields.Float('模型高[mm]', digits=(16, 3)) model_height = fields.Float('模型高[mm]', digits=(16, 3))
model_volume = fields.Float('模型体积[m³]') model_volume = fields.Float('模型体积[m³]')
model_machining_precision = fields.Selection([ model_machining_precision = fields.Selection([
('0.10', '±0.10mm'), ('±0.10mm', '±0.10mm'),
('0.05', '±0.05mm'), ('±0.05mm', '±0.05mm'),
('0.03', '±0.03mm'), ('±0.03mm', '±0.03mm'),
('0.02', '±0.02mm'), ('±0.02mm', '±0.02mm'),
('0.01', '±0.01mm')], string='加工精度') ('±0.01mm', '±0.01mm')], string='加工精度')
model_type_id = fields.Many2one('sf.model.type', string='模型类型') model_type_id = fields.Many2one('sf.model.type', string='模型类型')
model_processing_panel = fields.Char('模型加工面板') model_processing_panel = fields.Char('模型加工面板')
model_surface_process_id = fields.Many2one('sf.production.process', string='表面工艺') model_surface_process_id = fields.Many2one('sf.production.process', string='表面工艺')
@@ -35,15 +34,6 @@ class ResProductTemplate(models.Model):
materials_type_id = fields.Many2one('sf.materials.model', string='材料型号') materials_type_id = fields.Many2one('sf.materials.model', string='材料型号')
single_manufacturing = fields.Boolean(string="单个制造") single_manufacturing = fields.Boolean(string="单个制造")
upload_model_file = fields.Many2many('ir.attachment', 'upload_model_file_attachment_ref', string='上传模型文件') upload_model_file = fields.Many2many('ir.attachment', 'upload_model_file_attachment_ref', string='上传模型文件')
model_code = fields.Char('模型编码')
def _get_volume_uom_id_from_ir_config_parameter(self):
product_length_in_feet_param = self.env['ir.config_parameter'].sudo().get_param('product.volume_in_cubic_feet')
if product_length_in_feet_param == '1':
return self.env.ref('uom.product_uom_cubic_foot')
else:
return self.env.ref('sf_dlm.product_uom_cubic_millimeter')
# model_file = fields.Binary('模型文件') # model_file = fields.Binary('模型文件')
# 胚料的库存路线设置 # 胚料的库存路线设置
@@ -80,19 +70,18 @@ class ResProductTemplate(models.Model):
'model_volume': (item['model_long'] + model_type.embryo_tolerance) * ( 'model_volume': (item['model_long'] + model_type.embryo_tolerance) * (
item['model_width'] + model_type.embryo_tolerance) * ( item['model_width'] + model_type.embryo_tolerance) * (
item['model_height'] + model_type.embryo_tolerance), item['model_height'] + model_type.embryo_tolerance),
'model_type_id': model_type.id, 'model_type_id': 1,
'model_processing_panel': 'R', # 'model_machining_precision': item['model_machining_precision'],
'model_machining_precision': item['model_machining_precision'], 'model_processing_panel': 'A',
'model_code': item['barcode'], 'model_machining_precision': '±0.10mm',
'length': item['model_long'], 'length': item['model_long'],
'width': item['model_width'], 'width': item['model_width'],
'height': item['model_height'], 'height': item['model_height'],
'volume': item['model_long'] * item['model_width'] * item['model_height'], 'volume': item['model_long'] * item['model_width'] * item['model_height'],
'model_file': '' if not item['model_file'] else base64.b64decode(item['model_file']), 'model_file': base64.b64decode(item['model_file']),
'model_name': attachment.name, 'model_name': attachment.name,
'upload_model_file': [(6, 0, [attachment.id])], 'upload_model_file': [(6, 0, [attachment.id])],
# 'single_manufacturing': True, # 'single_manufacturing': True,
'tracking': 'serial',
'list_price': item['price'], 'list_price': item['price'],
# 'categ_id': self.env.ref('sf_dlm.product_category_finished_sf').id, # 'categ_id': self.env.ref('sf_dlm.product_category_finished_sf').id,
'materials_id': self.env['sf.production.materials'].search( 'materials_id': self.env['sf.production.materials'].search(
@@ -110,34 +99,34 @@ class ResProductTemplate(models.Model):
# 'route_ids': self._get_routes('') # 'route_ids': self._get_routes('')
} }
copy_product_id.sudo().write(vals) copy_product_id.sudo().write(vals)
# product_id.product_tmpl_id.active = False print(len(copy_product_id.model_file))
product_id.product_tmpl_id.active = False
return copy_product_id return copy_product_id
def attachment_create(self, name, data): def attachment_create(self, name, data):
attachment = self.env['ir.attachment'].create({ attachment = self.env['ir.attachment'].create({
'datas': base64.b64decode(data), 'datas': base64.b64decode(data),
'type': 'binary', 'type': 'binary',
'public': True,
'description': '模型文件', 'description': '模型文件',
'name': name 'name': name
}) })
return attachment return attachment
# 创建胚料 # 创建胚料
def no_bom_product_create(self, product_id, item, order_id, route_type, i): def no_bom_product_create(self, product_id, item, order_id, route_type):
no_bom_copy_product_id = product_id.with_user(self.env.ref("base.user_admin")).copy() no_bom_copy_product_id = product_id.with_user(self.env.ref("base.user_admin")).copy()
no_bom_copy_product_id.product_tmpl_id.active = True no_bom_copy_product_id.product_tmpl_id.active = True
materials_id = self.env['sf.production.materials'].search( materials_id = self.env['sf.production.materials'].search(
[('materials_no', '=', item['texture_code'])]) [('materials_no', '=', item['texture_code'])])
materials_type_id = self.env['sf.materials.model'].search( materials_type_id = self.env['sf.materials.model'].search(
[('materials_no', '=', item['texture_type_code'])]) [('materials_no', '=', item['texture_type_code'])])
model_type = self.env['sf.model.type'].search([], limit=1)
supplier = self.env['mrp.bom'].get_supplier(materials_type_id) supplier = self.env['mrp.bom'].get_supplier(materials_type_id)
logging.info('no_bom_copy_product_supplier-vals:%s' % supplier) logging.info('no_bom_copy_product_supplier-vals:%s' % supplier)
vals = { vals = {
'name': '%s-%s %s %s %s * %s * %s' % ( 'name': '%s %s %s %s * %s * %s' % (
order_id.name, i, materials_id.name, materials_type_id.name, order_id.name, materials_id.name, materials_type_id.name, item['model_long'], item['model_width'],
item['model_long'] + model_type.embryo_tolerance, item['model_width'] + model_type.embryo_tolerance, item['model_height']),
item['model_height'] + model_type.embryo_tolerance),
'length': item['model_long'] + model_type.embryo_tolerance, 'length': item['model_long'] + model_type.embryo_tolerance,
'width': item['model_width'] + model_type.embryo_tolerance, 'width': item['model_width'] + model_type.embryo_tolerance,
'height': item['model_height'] + model_type.embryo_tolerance, 'height': item['model_height'] + model_type.embryo_tolerance,
@@ -161,38 +150,40 @@ class ResProductTemplate(models.Model):
no_bom_copy_product_id.purchase_ok = True no_bom_copy_product_id.purchase_ok = True
no_bom_copy_product_id.seller_ids = [ no_bom_copy_product_id.seller_ids = [
(0, 0, {'partner_id': supplier.partner_id.id, 'delay': 1.0, 'is_subcontractor': True})] (0, 0, {'partner_id': supplier.partner_id.id, 'delay': 1.0, 'is_subcontractor': True})]
logging.info('no_bom_copy_product_id-seller_ids-vals:%s' % no_bom_copy_product_id.seller_ids)
elif route_type == 'purchase': elif route_type == 'purchase':
no_bom_copy_product_id.purchase_ok = True no_bom_copy_product_id.purchase_ok = True
no_bom_copy_product_id.seller_ids = [ no_bom_copy_product_id.seller_ids = [
(0, 0, {'partner_id': supplier.partner_id.id, 'delay': 1.0})] (0, 0, {'partner_id': supplier.partner_id.id, 'delay': 1.0})]
logging.info('no_bom_copy_product_id-seller_ids-vals:%s' % no_bom_copy_product_id.seller_ids)
no_bom_copy_product_id.write(vals) no_bom_copy_product_id.write(vals)
logging.info('no_bom_copy_product_id-vals:%s' % vals) logging.info('no_bom_copy_product_id-vals:%s' % vals)
# product_id.product_tmpl_id.active = False product_id.product_tmpl_id.active = False
return no_bom_copy_product_id return no_bom_copy_product_id
# @api.onchange('upload_model_file') @api.onchange('upload_model_file')
# def onchange_model_file(self): def onchange_model_file(self):
# for item in self: for item in self:
# if len(item.upload_model_file) > 1: if len(item.upload_model_file) > 1:
# raise ValidationError('只允许上传一个文件') raise ValidationError('只允许上传一个文件')
# if item.upload_model_file: if item.upload_model_file:
# file_attachment_id = item.upload_model_file[0] file_attachment_id = item.upload_model_file[0]
# item.model_name = file_attachment_id.name item.model_name = file_attachment_id.name
# # 附件路径 # 附件路径
# report_path = file_attachment_id._full_path(file_attachment_id.store_fname) report_path = file_attachment_id._full_path(file_attachment_id.store_fname)
# shapes = read_step_file(report_path) shapes = read_step_file(report_path)
# output_file = get_resource_path('sf_dlm', 'static/file', 'out.stl') output_file = get_resource_path('sf_dlm', 'static/file', 'out.stl')
# write_stl_file(shapes, output_file, 'binary', 0.03, 0.5) write_stl_file(shapes, output_file, 'binary', 0.03, 0.5)
# # 转化为glb # 转化为glb
# output_glb_file = get_resource_path('sf_dlm', 'static/file', 'out.glb') output_glb_file = get_resource_path('sf_dlm', 'static/file', 'out.glb')
# util_path = get_resource_path('sf_dlm', 'static/util') util_path = get_resource_path('sf_dlm', 'static/util')
# cmd = 'python %s/stl2gltf.py %s %s -b' % (util_path, output_file, output_glb_file) cmd = 'python %s/stl2gltf.py %s %s -b' % (util_path, output_file, output_glb_file)
# os.system(cmd) os.system(cmd)
# # 转base64 # 转base64
# with open(output_glb_file, 'rb') as fileObj: with open(output_glb_file, 'rb') as fileObj:
# image_data = fileObj.read() image_data = fileObj.read()
# base64_data = base64.b64encode(image_data) base64_data = base64.b64encode(image_data)
# item.model_file = base64_data item.model_file = base64_data
class ResMrpBom(models.Model): class ResMrpBom(models.Model):
@@ -253,6 +244,8 @@ class ResMrpBom(models.Model):
# 匹配bom # 匹配bom
def get_bom(self, product): def get_bom(self, product):
logging.info('get_bom-product:%s' % product)
logging.info('get_bom-product:%s' % product.materials_type_id.id)
embryo_has = self.env['product.product'].search( embryo_has = self.env['product.product'].search(
[('categ_id.type', '=', '胚料'), ('materials_type_id', '=', product.materials_type_id.id), [('categ_id.type', '=', '胚料'), ('materials_type_id', '=', product.materials_type_id.id),
('length', '>', product.length), ('width', '>', product.width), ('length', '>', product.length), ('width', '>', product.width),
@@ -264,7 +257,7 @@ class ResMrpBom(models.Model):
logging.info('get_bom-vals:%s' % embryo_has) logging.info('get_bom-vals:%s' % embryo_has)
if embryo_has: if embryo_has:
rate_of_waste = ((embryo_has.volume - product.model_volume) % embryo_has.volume) * 100 rate_of_waste = ((embryo_has.volume - product.model_volume) % embryo_has.volume) * 100
if rate_of_waste <= 20: if rate_of_waste >= 20:
return embryo_has return embryo_has
else: else:
return return

View File

@@ -12,7 +12,7 @@
<!-- </field>--> <!-- </field>-->
<field name="invoice_policy" position="after"> <field name="invoice_policy" position="after">
<!-- <field name="model_file" required="True" widget="model_viewer"/>--> <field name="model_file" required="True" widget="model_viewer"/>
<field name="materials_id" string="材料"/> <field name="materials_id" string="材料"/>
<field name="materials_type_id" string="型号" <field name="materials_type_id" string="型号"
domain="[('materials_id', '=', materials_id)]"/> domain="[('materials_id', '=', materials_id)]"/>
@@ -36,23 +36,11 @@
<xpath expr="//page[last()]" position="after"> <xpath expr="//page[last()]" position="after">
<page string="加工参数"> <page string="加工参数">
<group>
<group string="模型"> <group string="模型">
<label for="model_long" string="尺寸[mm]"/> <field name="model_long" string="[mm]"/>
<div class="o_address_format"> <field name="model_width" string="宽[mm]"/>
<label for="model_long" string=""/> <field name="model_height" string="高[mm]"/>
<field name="model_long" class="o_address_zip"/> <field name="model_volume" string="体积[m³]"/>
<!-- <span>&amp;nbsp;</span>-->
<label for="model_width" string="宽"/>
<field name="model_width" class="o_address_zip"/>
<!-- <span>&amp;nbsp;</span>-->
<label for="model_height" string="高"/>
<field name="model_height" class="o_address_zip"/>
</div>
<!-- <field name="model_long" string="长[mm]"/>-->
<!-- <field name="model_width" string="宽[mm]"/>-->
<!-- <field name="model_height" string="高[mm]"/>-->
<field name="model_volume" string="体积[mm³]"/>
<field name="model_type_id" string="模型类型"/> <field name="model_type_id" string="模型类型"/>
<field name="model_processing_panel" placeholder="例如R,U" string="加工面板"/> <field name="model_processing_panel" placeholder="例如R,U" string="加工面板"/>
<field name="model_machining_precision"/> <field name="model_machining_precision"/>
@@ -61,7 +49,6 @@
domain="[('processing_order_ids', '=', model_surface_process_id)]"/> domain="[('processing_order_ids', '=', model_surface_process_id)]"/>
<field name="model_remark" string="备注说明"/> <field name="model_remark" string="备注说明"/>
</group> </group>
</group>
</page> </page>
</xpath> </xpath>
</field> </field>

View File

@@ -10,7 +10,7 @@
""", """,
'category': 'sf', 'category': 'sf',
'website': 'https://www.sf.jikimo.com', 'website': 'https://www.sf.jikimo.com',
'depends': ['mrp', 'sf_base', 'maintenance', 'sf_mrs_connect'], 'depends': ['mrp', 'sf_base', 'maintenance'],
'data': [ 'data': [
'security/group_security.xml', 'security/group_security.xml',
'security/ir.model.access.csv', 'security/ir.model.access.csv',

View File

@@ -2,12 +2,10 @@
from odoo import api, fields, models,_ from odoo import api, fields, models,_
class ResProducTemplate_Production(models.Model): class resProduct(models.Model):
_inherit = 'product.template' _inherit = 'product.template'
model_file = fields.Binary('模型文件') model_file = fields.Binary('模型文件')
class MrpProduction(models.Model): class MrpProduction(models.Model):
_inherit = 'mrp.production' _inherit = 'mrp.production'
_description = "制造订单" _description = "制造订单"

View File

@@ -13,12 +13,6 @@ class ResWorkcenter(models.Model):
'maintenance.equipment', 'workcenter_id', string="Maintenance Equipment", 'maintenance.equipment', 'workcenter_id', string="Maintenance Equipment",
check_company=True) check_company=True)
# @api.onchange('machine_tool_id')
# def update_machine_tool_is_binding(self):
# self.machine_tool_id.is_binding = True
def action_work_order(self): def action_work_order(self):
if not self.env.context.get('desktop_list_view', False): if not self.env.context.get('desktop_list_view', False):
action = self.env["ir.actions.actions"]._for_xml_id("sf_manufacturing.mrp_workorder_action_tablet") action = self.env["ir.actions.actions"]._for_xml_id("sf_manufacturing.mrp_workorder_action_tablet")

View File

@@ -4,7 +4,6 @@ import math
import requests import requests
import logging import logging
import base64 import base64
import hashlib
# import subprocess # import subprocess
from datetime import datetime from datetime import datetime
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
@@ -48,12 +47,9 @@ class ResMrpWorkOrder(models.Model):
workorder.user_permissions = False workorder.user_permissions = False
user_permissions = fields.Boolean('用户权限', compute='get_user_permissions') user_permissions = fields.Boolean('用户权限', compute='get_user_permissions')
programming_no = fields.Char('编程单号')
work_state = fields.Char('业务状态')
programming_state = fields.Char('编程状态')
cnc_worksheet = fields.Binary( cnc_worksheet = fields.Binary(
'工作指令', readonly=True) '工作指令', readonly=True)
material_center_point = fields.Char(string='料中心点') material_center_point = fields.Char(string='料中心点')
X1_axis = fields.Float(default=0) X1_axis = fields.Float(default=0)
Y1_axis = fields.Float(default=0) Y1_axis = fields.Float(default=0)
Z1_axis = fields.Float(default=0) Z1_axis = fields.Float(default=0)
@@ -89,9 +85,12 @@ class ResMrpWorkOrder(models.Model):
string="检测结果") string="检测结果")
cnc_ids = fields.One2many("sf.cnc.processing", 'workorder_id', string="CNC加工") cnc_ids = fields.One2many("sf.cnc.processing", 'workorder_id', string="CNC加工")
tray_code = fields.Char(string="托盘") tray_code = fields.Char(string="托盘")
programming_no = fields.Char('编程单号')
is_programming = fields.Boolean('是否编程', default=False)
# 计算配料中心点和与x轴倾斜度方法 # 计算配料中心点和与x轴倾斜度方法
def getcenter(self): def getcenter(self):
try:
x1 = self.X1_axis x1 = self.X1_axis
x2 = self.X2_axis x2 = self.X2_axis
x3 = self.X3_axis x3 = self.X3_axis
@@ -126,11 +125,10 @@ class ResMrpWorkOrder(models.Model):
print("(%.2f,%.2f)" % (x, y)) print("(%.2f,%.2f)" % (x, y))
self.material_center_point = ("(%.2f,%.2f,%.2f)" % (x, y, z)) self.material_center_point = ("(%.2f,%.2f,%.2f)" % (x, y, z))
self.X_deviation_angle = jdz self.X_deviation_angle = jdz
# 将补偿值写入CNC加工工单 return self.material_center_point
workorder = self.env['mrp.workorder'].browse(self.ids) except:
work = workorder.production_id.workorder_ids raise UserError("参数计算有误")
work.compensation_value_x = eval(self.material_center_point)[0]
work.compensation_value_y = eval(self.material_center_point)[1]
def json_workorder_str(self, k, production, route): def json_workorder_str(self, k, production, route):
workorders_values_str = [0, '', { workorders_values_str = [0, '', {
@@ -140,7 +138,6 @@ class ResMrpWorkOrder(models.Model):
'name': route.route_workcenter_id.name, 'name': route.route_workcenter_id.name,
'processing_panel': k, 'processing_panel': k,
'routing_type': route.routing_type, 'routing_type': route.routing_type,
'work_state': '' if not route.routing_type == '获取CNC加工程序' else '待发起',
'workcenter_id': self.env['mrp.routing.workcenter'].get_workcenter(route.workcenter_ids.ids), 'workcenter_id': self.env['mrp.routing.workcenter'].get_workcenter(route.workcenter_ids.ids),
'date_planned_start': False, 'date_planned_start': False,
'date_planned_finished': False, 'date_planned_finished': False,
@@ -167,8 +164,9 @@ class ResMrpWorkOrder(models.Model):
'target': 'new', 'target': 'new',
'domain': [('workorder_id', '=', self.id)] 'domain': [('workorder_id', '=', self.id)]
} }
tray_id = fields.Many2one('sf.tray', string="托盘信息")
# 扫码绑定托盘方法 # 扫码绑定托盘方法
def gettray(self): def gettray(self):
if self.tray_code != False: if self.tray_code != False:
values = self.env['sf.tray'].search([("code", "=", self.tray_code)]) values = self.env['sf.tray'].search([("code", "=", self.tray_code)])
@@ -183,10 +181,11 @@ class ResMrpWorkOrder(models.Model):
'production_id': self.production_id, 'production_id': self.production_id,
'state': '占用', 'state': '占用',
}) })
self.tray_id = values
else: else:
raise UserError('该托盘编码已失效') raise UserError('该托盘编码已失效')
else: else:
return "" raise UserError('托盘码不能为空')
def gettray_auto(self, barcode): def gettray_auto(self, barcode):
if barcode != False: if barcode != False:
@@ -205,15 +204,45 @@ class ResMrpWorkOrder(models.Model):
else: else:
raise UserError('该托盘编码已失效') raise UserError('该托盘编码已失效')
else: else:
return "" return {
'name': _('New Maintenance Request'),
'view_mode': 'form',
'res_model': 'maintenance.request',
'type': 'ir.actions.act_window',
'context': {
'default_company_id': self.company_id.id,
'default_production_id': self.id,
},
'domain': [('production_id', '=', self.id)],
}
# 解除托盘绑定 # 解除托盘绑定
def unbindtray(self): def unbindtray(self):
tray = self.env['sf.tray'].search([("production_id", "=", self.production_id.id)]) tray = self.env['sf.tray'].search([("production_id", "=", self.production_id.id)])
if tray: if tray:
tray.unclamp() tray.unclamp()
return {
'name': _("工单"),
'view_mode': 'form',
'res_model': 'mrp.workorder',
'res_id': self.id,
'type': 'ir.actions.act_window',
'target': 'new'
}
return "" # return {
# 'name': _('New Maintenance Request'),
# 'view_mode': 'form',
# 'res_model': 'maintenance.request',
# 'res_id':self.id,
# 'type': 'ir.actions.act_window',
# 'context': {
# 'default_company_id': self.company_id.id,
# 'default_production_id': self.id,
# },
# 'domain': [('production_id', '=', self.id)],
# 'target':'new'
# }
def recreateManufacturingOrWorkerOrder(self): def recreateManufacturingOrWorkerOrder(self):
""" """
@@ -256,39 +285,27 @@ class ResMrpWorkOrder(models.Model):
self.env['stock.move'].sudo().create(productions._get_moves_finished_values()) self.env['stock.move'].sudo().create(productions._get_moves_finished_values())
productions._create_workorder2(self.processing_panel) productions._create_workorder2(self.processing_panel)
else: else:
return True
# def fetchCNCing(self): return {
# return None 'name': _("工单"),
'view_mode': 'form',
'res_model': 'mrp.workorder',
'res_id': self.id,
'type': 'ir.actions.act_window',
}
# cnc程序获取
# cnc程序获取 # cnc程序获取
def fetchCNC(self): def fetchCNC(self):
try:
cnc = self.env['mrp.workorder'].search( cnc = self.env['mrp.workorder'].search(
[('routing_type', '=', 'CNC加工'), ('production_id', '=', self.production_id.id)], limit=1) [('routing_type', '=', 'CNC加工'), ('production_id', '=', self.production_id.id)], limit=1)
logging.info('fetchCNC-cnc:%s' % cnc) res = {'model_code': cnc.product_id.barcode, 'production_no': self.production_id.name,
# if cnc.product_id.upload_model_file:
# logging.info('fetchCNC-upload_model_file:%s' % cnc.product_id.upload_model_file)
# attachments = cnc.product_id.upload_model_file[0]
# logging.info('fetchCNC-attachment1:%s' % attachments)
# logging.info('fetchCNC-attachment1:%s' % cnc.product_id.upload_model_file[0])
# logging.info('fetchCNC-attachment2:%s' % cnc.product_id.upload_model_file[0].datas)
# logging.info('fetchCNC-attachment:%s' % attachments.datas)
# base64_data = base64.b64encode(attachments.datas)
# logging.info('fetchCNC-attachment1:%s' % attachments)
# base64_datas = base64_data.decode('utf-8')
# model_code = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest()
# logging.info('fetchCNC-model_code:%s' % model_code)
logging.info('fetchCNC-model_code1:%s' % cnc.product_id.model_code)
res = {'model_code': '' if not cnc.product_id.model_code else cnc.product_id.model_code,
'production_no': self.production_id.name,
'machine_tool_code': cnc.workcenter_id.machine_tool_id.code, 'machine_tool_code': cnc.workcenter_id.machine_tool_id.code,
'material_code': cnc.env['sf.production.materials'].search( 'material_code': cnc.env['sf.production.materials'].search(
[('id', '=', cnc.product_id.materials_id.id)]).materials_no, [('id', '=', cnc.product_id.materials_id.id)]).materials_no,
'material_type_code': cnc.env['sf.materials.model'].search( 'material_type_code': cnc.env['sf.materials.model'].search(
[('id', '=', cnc.product_id.materials_type_id.id)]).materials_no, [('id', '=', cnc.product_id.materials_type_id.id)]).materials_no,
'machining_processing_panel': cnc.product_id.model_processing_panel, 'machining_precision': cnc.product_id.model_machining_precision,
# 'machining_precision': cnc.product_id.model_machining_precision,
'embryo_long': cnc.product_id.bom_ids.bom_line_ids.product_id.length, 'embryo_long': cnc.product_id.bom_ids.bom_line_ids.product_id.length,
'embryo_height': cnc.product_id.bom_ids.bom_line_ids.product_id.height, '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, 'embryo_width': cnc.product_id.bom_ids.bom_line_ids.product_id.width,
@@ -305,25 +322,8 @@ class ResMrpWorkOrder(models.Model):
# res_str = json.dumps(res) # res_str = json.dumps(res)
ret = requests.post(config_url, json={}, data=res, headers=config_header) ret = requests.post(config_url, json={}, data=res, headers=config_header)
ret = ret.json() ret = ret.json()
logging.info('fetchCNC-ret:%s' % ret)
if ret['status'] == 1: if ret['status'] == 1:
self.write( return self.write({'programming_no': ret['programming_no'], 'is_programming': True})
{'programming_no': ret['programming_no'], 'programming_state': '编程中', 'work_state': '编程中'})
else:
logging.info('fetchCNC-error:%s' % cnc)
raise UserError(ret['message'])
except Exception as e:
logging.info('fetchCNC error:%s' % e)
raise UserError(e)
# return {
# 'name': _("工单"),
# 'view_mode': 'form',
# 'res_model': 'mrp.workorder',
# 'res_id': self.id,
# 'type': 'ir.actions.act_window',
# 'target': 'new'
# }
def json_workorder_str1(self, k, production, route): def json_workorder_str1(self, k, production, route):
workorders_values_str = [0, '', { workorders_values_str = [0, '', {
@@ -333,7 +333,6 @@ class ResMrpWorkOrder(models.Model):
'name': route.route_workcenter_id.name, 'name': route.route_workcenter_id.name,
'processing_panel': k, 'processing_panel': k,
'routing_type': route.routing_type, 'routing_type': route.routing_type,
'work_state': '' if not route.routing_type == '获取CNC加工程序' else '待发起',
'workcenter_id': self.env['mrp.routing.workcenter'].get_workcenter(route.workcenter_ids.ids), 'workcenter_id': self.env['mrp.routing.workcenter'].get_workcenter(route.workcenter_ids.ids),
'date_planned_start': False, 'date_planned_start': False,
'date_planned_finished': False, 'date_planned_finished': False,
@@ -412,13 +411,11 @@ class CNCprocessing(models.Model):
workorder_id = fields.Many2one('mrp.workorder', string="工单") workorder_id = fields.Many2one('mrp.workorder', string="工单")
# mrs下发编程单创建CNC加工 # mrs下发编程单创建CNC加工
def cnc_processing_create(self, cnc_workorder, ret): def cnc_processing_create(self, obj):
logging.info('ret:%s' % ret) workorder = self.env['mrp.workorder'].search([('production_id.name', '=', obj['production_order_no']),
for obj in ret['programming_list']:
workorder = self.env['mrp.workorder'].search([('production_id.name', '=', ret['production_order_no']),
('processing_panel', '=', obj['processing_panel']), ('processing_panel', '=', obj['processing_panel']),
('routing_type', '=', 'CNC加工')]) ('routing_type', '=', 'CNC加工')])
cnc_processing = self.env['sf.cnc.processing'].create({ vals = {
'workorder_id': workorder.id, 'workorder_id': workorder.id,
'sequence_number': obj['sequence_number'], 'sequence_number': obj['sequence_number'],
'program_name': obj['program_name'], 'program_name': obj['program_name'],
@@ -432,66 +429,52 @@ class CNCprocessing(models.Model):
'cutting_tool_handle_type': obj['cutting_tool_handle_type'], 'cutting_tool_handle_type': obj['cutting_tool_handle_type'],
'estimated_processing_time': obj['estimated_processing_time'], 'estimated_processing_time': obj['estimated_processing_time'],
'remark': obj['remark'] 'remark': obj['remark']
}) }
self.get_cnc_processing_file(ret['folder_name'], cnc_processing, workorder.processing_panel) return self.env['sf.cnc.processing'].create(vals)
cnc_workorder.state = 'done'
cnc_workorder.work_state = '已编程'
cnc_workorder.programming_state = '已编程'
cnc_workorder.time_ids.date_end = datetime.now()
cnc_workorder.button_finish()
def get_cnc_processing_file(self, folder_name, cnc_processing, processing_panel):
logging.info('folder_name:%s' % folder_name)
serverdir = os.path.join('/tmp', folder_name, 'return', processing_panel)
logging.info('serverdir:%s' % serverdir)
for root, dirs, files in os.walk(serverdir):
for f in files:
logging.info('f:%s' % f)
if os.path.splitext(f)[1] == ".pdf":
full_path = os.path.join(serverdir, root, f)
logging.info('pdf:%s' % full_path)
if full_path != False:
if not cnc_processing.workorder_id.cnc_worksheet:
cnc_processing.workorder_id.cnc_worksheet = base64.b64encode(
open(full_path, 'rb').read())
else:
if cnc_processing.program_name == f.split('.')[0]:
cnc_file_path = os.path.join(serverdir, root, f)
logging.info('cnc_file_path:%s' % cnc_file_path)
self.write_file(cnc_file_path, cnc_processing)
# 创建附件(nc文件) # 创建附件(nc文件)
def attachment_create(self, name, data): def attachment_create(self, name, data):
attachment = self.env['ir.attachment'].create({ attachment = self.env['ir.attachment'].create({
'datas': base64.b64encode(data), 'datas': base64.b64encode(data),
'type': 'binary', 'type': 'binary',
'public': True,
'description': '程序文件', 'description': '程序文件',
'name': name 'name': name
}) })
return attachment return attachment
# 将FTP的nc文件下载到临时目录 # 将FTP的nc文件下载到临时目录
def download_file_tmp(self, production_no, processing_panel): def download_file_tmp(self, model_code, processing_panel):
remotepath = os.path.join('/', production_no, 'return', processing_panel) remotepath = os.path.join('/', model_code, 'return', processing_panel)
serverdir = os.path.join('/tmp', production_no, 'return', processing_panel) serverdir = os.path.join('/tmp', model_code, 'return', processing_panel)
ftp_resconfig = self.env['res.config.settings'].get_values() ftp = FtpController()
ftp = FtpController(str(ftp_resconfig['ftp_host']), int(ftp_resconfig['ftp_port']), ftp_resconfig['ftp_user'], ftp.download_file_tree(remotepath, serverdir)
ftp_resconfig['ftp_password']) return serverdir
download_state = ftp.download_file_tree(remotepath, serverdir)
return download_state
# 将nc文件存到attach的datas里 # 将nc文件存到attach的datas里
def write_file(self, nc_file_path, cnc): def write_file(self, nc_file_path, cnc):
if os.path.exists(nc_file_path): if os.path.exists(nc_file_path):
with open(nc_file_path, 'rb') as file: with open(nc_file_path, 'rb') as file:
data_bytes = file.read() data_bytes = file.read()
attachment = self.attachment_create(cnc.program_name, data_bytes) attachment = self.attachment_create(cnc.program_name + '.NC', data_bytes)
cnc.write({'cnc_id': attachment.id}) cnc.write({'cnc_id': attachment.id})
file.close() file.close()
else: else:
return False return False
# 将nc文件对应的excel清单转为pdf
# def to_pdf(self, excel_path, pdf_path):
# """
# 需要在linux中下载好libreoffice
# """
# logging.info('pdf_path:%s' % pdf_path)
# logging.info('pdf_path:%s' % excel_path)
# # 注意cmd中的libreoffice要和linux中安装的一致
# cmd = 'soffice --headless --convert-to pdf'.split() + [excel_path] + ['--outdir'] + [pdf_path]
# p = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, bufsize=1)
# # p.wait(timeout=30) # 停顿30秒等待转化
# # stdout, stderr = p.communicate()
# p.communicate()
class SfWorkOrderBarcodes(models.Model): class SfWorkOrderBarcodes(models.Model):
""" """

View File

@@ -20,6 +20,41 @@ class Tray(models.Model):
def updateTrayState(self): def updateTrayState(self):
if self.workorder_id != False: if self.workorder_id != False:
self.state = '占用' self.state = '占用'
else: else:
self.state = '空闲' self.state = '空闲'

View File

@@ -107,7 +107,7 @@
</xpath> </xpath>
<xpath expr="//field[@name='alternative_workcenter_ids']" position="after"> <xpath expr="//field[@name='alternative_workcenter_ids']" position="after">
<field name="machine_tool_id" domain="[('is_binding', '=', False)]"/> <field name="machine_tool_id"/>
</xpath> </xpath>
</field> </field>
</record> </record>

View File

@@ -12,21 +12,32 @@
<field name="name" position="after"> <field name="name" position="after">
<field name="processing_panel"/> <field name="processing_panel"/>
</field> </field>
<field name="state" position="after">
<field name="work_state"/>
</field>
<xpath expr="//button[@name='button_start']" position="attributes"> <xpath expr="//button[@name='button_start']" position="attributes">
<attribute name="attrs">{'invisible': ['|', '|', '|','|', ('production_state','in', ('draft', 'done', <attribute name="attrs">{'invisible': ['|', '|', '|','|', ('production_state','in', ('draft', 'done',
'cancel')), ('working_state', '=', 'blocked'), ('state', 'in', ('done', 'cancel')), 'cancel')), ('working_state', '=', 'blocked'), ('state', 'in', ('done', 'cancel')),
('is_user_working', '!=', False),("user_permissions","=",False)]} ('is_user_working', '!=', False),("user_permissions","=",False)]}
</attribute> </attribute>
</xpath> </xpath>
<xpath expr="//button[@name='%(mrp.act_mrp_block_workcenter_wo)d']" position="attributes">
<attribute name="attrs">{'invisible': [("user_permissions","=",False)]} </attribute>
<attribute name="string">停工</attribute>
</xpath>
<xpath expr="//button[@name='action_open_wizard']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<!-- <button name="button_start" type="object" string="Start" class="btn-success"--> <!-- <button name="button_start" type="object" string="Start" class="btn-success"-->
<!-- attrs="{'invisible': ['|', '|', '|', ('production_state','in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('state', 'in', ('done', 'cancel')), ('is_user_working', '!=', False)]}"/>--> <!-- attrs="{'invisible': ['|', '|', '|', ('production_state','in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('state', 'in', ('done', 'cancel')), ('is_user_working', '!=', False)]}"/>-->
<!-- <button name="button_pending" type="object" string="Pause" class="btn-warning"--> <!-- <button name="button_pending" type="object" string="Pause" class="btn-warning"-->
<!-- attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('is_user_working', '=', False)]}"/>--> <!-- attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('is_user_working', '=', False)]}"/>-->
<!-- <button name="button_finish" type="object" string="Done" class="btn-success"--> <!-- <button name="button_finish" type="object" string="Done" class="btn-success"-->
<!-- attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('is_user_working', '=', False)]}"/>--> <!-- 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="Block" context="{'default_workcenter_id': workcenter_id}" class="btn-danger"-->
<!-- attrs="{'invisible': ['|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked')]}"/>-->
<!-- <button name="button_unblock" type="object" string="Unblock" context="{'default_workcenter_id': workcenter_id}" class="btn-danger"-->
<!-- attrs="{'invisible': ['|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '!=', 'blocked')]}"/>-->
<!-- <button name="action_open_wizard" type="object" icon="fa-external-link" class="oe_edit_only"-->
<!-- title="Open Work Order"/>-->
<tree position="attributes"> <tree position="attributes">
<attribute name="multi_edit"></attribute> <attribute name="multi_edit"></attribute>
<attribute name="editable"></attribute> <attribute name="editable"></attribute>
@@ -80,23 +91,17 @@
<xpath expr="field[@name='is_user_working']" position="before"> <xpath expr="field[@name='is_user_working']" position="before">
<field name='user_permissions' invisible="1"/> <field name='user_permissions' invisible="1"/>
</xpath> </xpath>
<xpath expr="//page[last()]" position="after"> <xpath expr="//page[last()]" position="after">
<page string="获取CNC加工程序" attrs='{"invisible": [("routing_type","!=","获取CNC加工程序")]}'> <page string="获取CNC加工程序" attrs='{"invisible": [("routing_type","!=","获取CNC加工程序")]}'>
<group>
<field name="programming_no" readonly="1" <div class="col-12 col-lg-6 o_setting_box">
attrs='{"invisible": [("programming_no","=",False)]}'/>
<field name="programming_state" readonly="1"
attrs='{"invisible": [("programming_no","=",False)]}'/>
</group>
<group>
<div class="col-12 col-lg-6 o_setting_box" style="white-space: nowrap">
<button type="object" class="oe_highlight" name="fetchCNC" string="获取CNC程序代码" <button type="object" class="oe_highlight" name="fetchCNC" string="获取CNC程序代码"
attrs='{"invisible": ["|",("state","!=","progress"),("user_permissions","=",False),("programming_no","!=",False)]}'/> attrs='{"invisible": ["|",("state","!=","progress"),("user_permissions","=",False)]}'/>
<!-- <button type="object" class="oe_highlight disabled" name="fetchCNC" string="获取CNC程序代码"-->
<!-- attrs='{"invisible": [("programming_no","=",False)]}'/>-->
</div> </div>
</group>
</page> </page>
</xpath> </xpath>
<xpath expr="//page[last()]" position="after"> <xpath expr="//page[last()]" position="after">
<page string="装夹托盘" attrs='{"invisible": [("routing_type","!=","装夹")]}'> <page string="装夹托盘" attrs='{"invisible": [("routing_type","!=","装夹")]}'>
@@ -104,12 +109,16 @@
<field name="routing_type" invisible="1"/> <field name="routing_type" invisible="1"/>
<field name="processing_panel" readonly="1"/> <field name="processing_panel" readonly="1"/>
<field name="tray_code"/> <field name="tray_code"/>
<field name="tray_id" readonly="1"/>
</group> </group>
<div class="col-12 col-lg-6 o_setting_box"> <div class="col-12 col-lg-6 o_setting_box">
<button type="object" class="oe_highlight" name="gettray" string="绑定托盘" <button type="object" class="oe_highlight" name="gettray" string="绑定托盘"
attrs='{"invisible": [("production_id","=",False)]}'/> attrs='{"invisible": ["|","|",("tray_id","!=",False),("state","!=","progress"),("production_id","=",False)]}'/>
</div> </div>
</page> </page>
</xpath> </xpath>
<xpath expr="//page[last()]" position="after"> <xpath expr="//page[last()]" position="after">
<page string="三元前置检测定位参数" attrs='{"invisible": [("routing_type","!=","前置三元定位检测")]}'> <page string="三元前置检测定位参数" attrs='{"invisible": [("routing_type","!=","前置三元定位检测")]}'>
@@ -217,7 +226,7 @@
<div class="col-12 col-lg-6 o_setting_box"> <div class="col-12 col-lg-6 o_setting_box">
<button type="object" class="oe_highlight" name="getcenter" string="计算定位" <button type="object" class="oe_highlight" name="getcenter" string="计算定位"
attrs='{"invisible": [("user_permissions","=",False)]}'/> attrs='{"invisible": ["|","|",("material_center_point","!=",False),("state","!=","progress"),("user_permissions","=",False)]}'/>
</div> </div>
<group> <group>
@@ -259,7 +268,7 @@
</group> </group>
<div class="col-12 col-lg-6 o_setting_box"> <div class="col-12 col-lg-6 o_setting_box">
<button type="object" class="oe_highlight" name="recreateManufacturingOrWorkerOrder" <button type="object" class="oe_highlight" name="recreateManufacturingOrWorkerOrder"
string="检测确认" attrs='{"invisible": [("user_permissions","=",False)]}'/> string="检测确认" attrs='{"invisible": ["|",("state","!=","progress"),("user_permissions","=",False)]}'/>
</div> </div>
</page> </page>
</xpath> </xpath>
@@ -268,11 +277,11 @@
<div class="col-12 col-lg-6 o_setting_box"> <div class="col-12 col-lg-6 o_setting_box">
<button type="object" class="oe_highlight" name="unbindtray" string="解除装夹" <button type="object" class="oe_highlight" name="unbindtray" string="解除装夹"
attrs='{"invisible": [("user_permissions","=",False)]}'/> attrs='{"invisible": ["|",("state","!=","progress"),("user_permissions","=",False)]}'/>
</div> </div>
<div class="col-12 col-lg-6 o_setting_box"> <div class="col-12 col-lg-6 o_setting_box">
<button type="action" class="oe_highlight" name="sf_manufacturing.label_sf_tray_code1" <button type="action" class="oe_highlight" name="sf_manufacturing.label_sf_tray_code1"
string="打印标签" attrs='{"invisible": [("user_permissions","=",False)]}'/> string="打印标签" attrs='{"invisible": ["|",("state","!=","progress"),("user_permissions","=",False)]}'/>
</div> </div>
</page> </page>

View File

@@ -20,32 +20,44 @@ class Sf_Mrs_Connect(http.Controller):
""" """
logging.info('get_cnc_processing_create:%s' % kw) logging.info('get_cnc_processing_create:%s' % kw)
try: try:
res = {'status': 1, 'message': '成功'}
datas = request.httprequest.data datas = request.httprequest.data
ret = json.loads(datas) ret = json.loads(datas)
ret = json.loads(ret['result']) ret = json.loads(ret['result'])
# 查询状态为进行中且类型为获取CNC加工程序的工单 for obj in ret:
cnc_workorder = request.env['mrp.workorder'].with_user( cnc = request.env['sf.cnc.processing'].with_user(
request.env.ref("base.user_admin")).search([('production_id.name', '=', ret['production_order_no']), request.env.ref("base.user_admin")).cnc_processing_create(obj)
('routing_type', '=', '获取CNC加工程序')]) # # 从ftp拉取对应的文件
if cnc_workorder: model_code = cnc.workorder_id.product_id.barcode
# 拉取所有加工面的程序文件 processing_panel = cnc.workorder_id.processing_panel
# i = 1 logging.info('model_code:%s' % model_code)
for r in ret['processing_panel']: server_dir = cnc.with_user(request.env.ref("base.user_admin")).download_file_tmp(model_code,
download_state = request.env['sf.cnc.processing'].with_user( processing_panel)
request.env.ref("base.user_admin")).download_file_tmp( # cnc_file_path = os.path.join('/', server_dir, cnc.program_name + '.nc')
ret['folder_name'], r) # logging.info('cnc_file_path:%s' % cnc_file_path)
if download_state == False: # cnc.with_user(request.env.ref("base.user_admin")).write_file(cnc_file_path, cnc)
res['status'] = -2 logging.info('server_dir:%s' % server_dir)
res['message'] = '制造订单号为%s的CNC程序文件从FTP拉取失败' % (cnc_workorder.production_id.name) for root, dirs, files in os.walk(server_dir):
return json.JSONEncoder().encode(res) for f in files:
request.env['sf.cnc.processing'].with_user( logging.info('f:%s' % f)
request.env.ref("base.user_admin")).cnc_processing_create(cnc_workorder, ret) logging.info('f[0]:%s' % f.split('.')[0])
return json.JSONEncoder().encode(res) if os.path.splitext(f)[1] == ".pdf":
full_path = os.path.join(server_dir, root, f)
logging.info('pdf:%s' % full_path)
if full_path != False:
if not cnc.workorder_id.cnc_worksheet:
cnc.workorder_id.cnc_worksheet = base64.b64encode(open(full_path, 'rb').read())
else: else:
res = {'status': 0, 'message': '该制造订单暂未开始'} logging.info('break:%s' % 'break')
return json.JSONEncoder().encode(res) continue
else:
logging.info('cnc.program_name:%s' % cnc.program_name)
if cnc.program_name == f.split('.')[0]:
logging.info('f[0]:%s' % f[0])
cnc_file_path = os.path.join(server_dir, root, f)
logging.info('cnc_file_path:%s' % cnc_file_path)
cnc.with_user(request.env.ref("base.user_admin")).write_file(cnc_file_path, cnc)
else:
continue
except Exception as e: except Exception as e:
res = {'status': -1, 'message': '系统解析失败'}
logging.info('get_cnc_processing_create error:%s' % e) logging.info('get_cnc_processing_create error:%s' % e)
return json.JSONEncoder().encode(res)

View File

@@ -15,31 +15,26 @@ class FtpController():
ftp = FTP() ftp = FTP()
def __init__(self, host, port, username, password): def __init__(self, host="192.168.50.202", port=21, username="ftpuser", password="123456"):
try: try:
self.ftp.connect(host, port) self.ftp.connect(host, port)
self.ftp.login(username, password) self.ftp.login(username, password)
logging.info("ftp连接成功") logging.info("连接成功: ")
except: except:
logging.info("ftp连接失败") logging.info("连接失败: ")
return False
# 下载目录下的文件 # 下载目录下的文件
def download_file_tree(self, target_dir, serverdir): def download_file_tree(self, target_dir, serverdir):
if not os.path.exists(serverdir): if not os.path.exists(serverdir):
os.makedirs(serverdir) os.makedirs(serverdir)
try:
logging.info("进入FTP目录 ")
self.ftp.cwd(target_dir) # 切换工作路径 self.ftp.cwd(target_dir) # 切换工作路径
logging.info('FTP目录:%s' % target_dir)
remotenames = self.ftp.nlst() remotenames = self.ftp.nlst()
logging.info('FTP目录文件:%s' % remotenames)
for file in remotenames: for file in remotenames:
server = os.path.join(serverdir, file) server = os.path.join(serverdir, file)
if file.find(".") != -1: if file.find(".") != -1:
self.download_file(server, file) self.download_file(server, file)
except: else:
return False return
# 下载指定目录下的指定文件 # 下载指定目录下的指定文件
def download_file(self, serverfile, remotefile): def download_file(self, serverfile, remotefile):

View File

@@ -14,10 +14,6 @@ class ResConfigSettings(models.TransientModel):
token = fields.Char(string='TOKEN', default='b811ac06-3f00-11ed-9aed-0242ac110003') token = fields.Char(string='TOKEN', default='b811ac06-3f00-11ed-9aed-0242ac110003')
sf_secret_key = fields.Char(string='密钥', default= 'wBmxej38OkErKhD6') sf_secret_key = fields.Char(string='密钥', default= 'wBmxej38OkErKhD6')
sf_url = fields.Char(string='访问地址', default= 'https://sf.cs.jikimo.com') sf_url = fields.Char(string='访问地址', default= 'https://sf.cs.jikimo.com')
ftp_host = fields.Char(string='FTP的ip')
ftp_port = fields.Char(string='FTP端口')
ftp_user = fields.Char(string='FTP用户')
ftp_password = fields.Char(string='FTP密码')
def sf_all_sync(self): def sf_all_sync(self):
self.env['sf.production.materials'].sync_all_production_materials() self.env['sf.production.materials'].sync_all_production_materials()
@@ -44,6 +40,8 @@ class ResConfigSettings(models.TransientModel):
_logger.info("同步资源库刀具") _logger.info("同步资源库刀具")
# self.env['sf.processing.order'].sync_all_processing_order() # self.env['sf.processing.order'].sync_all_processing_order()
@api.model @api.model
def get_values(self): def get_values(self):
""" """
@@ -55,19 +53,11 @@ class ResConfigSettings(models.TransientModel):
token = config.get_param('token', default='') token = config.get_param('token', default='')
sf_secret_key = config.get_param('sf_secret_key', default='') sf_secret_key = config.get_param('sf_secret_key', default='')
sf_url = config.get_param('sf_url', default='') sf_url = config.get_param('sf_url', default='')
ftp_host = config.get_param('ftp_host', default='')
ftp_port = config.get_param('ftp_port', default='')
ftp_user = config.get_param('ftp_user', default='')
ftp_password = config.get_param('ftp_password', default='')
values.update( values.update(
token=token, token=token,
sf_secret_key=sf_secret_key, sf_secret_key=sf_secret_key,
sf_url=sf_url, sf_url=sf_url,
ftp_host=ftp_host,
ftp_port=ftp_port,
ftp_user=ftp_user,
ftp_password=ftp_password
) )
return values return values
@@ -77,7 +67,4 @@ class ResConfigSettings(models.TransientModel):
ir_config.set_param("token", self.token or "") ir_config.set_param("token", self.token or "")
ir_config.set_param("sf_secret_key", self.sf_secret_key or "") ir_config.set_param("sf_secret_key", self.sf_secret_key or "")
ir_config.set_param("sf_url", self.sf_url or "") ir_config.set_param("sf_url", self.sf_url or "")
ir_config.set_param("ftp_host", self.ftp_host or "")
ir_config.set_param("ftp_port", self.ftp_port or "")
ir_config.set_param("ftp_user", self.ftp_user or "")
ir_config.set_param("ftp_password", self.ftp_password or "")

View File

@@ -14,52 +14,25 @@
<div class="o_setting_left_pane"/> <div class="o_setting_left_pane"/>
<div class="o_setting_right_pane"> <div class="o_setting_right_pane">
<div class="text-muted"> <div class="text-muted">
<label for="sf_url"/> <label for="token"/>
<field name="sf_url"/>
</div>
<div class="text-muted">
<label for="token" string="Token"/>
<field name="token" /> <field name="token" />
</div> </div>
<div class="text-muted"> <div class="text-muted">
<label for="sf_secret_key"/> <label for="sf_secret_key"/>
<field name="sf_secret_key"/> <field name="sf_secret_key"/>
</div>
<div class="text-muted">
<label for="sf_url"/>
<field name="sf_url"/>
</div>
</div>
</div> </div>
<div class="col-12 col-lg-6 o_setting_box"> <div class="col-12 col-lg-6 o_setting_box">
<button type="object" class="oe_highlight" name="sf_all_sync" <button type="object" class="oe_highlight" name="sf_all_sync" string="同步资源库所有基础数据"
string="同步资源库基础数据"
/> />
</div> </div>
</div> </div>
</div> </div>
</div>
</div>
<div>
<h2>FTP参数配置</h2>
<div class="row mt16 o_settings_container" id="pay_api">
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane"/>
<div class="o_setting_right_pane">
<div class="text-muted">
<label for="ftp_host" string="访问地址"/>
<field name="ftp_host"/>
</div>
<div class="text-muted">
<label for="ftp_port" string="端口"/>
<field name="ftp_port"/>
</div>
<div class="text-muted">
<label for="ftp_user" string="用户"/>
<field name="ftp_user"/>
</div>
<div class="text-muted">
<label for="ftp_password" string="密码"/>
<field name="ftp_password" password="True"/>
</div>
</div>
</div>
</div>
</div>
</xpath> </xpath>
</field> </field>
</record> </record>

View File

@@ -44,7 +44,7 @@ class ReSaleOrder(models.Model):
product.model_machining_precision, product.model_machining_precision,
product.materials_id.name), product.materials_id.name),
'price_unit': product.list_price, 'price_unit': product.list_price,
# 'route_id': product.route_ids, 'route_id': product.route_ids,
'product_uom_qty': item['number'] 'product_uom_qty': item['number']
} }
return self.env['sale.order.line'].create(vals) return self.env['sale.order.line'].create(vals)