优化sf获取cnc程序和ftp
This commit is contained in:
@@ -77,7 +77,7 @@ class MachineTool(models.Model):
|
|||||||
b_axis = fields.Integer('B轴')
|
b_axis = fields.Integer('B轴')
|
||||||
c_axis = fields.Integer('C轴')
|
c_axis = fields.Integer('C轴')
|
||||||
remark = fields.Text('备注')
|
remark = fields.Text('备注')
|
||||||
is_binding = fields.Boolean('是否绑定机床', default=False)
|
is_binding = fields.Boolean('是否绑定工作中心', default=False)
|
||||||
precision = fields.Float('加工精度')
|
precision = fields.Float('加工精度')
|
||||||
control_system_id = fields.Many2one('sf.machine.control_system',
|
control_system_id = fields.Many2one('sf.machine.control_system',
|
||||||
string="控制系统")
|
string="控制系统")
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from odoo.http import request
|
|||||||
|
|
||||||
class Sf_Bf_Connect(http.Controller):
|
class Sf_Bf_Connect(http.Controller):
|
||||||
|
|
||||||
@http.route('/api/bfm_process_order/list', type='http', auth='none', methods=['GET', 'POST'], csrf=False,
|
@http.route('/api/bfm_process_order/list', type='http', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||||
cors="*")
|
cors="*")
|
||||||
def get_bfm_process_order_list(self, **kw):
|
def get_bfm_process_order_list(self, **kw):
|
||||||
"""
|
"""
|
||||||
@@ -44,9 +44,7 @@ class Sf_Bf_Connect(http.Controller):
|
|||||||
# else:
|
# else:
|
||||||
product = request.env['product.template'].sudo().product_create(product_id, item, order_id,
|
product = request.env['product.template'].sudo().product_create(product_id, item, order_id,
|
||||||
kw['order_number'], i)
|
kw['order_number'], i)
|
||||||
# order_id.with_user(request.env.ref("base.user_admin")).sale_order_create_line(product, item)
|
i += 1
|
||||||
logging.info('order_id:%s' % order_id)
|
|
||||||
logging.info('product:%s' % product)
|
|
||||||
bom_data = request.env['mrp.bom'].with_user(request.env.ref("base.user_admin")).get_bom(product)
|
bom_data = request.env['mrp.bom'].with_user(request.env.ref("base.user_admin")).get_bom(product)
|
||||||
logging.info('bom_data:%s' % bom_data)
|
logging.info('bom_data:%s' % bom_data)
|
||||||
if bom_data:
|
if bom_data:
|
||||||
@@ -102,7 +100,6 @@ class Sf_Bf_Connect(http.Controller):
|
|||||||
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)
|
||||||
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)
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class Http(models.AbstractModel):
|
|||||||
raise AuthenticationError('无效的token')
|
raise AuthenticationError('无效的token')
|
||||||
timestamp_str = int(time.time())
|
timestamp_str = int(time.time())
|
||||||
# 设置API接口请求时间,不能超过5秒
|
# 设置API接口请求时间,不能超过5秒
|
||||||
deltime = datetime.timedelta(seconds=5)
|
deltime = datetime.timedelta(seconds=60)
|
||||||
if abs(int(datas['HTTP_TIMESTAMP'])-timestamp_str) > deltime.seconds:
|
if abs(int(datas['HTTP_TIMESTAMP'])-timestamp_str) > deltime.seconds:
|
||||||
raise AuthenticationError('请求已过期')
|
raise AuthenticationError('请求已过期')
|
||||||
# 获得sha1_str加密字符串
|
# 获得sha1_str加密字符串
|
||||||
|
|||||||
@@ -10,9 +10,10 @@
|
|||||||
""",
|
""",
|
||||||
'category': 'sf',
|
'category': 'sf',
|
||||||
'website': 'https://www.sf.jikimo.com',
|
'website': 'https://www.sf.jikimo.com',
|
||||||
'depends': ['mrp', 'base', 'sf_manufacturing', 'web_widget_model_viewer', 'purchase', 'mrp_subcontracting'],
|
'depends': ['mrp', 'base', 'sf_manufacturing', 'web_widget_model_viewer', 'purchase', 'mrp_subcontracting', 'uom'],
|
||||||
'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': [
|
||||||
|
|||||||
11
sf_dlm/data/uom_data.xml
Normal file
11
sf_dlm/data/uom_data.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo noupdate="1">
|
||||||
|
<!-- UOM.UOM -->
|
||||||
|
<!-- VOLUME -->
|
||||||
|
<record id="product_uom_cubic_millimeter" model="uom.uom">
|
||||||
|
<field name="name">立方毫米</field>
|
||||||
|
<field name="category_id" ref="uom.product_uom_categ_vol"/>
|
||||||
|
<field name="factor_inv">1000</field>
|
||||||
|
<field name="uom_type">bigger</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
@@ -3,9 +3,10 @@ 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'
|
||||||
|
|
||||||
@@ -34,7 +35,16 @@ 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_file = fields.Binary('模型文件')
|
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('模型文件')
|
||||||
|
|
||||||
# 胚料的库存路线设置
|
# 胚料的库存路线设置
|
||||||
# def _get_routes(self, route_type):
|
# def _get_routes(self, route_type):
|
||||||
@@ -72,16 +82,18 @@ class ResProductTemplate(models.Model):
|
|||||||
item['model_height'] + model_type.embryo_tolerance),
|
item['model_height'] + model_type.embryo_tolerance),
|
||||||
'model_type_id': 1,
|
'model_type_id': 1,
|
||||||
# 'model_machining_precision': item['model_machining_precision'],
|
# 'model_machining_precision': item['model_machining_precision'],
|
||||||
'model_processing_panel': 'A',
|
'model_processing_panel': 'R',
|
||||||
'model_machining_precision': '±0.10mm',
|
'model_machining_precision': '±0.10mm',
|
||||||
|
'model_code': item['barcode'],
|
||||||
'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': base64.b64decode(item['model_file']),
|
'model_file': '' if not item['model_file'] else 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(
|
||||||
@@ -94,18 +106,17 @@ class ResProductTemplate(models.Model):
|
|||||||
# [('process_encode', '=', item['process_parameters_code'])]).id,
|
# [('process_encode', '=', item['process_parameters_code'])]).id,
|
||||||
'model_remark': item['remark'],
|
'model_remark': item['remark'],
|
||||||
'default_code': '%s-%s' % (order_number, i),
|
'default_code': '%s-%s' % (order_number, i),
|
||||||
#'barcode': item['barcode'],
|
# 'barcode': item['barcode'],
|
||||||
'active': True,
|
'active': True,
|
||||||
# 'route_ids': self._get_routes('')
|
# 'route_ids': self._get_routes('')
|
||||||
}
|
}
|
||||||
copy_product_id.sudo().write(vals)
|
copy_product_id.sudo().write(vals)
|
||||||
print(len(copy_product_id.model_file))
|
# product_id.product_tmpl_id.active = False
|
||||||
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',
|
||||||
'description': '模型文件',
|
'description': '模型文件',
|
||||||
'name': name
|
'name': name
|
||||||
@@ -125,8 +136,9 @@ class ResProductTemplate(models.Model):
|
|||||||
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' % (
|
'name': '%s %s %s %s * %s * %s' % (
|
||||||
order_id.name, materials_id.name, materials_type_id.name, item['model_long'], item['model_width'],
|
order_id.name, materials_id.name, materials_type_id.name,
|
||||||
item['model_height']),
|
item['model_long'] + model_type.embryo_tolerance, item['model_width'] + model_type.embryo_tolerance,
|
||||||
|
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,
|
||||||
@@ -158,32 +170,32 @@ class ResProductTemplate(models.Model):
|
|||||||
logging.info('no_bom_copy_product_id-seller_ids-vals:%s' % no_bom_copy_product_id.seller_ids)
|
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):
|
||||||
@@ -244,8 +256,6 @@ 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),
|
||||||
@@ -257,7 +267,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
|
||||||
|
|||||||
@@ -6,13 +6,13 @@
|
|||||||
<field name="model">product.template</field>
|
<field name="model">product.template</field>
|
||||||
<field name="inherit_id" ref="product.product_template_only_form_view"/>
|
<field name="inherit_id" ref="product.product_template_only_form_view"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<!-- <field name="image_1920" position="replace">-->
|
<!-- <field name="image_1920" position="replace">-->
|
||||||
<!-- <field name="upload_model_file" required="True"-->
|
<!-- <field name="upload_model_file" required="True"-->
|
||||||
<!-- widget='many2many_binary'/>-->
|
<!-- widget='many2many_binary'/>-->
|
||||||
<!-- </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,18 +36,31 @@
|
|||||||
|
|
||||||
<xpath expr="//page[last()]" position="after">
|
<xpath expr="//page[last()]" position="after">
|
||||||
<page string="加工参数">
|
<page string="加工参数">
|
||||||
<group string="模型">
|
<group>
|
||||||
<field name="model_long" string="长[mm]"/>
|
<group string="模型">
|
||||||
<field name="model_width" string="宽[mm]"/>
|
<label for="model_long" string="尺寸[mm]"/>
|
||||||
<field name="model_height" string="高[mm]"/>
|
<div class="o_address_format">
|
||||||
<field name="model_volume" string="体积[m³]"/>
|
<label for="model_long" string="长"/>
|
||||||
<field name="model_type_id" string="模型类型"/>
|
<field name="model_long" class="o_address_zip"/>
|
||||||
<field name="model_processing_panel" placeholder="例如R,U" string="加工面板"/>
|
<!-- <span>&nbsp;</span>-->
|
||||||
<field name="model_machining_precision"/>
|
<label for="model_width" string="宽"/>
|
||||||
<field name="model_surface_process_id" string="表面工艺"/>
|
<field name="model_width" class="o_address_zip"/>
|
||||||
<field name="model_process_parameters_id" string="工艺参数"
|
<!-- <span>&nbsp;</span>-->
|
||||||
domain="[('processing_order_ids', '=', model_surface_process_id)]"/>
|
<label for="model_height" string="高"/>
|
||||||
<field name="model_remark" 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_processing_panel" placeholder="例如R,U" string="加工面板"/>
|
||||||
|
<field name="model_machining_precision"/>
|
||||||
|
<field name="model_surface_process_id" string="表面工艺"/>
|
||||||
|
<field name="model_process_parameters_id" string="工艺参数"
|
||||||
|
domain="[('processing_order_ids', '=', model_surface_process_id)]"/>
|
||||||
|
<field name="model_remark" string="备注说明"/>
|
||||||
|
</group>
|
||||||
</group>
|
</group>
|
||||||
</page>
|
</page>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
|||||||
@@ -10,15 +10,15 @@
|
|||||||
""",
|
""",
|
||||||
'category': 'sf',
|
'category': 'sf',
|
||||||
'website': 'https://www.sf.jikimo.com',
|
'website': 'https://www.sf.jikimo.com',
|
||||||
'depends': ['mrp', 'sf_base', 'maintenance'],
|
'depends': ['mrp', 'sf_base', 'maintenance', 'sf_mrs_connect'],
|
||||||
'data': [
|
'data': [
|
||||||
'security/group_security.xml',
|
'security/group_security.xml',
|
||||||
'security/ir.model.access.csv',
|
'security/ir.model.access.csv',
|
||||||
'report/tray_report.xml',
|
'report/tray_report.xml',
|
||||||
'views/mrp_maintenance_views.xml',
|
'views/mrp_maintenance_views.xml',
|
||||||
'views/mrp_routing_workcenter_view.xml',
|
'views/mrp_routing_workcenter_view.xml',
|
||||||
'views/mrp_workorder_view.xml',
|
|
||||||
'views/mrp_workcenter_views.xml',
|
'views/mrp_workcenter_views.xml',
|
||||||
|
'views/mrp_workorder_view.xml',
|
||||||
'views/tray_view.xml',
|
'views/tray_view.xml',
|
||||||
'views/model_type_view.xml',
|
'views/model_type_view.xml',
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ from . import mrp_routing_workcenter
|
|||||||
from . import mrp_workorder
|
from . import mrp_workorder
|
||||||
from . import model_type
|
from . import model_type
|
||||||
from . import stock
|
from . import stock
|
||||||
|
from . import res_user
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ class ModelType(models.Model):
|
|||||||
_description = '模型类型'
|
_description = '模型类型'
|
||||||
|
|
||||||
name = fields.Char('名称')
|
name = fields.Char('名称')
|
||||||
embryo_tolerance = fields.Integer('胚料的容余量')
|
embryo_tolerance = fields.Boolean('胚料的容余量', default=False)
|
||||||
routing_tmpl_ids = fields.One2many('sf.model.type.routing.sort', 'model_type_id', '工序模板')
|
routing_tmpl_ids = fields.One2many('sf.model.type.routing.sort', 'model_type_id', '工序模板')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from odoo import api, fields, models, _
|
from odoo import api, fields, models,_
|
||||||
|
|
||||||
|
|
||||||
|
class ResProducTemplate_Production(models.Model):
|
||||||
|
_inherit = 'product.template'
|
||||||
|
|
||||||
|
model_file = fields.Binary('模型文件')
|
||||||
|
|
||||||
|
|
||||||
class MrpProduction(models.Model):
|
class MrpProduction(models.Model):
|
||||||
@@ -9,8 +15,7 @@ class MrpProduction(models.Model):
|
|||||||
tray_ids = fields.One2many('sf.tray', 'production_id', string="托盘")
|
tray_ids = fields.One2many('sf.tray', 'production_id', string="托盘")
|
||||||
maintenance_count = fields.Integer(compute='_compute_maintenance_count', string="Number of maintenance requests")
|
maintenance_count = fields.Integer(compute='_compute_maintenance_count', string="Number of maintenance requests")
|
||||||
request_ids = fields.One2many('maintenance.request', 'production_id')
|
request_ids = fields.One2many('maintenance.request', 'production_id')
|
||||||
# model_file = fields.Binary('模型文件', related='product_id.model_file')
|
model_file = fields.Binary('模型文件', related='product_id.model_file')
|
||||||
# model_information = fields.Char('模型信息', related='product_id.model_information')
|
|
||||||
|
|
||||||
@api.depends('request_ids')
|
@api.depends('request_ids')
|
||||||
def _compute_maintenance_count(self):
|
def _compute_maintenance_count(self):
|
||||||
@@ -131,9 +136,6 @@ class MrpProduction(models.Model):
|
|||||||
'location_src_id': production.location_src_id.id,
|
'location_src_id': production.location_src_id.id,
|
||||||
'location_dest_id': production.location_dest_id.id,
|
'location_dest_id': production.location_dest_id.id,
|
||||||
'bom_id': production.bom_id.id,
|
'bom_id': production.bom_id.id,
|
||||||
'model_file': base64.b64decode(production.product_id.model_file),
|
|
||||||
'model_information': '%s/%s' % (
|
|
||||||
production.product_id.model_processing_panel, production.product_id.materials_id.name),
|
|
||||||
'date_deadline': production.date_deadline,
|
'date_deadline': production.date_deadline,
|
||||||
'date_planned_start': production.date_planned_start,
|
'date_planned_start': production.date_planned_start,
|
||||||
'date_planned_finished': production.date_planned_finished,
|
'date_planned_finished': production.date_planned_finished,
|
||||||
|
|||||||
@@ -7,16 +7,18 @@ class ResWorkcenter(models.Model):
|
|||||||
_inherit = "mrp.workcenter"
|
_inherit = "mrp.workcenter"
|
||||||
machine_tool_id = fields.Many2one('sf.machine_tool', '机床')
|
machine_tool_id = fields.Many2one('sf.machine_tool', '机床')
|
||||||
|
|
||||||
@api.onchange('machine_tool_id')
|
users_ids = fields.Many2many("res.users", 'users_workcenter')
|
||||||
def get_machine_tool_is_binding(self):
|
|
||||||
print('1111111')
|
|
||||||
for item in self:
|
|
||||||
item.machine_tool_id.is_binding = False
|
|
||||||
|
|
||||||
equipment_ids = fields.One2many(
|
equipment_ids = fields.One2many(
|
||||||
'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")
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ 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
|
||||||
@@ -19,6 +20,7 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
_order = 'sequence'
|
_order = 'sequence'
|
||||||
|
|
||||||
workcenter_id = fields.Many2one('mrp.workcenter', required=False)
|
workcenter_id = fields.Many2one('mrp.workcenter', required=False)
|
||||||
|
users_ids = fields.Many2many("res.users", 'users_workorder', related="workcenter_id.users_ids")
|
||||||
processing_panel = fields.Char('加工面')
|
processing_panel = fields.Char('加工面')
|
||||||
sequence = fields.Integer(string='工序')
|
sequence = fields.Integer(string='工序')
|
||||||
routing_type = fields.Selection([
|
routing_type = fields.Selection([
|
||||||
@@ -29,8 +31,26 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
('后置三元质量检测', '后置三元质量检测'),
|
('后置三元质量检测', '后置三元质量检测'),
|
||||||
('解除装夹', '解除装夹'),
|
('解除装夹', '解除装夹'),
|
||||||
], string="工序类型")
|
], string="工序类型")
|
||||||
|
|
||||||
|
@api.onchange('users_ids')
|
||||||
|
def get_user_permissions(self):
|
||||||
|
uid = self.env.uid
|
||||||
|
for workorder in self:
|
||||||
|
if workorder.users_ids:
|
||||||
|
list_user_id = []
|
||||||
|
for item in workorder.users_ids:
|
||||||
|
list_user_id.append(item.id)
|
||||||
|
if uid in list_user_id:
|
||||||
|
workorder.user_permissions = True
|
||||||
|
else:
|
||||||
|
workorder.user_permissions = False
|
||||||
|
else:
|
||||||
|
workorder.user_permissions = False
|
||||||
|
|
||||||
|
user_permissions = fields.Boolean('用户权限', compute='get_user_permissions')
|
||||||
programming_no = fields.Char('编程单号')
|
programming_no = fields.Char('编程单号')
|
||||||
is_programming = fields.Boolean('是否编程', default=False)
|
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='配料中心点')
|
||||||
@@ -106,7 +126,11 @@ 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
|
||||||
return self.material_center_point
|
# 将补偿值写入CNC加工工单
|
||||||
|
workorder = self.env['mrp.workorder'].browse(self.ids)
|
||||||
|
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]
|
||||||
|
|
||||||
def json_workorder_str(self, k, production, route):
|
def json_workorder_str(self, k, production, route):
|
||||||
workorders_values_str = [0, '', {
|
workorders_values_str = [0, '', {
|
||||||
@@ -116,6 +140,7 @@ 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,
|
||||||
@@ -233,35 +258,72 @@ class ResMrpWorkOrder(models.Model):
|
|||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
# def fetchCNCing(self):
|
||||||
|
# return None
|
||||||
|
|
||||||
# cnc程序获取
|
# cnc程序获取
|
||||||
def fetchCNC(self):
|
def fetchCNC(self):
|
||||||
cnc = self.env['mrp.workorder'].search(
|
try:
|
||||||
[('routing_type', '=', 'CNC加工'), ('production_id', '=', self.production_id.id)], limit=1)
|
cnc = self.env['mrp.workorder'].search(
|
||||||
res = {'model_code': cnc.product_id.barcode, 'production_no': self.production_id.name,
|
[('routing_type', '=', 'CNC加工'), ('production_id', '=', self.production_id.id)], limit=1)
|
||||||
'machine_tool_code': cnc.workcenter_id.machine_tool_id.code,
|
logging.info('fetchCNC-cnc:%s' % cnc)
|
||||||
'material_code': cnc.env['sf.production.materials'].search(
|
# if cnc.product_id.upload_model_file:
|
||||||
[('id', '=', cnc.product_id.materials_id.id)]).materials_no,
|
# logging.info('fetchCNC-upload_model_file:%s' % cnc.product_id.upload_model_file)
|
||||||
'material_type_code': cnc.env['sf.materials.model'].search(
|
# attachments = cnc.product_id.upload_model_file[0]
|
||||||
[('id', '=', cnc.product_id.materials_type_id.id)]).materials_no,
|
# logging.info('fetchCNC-attachment1:%s' % attachments)
|
||||||
'machining_precision': cnc.product_id.model_machining_precision,
|
# logging.info('fetchCNC-attachment1:%s' % cnc.product_id.upload_model_file[0])
|
||||||
'embryo_long': cnc.product_id.bom_ids.bom_line_ids.product_id.length,
|
# logging.info('fetchCNC-attachment2:%s' % cnc.product_id.upload_model_file[0].datas)
|
||||||
'embryo_height': cnc.product_id.bom_ids.bom_line_ids.product_id.height,
|
# logging.info('fetchCNC-attachment:%s' % attachments.datas)
|
||||||
'embryo_width': cnc.product_id.bom_ids.bom_line_ids.product_id.width,
|
# base64_data = base64.b64encode(attachments.datas)
|
||||||
'order_no': cnc.production_id.origin,
|
# logging.info('fetchCNC-attachment1:%s' % attachments)
|
||||||
'user': self.env.user.name,
|
# base64_datas = base64_data.decode('utf-8')
|
||||||
'model_file': base64.b64encode(cnc.product_id.model_file).decode('utf-8')
|
# model_code = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest()
|
||||||
}
|
# logging.info('fetchCNC-model_code:%s' % model_code)
|
||||||
logging.info('res:%s' % res)
|
logging.info('fetchCNC-model_code1:%s' % cnc.product_id.model_code)
|
||||||
configsettings = self.env['res.config.settings'].get_values()
|
res = {'model_code': '' if not cnc.product_id.model_code else cnc.product_id.model_code,
|
||||||
config_header = Common.get_headers(self, configsettings['token'], configsettings['sf_secret_key'])
|
'production_no': self.production_id.name,
|
||||||
url = '/api/intelligent_programming/create'
|
'machine_tool_code': cnc.workcenter_id.machine_tool_id.code,
|
||||||
config_url = configsettings['sf_url'] + url
|
'material_code': cnc.env['sf.production.materials'].search(
|
||||||
# res_str = json.dumps(res)
|
[('id', '=', cnc.product_id.materials_id.id)]).materials_no,
|
||||||
ret = requests.post(config_url, json={}, data=res, headers=config_header)
|
'material_type_code': cnc.env['sf.materials.model'].search(
|
||||||
ret = ret.json()
|
[('id', '=', cnc.product_id.materials_type_id.id)]).materials_no,
|
||||||
result = json.loads(ret['result'])
|
'machining_processing_panel': cnc.product_id.model_processing_panel,
|
||||||
if result['status'] == 1:
|
'machining_precision': cnc.product_id.model_machining_precision,
|
||||||
return self.write({'programming_no': result['programming_no'], 'is_programming': True})
|
'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_width': cnc.product_id.bom_ids.bom_line_ids.product_id.width,
|
||||||
|
'order_no': cnc.production_id.origin,
|
||||||
|
'user': self.env.user.name,
|
||||||
|
'model_file': '' if not cnc.product_id.model_file else base64.b64encode(
|
||||||
|
cnc.product_id.model_file).decode('utf-8')
|
||||||
|
}
|
||||||
|
logging.info('res:%s' % res)
|
||||||
|
configsettings = self.env['res.config.settings'].get_values()
|
||||||
|
config_header = Common.get_headers(self, configsettings['token'], configsettings['sf_secret_key'])
|
||||||
|
url = '/api/intelligent_programming/create'
|
||||||
|
config_url = configsettings['sf_url'] + url
|
||||||
|
# res_str = json.dumps(res)
|
||||||
|
ret = requests.post(config_url, json={}, data=res, headers=config_header)
|
||||||
|
ret = ret.json()
|
||||||
|
logging.info('fetchCNC-ret:%s' % ret)
|
||||||
|
if ret['status'] == 1:
|
||||||
|
self.write(
|
||||||
|
{'programming_no': ret['programming_no'], 'programming_state': '编程中', 'work_state': '编程中'})
|
||||||
|
else:
|
||||||
|
logging.info('fetchCNC-error:%s' % cnc)
|
||||||
|
raise UserError('行业资源库解析失败')
|
||||||
|
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, '', {
|
||||||
@@ -271,6 +333,7 @@ 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,
|
||||||
@@ -349,44 +412,73 @@ 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, obj):
|
def cnc_processing_create(self, cnc_workorder, ret):
|
||||||
workorder = self.env['mrp.workorder'].search([('production_id.name', '=', obj['production_order_no']),
|
for obj in ret['programming_list']:
|
||||||
('processing_panel', '=', obj['processing_panel']),
|
workorder = self.env['mrp.workorder'].search([('production_id.name', '=', ret['production_order_no']),
|
||||||
('routing_type', '=', 'CNC加工')])
|
('processing_panel', '=', obj['processing_panel']),
|
||||||
vals = {
|
('routing_type', '=', 'CNC加工')])
|
||||||
'workorder_id': workorder.id,
|
cnc_processing = self.env['sf.cnc.processing'].create({
|
||||||
'sequence_number': obj['sequence_number'],
|
'workorder_id': workorder.id,
|
||||||
'program_name': obj['program_name'],
|
'sequence_number': obj['sequence_number'],
|
||||||
'cutting_tool_name': obj['cutting_tool_name'],
|
'program_name': obj['program_name'],
|
||||||
'cutting_tool_no': obj['cutting_tool_no'],
|
'cutting_tool_name': obj['cutting_tool_name'],
|
||||||
'processing_type': obj['processing_type'],
|
'cutting_tool_no': obj['cutting_tool_no'],
|
||||||
'margin_x_y': obj['margin_x_y'],
|
'processing_type': obj['processing_type'],
|
||||||
'margin_z': obj['margin_z'],
|
'margin_x_y': obj['margin_x_y'],
|
||||||
'depth_of_processing_z': obj['depth_of_processing_z'],
|
'margin_z': obj['margin_z'],
|
||||||
'cutting_tool_extension_length': obj['cutting_tool_extension_length'],
|
'depth_of_processing_z': obj['depth_of_processing_z'],
|
||||||
'cutting_tool_handle_type': obj['cutting_tool_handle_type'],
|
'cutting_tool_extension_length': obj['cutting_tool_extension_length'],
|
||||||
'estimated_processing_time': obj['estimated_processing_time'],
|
'cutting_tool_handle_type': obj['cutting_tool_handle_type'],
|
||||||
'remark': obj['remark']
|
'estimated_processing_time': obj['estimated_processing_time'],
|
||||||
}
|
'remark': obj['remark']
|
||||||
return self.env['sf.cnc.processing'].create(vals)
|
})
|
||||||
|
self.get_cnc_processing_file(ret['folder_name'], cnc_processing)
|
||||||
|
cnc_workorder.state = 'done'
|
||||||
|
cnc_workorder.work_state = '已编程'
|
||||||
|
cnc_workorder.programming_state = '已编程'
|
||||||
|
cnc_workorder.time_ids.date_end = datetime.now()
|
||||||
|
|
||||||
|
def get_cnc_processing_file(self, folder_name, cnc_processing):
|
||||||
|
logging.info('folder_name:%s' % folder_name)
|
||||||
|
serverdir = os.path.join('/', folder_name, 'return', cnc_processing.processing_panel)
|
||||||
|
logging.info('serverdir:%s' % serverdir)
|
||||||
|
for root, dirs, files in os.walk(server_dir):
|
||||||
|
for f in files:
|
||||||
|
logging.info('f:%s' % f)
|
||||||
|
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_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(server_dir, root, f)
|
||||||
|
logging.info('cnc_file_path:%s' % cnc_file_path)
|
||||||
|
cnc_processing.with_user(request.env.ref("base.user_admin")).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, model_code, processing_panel):
|
def download_file_tmp(self, production_no, processing_panel):
|
||||||
remotepath = os.path.join('/', model_code, 'return', processing_panel)
|
remotepath = os.path.join('/', production_no, 'return', processing_panel)
|
||||||
serverdir = os.path.join('/tmp', model_code, 'return', processing_panel)
|
serverdir = os.path.join('/tmp', production_no, 'return', processing_panel)
|
||||||
ftp = FtpController()
|
ftp_resconfig = self.env['res.config.settings'].get_values()
|
||||||
ftp.download_file_tree(remotepath, serverdir)
|
ftp = FtpController(str(ftp_resconfig['ftp_host']), int(ftp_resconfig['ftp_port']), ftp_resconfig['ftp_user'],
|
||||||
return serverdir
|
ftp_resconfig['ftp_password'])
|
||||||
|
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):
|
||||||
|
|||||||
7
sf_manufacturing/models/res_user.py
Normal file
7
sf_manufacturing/models/res_user.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from odoo import SUPERUSER_ID, _, api, fields, models, registry
|
||||||
|
|
||||||
|
class Users(models.Model):
|
||||||
|
_inherit = 'res.users'
|
||||||
|
|
||||||
|
workcenter_ids = fields.Many2many("mrp.workcenter", 'users_workcenter')
|
||||||
@@ -66,25 +66,24 @@ class StockRule(models.Model):
|
|||||||
list2 = []
|
list2 = []
|
||||||
for item in procurements:
|
for item in procurements:
|
||||||
num = int(item[0].product_qty)
|
num = int(item[0].product_qty)
|
||||||
product = self.env['product.template'].search(
|
|
||||||
["&", ("name", '=', item[0].product_id.display_name), ('single_manufacturing', '!=', False)])
|
product = self.env['product.product'].search(
|
||||||
if product:
|
[("id", '=', item[0].product_id.id)])
|
||||||
|
product_tmpl = self.env['product.template'].search(
|
||||||
|
["&", ("id", '=', product.product_tmpl_id.id), ('single_manufacturing', "!=", False)])
|
||||||
|
if product_tmpl:
|
||||||
if num > 1:
|
if num > 1:
|
||||||
for no in range(1, num + 1):
|
for no in range(1, num + 1):
|
||||||
Procurement = namedtuple('Procurement', ['product_id', 'product_qty',
|
Procurement = namedtuple('Procurement', ['product_id', 'product_qty',
|
||||||
'product_uom', 'location_id', 'name', 'origin',
|
'product_uom', 'location_id', 'name', 'origin',
|
||||||
'company_id',
|
'company_id',
|
||||||
'values', 'model_file',
|
'values'])
|
||||||
'model_information'])
|
|
||||||
s = Procurement(product_id=item[0].product_id, product_qty=1.0, product_uom=item[0].product_uom,
|
s = Procurement(product_id=item[0].product_id, product_qty=1.0, product_uom=item[0].product_uom,
|
||||||
location_id=item[0].location_id,
|
location_id=item[0].location_id,
|
||||||
name=item[0].name,
|
name=item[0].name,
|
||||||
origin=item[0].origin,
|
origin=item[0].origin,
|
||||||
company_id=item[0].company_id,
|
company_id=item[0].company_id,
|
||||||
values=item[0].values,
|
values=item[0].values,
|
||||||
model_file=base64.b64decode(item[0].product_id.model_file),
|
|
||||||
model_information='%s/%s' % (item[0].product_id.model_processing_panel,
|
|
||||||
item[0].product_id.materials_id.name),
|
|
||||||
)
|
)
|
||||||
item1 = list(item)
|
item1 = list(item)
|
||||||
item1[0] = s
|
item1[0] = s
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import base64
|
import base64
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from odoo import api, fields, models, SUPERUSER_ID, _
|
from odoo import api, fields, models, SUPERUSER_ID, _
|
||||||
# from pystrich.code128 import Code128Encoder
|
#from pystrich.code128 import Code128Encoder
|
||||||
|
|
||||||
|
|
||||||
class Tray(models.Model):
|
class Tray(models.Model):
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
<form string="模型类型">
|
<form string="模型类型">
|
||||||
<group>
|
<group>
|
||||||
<field name="name" required="1"/>
|
<field name="name" required="1"/>
|
||||||
<field name="embryo_tolerance" string="胚料容余(mm)"/>
|
<field name="embryo_tolerance" required="1"/>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<field name='routing_tmpl_ids'>
|
<field name='routing_tmpl_ids'>
|
||||||
|
|||||||
@@ -24,14 +24,16 @@
|
|||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record id="mrp_workcenter_view_kanban_inherit_workorder" model="ir.ui.view">
|
<record id="mrp_workcenter_view_kanban_inherit_workorder" model="ir.ui.view">
|
||||||
<field name="name">mrp.workcenter.view.kanban.inherit.mrp.workorder</field>
|
<field name="name">mrp.workcenter.view.kanban.inherit.mrp.workorder</field>
|
||||||
<field name="model">mrp.workcenter</field>
|
<field name="model">mrp.workcenter</field>
|
||||||
<field name="inherit_id" ref="mrp.mrp_workcenter_kanban"/>
|
<field name="inherit_id" ref="mrp.mrp_workcenter_kanban"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<!-- Desktop view -->
|
<!-- Desktop view -->
|
||||||
<xpath expr="//div[@name='o_wo']" position="inside">
|
<xpath expr="//div[@name='o_wo']" position="inside">
|
||||||
<button class="btn btn-secondary fa fa-desktop" name="action_work_order" type="object" context="{'search_default_ready': 1, 'search_default_progress': 1, 'search_default_pending': 1, 'desktop_list_view': 1, 'search_default_workcenter_id': active_id}" title="Work orders" aria-label="Work orders"/>
|
<button class="btn btn-secondary fa fa-desktop" name="action_work_order" type="object"
|
||||||
|
context="{'search_default_ready': 1, 'search_default_progress': 1, 'search_default_pending': 1, 'desktop_list_view': 1, 'search_default_workcenter_id': active_id}"
|
||||||
|
title="Work orders" aria-label="Work orders"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
@@ -39,25 +41,46 @@
|
|||||||
<!-- override to change the no content image -->
|
<!-- override to change the no content image -->
|
||||||
<record id="mrp.action_work_orders" model="ir.actions.act_window">
|
<record id="mrp.action_work_orders" model="ir.actions.act_window">
|
||||||
<field name="help" type="html">
|
<field name="help" type="html">
|
||||||
<p class="o_view_nocontent_workorder">
|
<p class="o_view_nocontent_workorder">
|
||||||
No work orders to do!
|
No work orders to do!
|
||||||
</p><p>
|
</p>
|
||||||
Work orders are operations to do as part of a manufacturing order.
|
<p>
|
||||||
Operations are defined in the bill of materials or added in the manufacturing order directly.
|
Work orders are operations to do as part of a manufacturing order.
|
||||||
</p><p>
|
Operations are defined in the bill of materials or added in the manufacturing order directly.
|
||||||
Use the table work center control panel to register operations in the shop floor directly.
|
</p>
|
||||||
The tablet provides worksheets for your workers and allow them to scrap products, track time,
|
<p>
|
||||||
launch a maintenance request, perform quality tests, etc.
|
Use the table work center control panel to register operations in the shop floor directly.
|
||||||
</p>
|
The tablet provides worksheets for your workers and allow them to scrap products, track time,
|
||||||
|
launch a maintenance request, perform quality tests, etc.
|
||||||
|
</p>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
<record id="mrp_workcenter_kanban_action1" model="ir.actions.act_window">
|
||||||
|
<field name="name">Work Centers Overview</field>
|
||||||
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
<field name="res_model">mrp.workcenter</field>
|
||||||
|
<field name="view_mode">kanban,form</field>
|
||||||
|
<field name="view_id" ref="mrp.mrp_workcenter_kanban"/>
|
||||||
|
<field name="search_view_id" ref="mrp.view_mrp_workcenter_search"/>
|
||||||
|
<field name="domain">[('users_ids','in',uid)]</field>
|
||||||
|
<field name="help" type="html">
|
||||||
|
<p class="o_view_nocontent_smiling_face">
|
||||||
|
Create a new work center
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Manufacturing operations are processed at Work Centers. A Work Center can be composed of
|
||||||
|
workers and/or machines, they are used for costing, scheduling, capacity planning, etc.
|
||||||
|
They can be defined via the configuration menu.
|
||||||
|
</p>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<menuitem id="menu_mrp_dashboard"
|
<menuitem id="menu_mrp_dashboard"
|
||||||
name="工作中心概述"
|
name="工作中心概述"
|
||||||
action="mrp.mrp_workcenter_kanban_action"
|
action="mrp_workcenter_kanban_action1"
|
||||||
groups="mrp.group_mrp_routings"
|
groups="mrp.group_mrp_routings"
|
||||||
parent="mrp.menu_mrp_root"
|
parent="mrp.menu_mrp_root"
|
||||||
sequence="5"/>
|
sequence="5"/>
|
||||||
|
|
||||||
<!-- MRP.WORKCENTER -->
|
<!-- MRP.WORKCENTER -->
|
||||||
<record model="ir.ui.view" id="view_mrp_workcenter_form_inherit_sf">
|
<record model="ir.ui.view" id="view_mrp_workcenter_form_inherit_sf">
|
||||||
@@ -79,6 +102,9 @@
|
|||||||
</field>
|
</field>
|
||||||
</page>
|
</page>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
<xpath expr="//field[@name='company_id']" position="after">
|
||||||
|
<field name="users_ids" widget="many2many_tags" string="可操作用户"/>
|
||||||
|
</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" domain="[('is_binding', '=', False)]"/>
|
||||||
|
|||||||
@@ -7,10 +7,30 @@
|
|||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<field name="name" position="before">
|
<field name="name" position="before">
|
||||||
<field name="sequence"/>
|
<field name="sequence"/>
|
||||||
|
<field name='user_permissions'/>
|
||||||
</field>
|
</field>
|
||||||
<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">
|
||||||
|
<attribute name="attrs">{'invisible': ['|', '|', '|','|', ('production_state','in', ('draft', 'done',
|
||||||
|
'cancel')), ('working_state', '=', 'blocked'), ('state', 'in', ('done', 'cancel')),
|
||||||
|
('is_user_working', '!=', False),("user_permissions","=",False)]}
|
||||||
|
</attribute>
|
||||||
|
</xpath>
|
||||||
|
<!-- <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)]}"/>-->
|
||||||
|
<!-- <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)]}"/>-->
|
||||||
|
<!-- <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)]}"/>-->
|
||||||
|
<tree position="attributes">
|
||||||
|
<attribute name="multi_edit"></attribute>
|
||||||
|
<attribute name="editable"></attribute>
|
||||||
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
@@ -57,15 +77,27 @@
|
|||||||
<field name="model">mrp.workorder</field>
|
<field name="model">mrp.workorder</field>
|
||||||
<field name="inherit_id" ref="mrp.mrp_production_workorder_form_view_inherit"/>
|
<field name="inherit_id" ref="mrp.mrp_production_workorder_form_view_inherit"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<field name="production_id" position="after">
|
<xpath expr="field[@name='is_user_working']" position="before">
|
||||||
<field name="programming_no" readonly="1"
|
<field name='user_permissions' invisible="1"/>
|
||||||
attrs='{"invisible": [("routing_type","!=","获取CNC加工程序")]}'/>
|
</xpath>
|
||||||
</field>
|
|
||||||
|
|
||||||
<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加工程序")]}'>
|
||||||
<div class="col-12 col-lg-6 o_setting_box">
|
<group>
|
||||||
<button type="object" class="oe_highlight" name="fetchCNC" string="获取CNC程序代码"/>
|
<field name="programming_no" readonly="1"
|
||||||
</div>
|
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程序代码"
|
||||||
|
attrs='{"invisible": [("user_permissions","=",False)]}'/>
|
||||||
|
<button type="object" class="oe_highlight disabled" name="fetchCNC" string="获取CNC程序代码"
|
||||||
|
attrs='{"invisible": ["|",("programming_no","=",False),("programming_no","=",False)]}'/>
|
||||||
|
</div>
|
||||||
|
</group>
|
||||||
</page>
|
</page>
|
||||||
|
|
||||||
</xpath>
|
</xpath>
|
||||||
@@ -189,7 +221,8 @@
|
|||||||
</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="getcenter" string="计算定位"/>
|
<button type="object" class="oe_highlight" name="getcenter" string="计算定位"
|
||||||
|
attrs='{"invisible": [("user_permissions","=",False)]}'/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<group>
|
<group>
|
||||||
@@ -231,7 +264,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="检测确认"/>
|
string="检测确认" attrs='{"invisible": [("user_permissions","=",False)]}'/>
|
||||||
</div>
|
</div>
|
||||||
</page>
|
</page>
|
||||||
</xpath>
|
</xpath>
|
||||||
@@ -239,11 +272,12 @@
|
|||||||
<page string="解除装夹" attrs='{"invisible": [("routing_type","!=","解除装夹")]}'>
|
<page string="解除装夹" attrs='{"invisible": [("routing_type","!=","解除装夹")]}'>
|
||||||
|
|
||||||
<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)]}'/>
|
||||||
</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="打印标签"/>
|
string="打印标签" attrs='{"invisible": [("user_permissions","=",False)]}'/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</page>
|
</page>
|
||||||
|
|||||||
BIN
sf_manufacturing1.zip
Normal file
BIN
sf_manufacturing1.zip
Normal file
Binary file not shown.
@@ -20,44 +20,55 @@ 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'])
|
||||||
for obj in ret:
|
# 查询状态为进行中且类型为获取CNC加工程序的工单
|
||||||
cnc = request.env['sf.cnc.processing'].with_user(
|
cnc_workorder = self.env['mrp.workorder'].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)
|
logging.info('download_state:%s' % download_state)
|
||||||
# cnc.with_user(request.env.ref("base.user_admin")).write_file(cnc_file_path, cnc)
|
# i += 1
|
||||||
logging.info('server_dir:%s' % server_dir)
|
if download_state == False:
|
||||||
for root, dirs, files in os.walk(server_dir):
|
res = {'status': -2, 'message': 'cnc文件拉取失败'}
|
||||||
for f in files:
|
return json.JSONEncoder().encode(res)
|
||||||
logging.info('f:%s' % f)
|
request.env['sf.cnc.processing'].with_user(
|
||||||
logging.info('f[0]:%s' % f.split('.')[0])
|
request.env.ref("base.user_admin")).cnc_processing_create(ret)
|
||||||
if os.path.splitext(f)[1] == ".pdf":
|
return json.JSONEncoder().encode(res)
|
||||||
full_path = os.path.join(server_dir, root, f)
|
else:
|
||||||
logging.info('pdf:%s' % full_path)
|
res = {'status': 0, 'message': '该制造订单暂未开始'}
|
||||||
if full_path != False:
|
return json.JSONEncoder().encode(res)
|
||||||
if not cnc.workorder_id.cnc_worksheet:
|
except Exception as e:
|
||||||
cnc.workorder_id.cnc_worksheet = base64.b64encode(open(full_path, 'rb').read())
|
res = {'status': -1, 'message': '系统解析失败'}
|
||||||
else:
|
logging.info('get_cnc_processing_create error:%s' % e)
|
||||||
logging.info('break:%s' % 'break')
|
return json.JSONEncoder().encode(res)
|
||||||
continue
|
|
||||||
else:
|
@http.route('/api/cnc_processing/update_state', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||||
logging.info('cnc.program_name:%s' % cnc.program_name)
|
cors="*")
|
||||||
if cnc.program_name == f.split('.')[0]:
|
def get_cnc_processing_state(self, **kw):
|
||||||
logging.info('f[0]:%s' % f[0])
|
"""
|
||||||
cnc_file_path = os.path.join(server_dir, root, f)
|
获取mrs下发的编程单的状态
|
||||||
logging.info('cnc_file_path:%s' % cnc_file_path)
|
:param kw:
|
||||||
cnc.with_user(request.env.ref("base.user_admin")).write_file(cnc_file_path, cnc)
|
:return:
|
||||||
else:
|
"""
|
||||||
continue
|
logging.info('get_cnc_processing_state:%s' % kw)
|
||||||
|
try:
|
||||||
|
res = {'status': 1, 'message': '成功'}
|
||||||
|
datas = request.httprequest.data
|
||||||
|
ret = json.loads(datas)
|
||||||
|
ret = json.loads(ret['result'])
|
||||||
|
cnc_processing = request.env['sf.cnc.processing'].with_user(
|
||||||
|
request.env.ref("base.user_admin")).cnc_processing_create(ret['programming_list'],
|
||||||
|
ret['production_order_no'])
|
||||||
|
|
||||||
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)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class FtpController():
|
|||||||
|
|
||||||
ftp = FTP()
|
ftp = FTP()
|
||||||
|
|
||||||
def __init__(self, host="192.168.50.202", port=21, username="ftpuser", password="123456"):
|
def __init__(self, host, port, username, password):
|
||||||
try:
|
try:
|
||||||
self.ftp.connect(host, port)
|
self.ftp.connect(host, port)
|
||||||
self.ftp.login(username, password)
|
self.ftp.login(username, password)
|
||||||
@@ -27,17 +27,18 @@ class FtpController():
|
|||||||
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:
|
||||||
self.ftp.cwd(target_dir) # 切换工作路径
|
self.ftp.cwd(target_dir) # 切换工作路径
|
||||||
remotenames = self.ftp.nlst()
|
remotenames = self.ftp.nlst()
|
||||||
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)
|
||||||
else:
|
except:
|
||||||
return
|
return False
|
||||||
|
|
||||||
# 下载指定目录下的指定文件
|
# 下载指定目录下的指定文件
|
||||||
def download_file(self, serverfile, remotefile):
|
def download_file(self, serverfile, remotefile):
|
||||||
file_handler = open(serverfile, 'wb')
|
file_handler = open(serverfile, 'wb')
|
||||||
self.ftp.retrbinary('RETR ' + remotefile, file_handler.write)
|
self.ftp.retrbinary('RETR ' + remotefile, file_handler.write)
|
||||||
file_handler.close()
|
file_handler.close()
|
||||||
|
|||||||
@@ -12,8 +12,12 @@ class ResConfigSettings(models.TransientModel):
|
|||||||
_inherit = 'res.config.settings'
|
_inherit = 'res.config.settings'
|
||||||
|
|
||||||
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()
|
||||||
@@ -40,8 +44,6 @@ 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):
|
||||||
"""
|
"""
|
||||||
@@ -53,11 +55,19 @@ 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
|
||||||
|
|
||||||
@@ -67,4 +77,7 @@ 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 "")
|
||||||
|
|||||||
@@ -14,22 +14,49 @@
|
|||||||
<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="token"/>
|
<label for="sf_url"/>
|
||||||
<field name="token" />
|
<field name="sf_url"/>
|
||||||
|
</div>
|
||||||
|
<div class="text-muted">
|
||||||
|
<label for="token" string="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>
|
||||||
<div class="text-muted">
|
<div class="col-12 col-lg-6 o_setting_box">
|
||||||
<label for="sf_url"/>
|
<button type="object" class="oe_highlight" name="sf_all_sync"
|
||||||
<field name="sf_url"/>
|
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="col-12 col-lg-6 o_setting_box">
|
||||||
<button type="object" class="oe_highlight" name="sf_all_sync" string="同步资源库所有基础数据"
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user