diff --git a/sf_manufacturing/controllers/controllers.py b/sf_manufacturing/controllers/controllers.py
index c548222a..63fd4f57 100644
--- a/sf_manufacturing/controllers/controllers.py
+++ b/sf_manufacturing/controllers/controllers.py
@@ -238,7 +238,7 @@ class Manufacturing_Connect(http.Controller):
workorder = request.env['mrp.workorder'].sudo().search(
[('production_id', '=', production_id), ('routing_type', '=', routing_type)], limit=1)
if workorder:
- workorder.test_result = ret['Quality']
+ # workorder.test_results = ret['Quality']
logging.info('制造订单:%s' % workorder.production_id.name)
if 'ReportPaht' in ret:
download_state = request.env['mrp.workorder'].with_user(
@@ -261,8 +261,7 @@ class Manufacturing_Connect(http.Controller):
('picking_id', '=', stock_picking.id)])
if quality_check:
logging.info('质检单:%s' % quality_check.name)
- quality_check.write({'report_pdf': workorder.detection_report,
- 'report_result': workorder.test_result})
+ quality_check.write({'report_pdf': workorder.detection_report})
elif download_state == 2:
res = {'Succeed': False, 'ErrorCode': 205,
'Error': 'ReportPaht中的工件号与制造订单%s不匹配,请检查ReportPaht是否正确' % workorder.production_id.name}
diff --git a/sf_manufacturing/data/stock_data.xml b/sf_manufacturing/data/stock_data.xml
index 6bd0fe53..72559691 100644
--- a/sf_manufacturing/data/stock_data.xml
+++ b/sf_manufacturing/data/stock_data.xml
@@ -67,5 +67,21 @@
search="[('barcode','=','WH-PREPRODUCTION')]"/>
+
+
+ 表面工艺外协
+
+ True
+ 11
+
+
+
+
+
+
+
+
+
+
diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py
index 3b6e8ead..81580db7 100644
--- a/sf_manufacturing/models/mrp_workorder.py
+++ b/sf_manufacturing/models/mrp_workorder.py
@@ -98,7 +98,8 @@ class ResMrpWorkOrder(models.Model):
Y10_axis = fields.Float(default=0)
Z10_axis = fields.Float(default=0)
X_deviation_angle = fields.Integer(string="X轴偏差度", default=0)
- test_result = fields.Char("检测结果")
+ test_results = fields.Selection([("合格", "合格"), ("返工", "返工"), ("报废", "报废")], default='合格',
+ string="检测结果")
cnc_ids = fields.One2many("sf.cnc.processing", 'workorder_id', string="CNC加工程序")
cmm_ids = fields.One2many("sf.cmm.program", 'workorder_id', string="CMM程序")
tray_code = fields.Char(string="托盘编码")
@@ -143,6 +144,7 @@ class ResMrpWorkOrder(models.Model):
production_line_state = fields.Selection(related='production_id.production_line_state',
string='上/下产线', store=True)
detection_report = fields.Binary('检测报告', readonly=True)
+ is_remanufacture = fields.Boolean(string='是否重新生成制造订单', default=True)
def get_plan_workorder(self, production_line):
tomorrow = (date.today() + timedelta(days=+1)).strftime("%Y-%m-%d")
@@ -446,7 +448,7 @@ class ResMrpWorkOrder(models.Model):
"""
重新生成制造订单或者重新生成工单
"""
- if self.test_result == '报废':
+ if self.test_results == '报废':
values = self.env['mrp.production'].create_production1_values(self.production_id)
productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company(
self.production_id.company_id).create(
@@ -478,7 +480,7 @@ class ResMrpWorkOrder(models.Model):
'mail.message_origin_link',
values={'self': production, 'origin': origin_production},
subtype_id=self.env.ref('mail.mt_note').id)
- if self.test_result == '返工':
+ if self.test_results == '返工':
productions = self.production_id
# self.env['stock.move'].sudo().create(productions._get_moves_raw_values())
# self.env['stock.move'].sudo().create(productions._get_moves_finished_values())
@@ -608,6 +610,8 @@ class ResMrpWorkOrder(models.Model):
if self.routing_type == '装夹预调':
if not self.material_center_point and self.X_deviation_angle > 0:
raise UserError("请对前置三元检测定位参数进行计算定位")
+ if not self.rfid_code:
+ raise UserError("请扫RFID码进行绑定")
if self.picking_out_id:
picking_out = self.env['stock.picking'].search([('id', '=', self.picking_out_id.id)])
if picking_out.workorder_out_id:
@@ -849,6 +853,38 @@ class SfWorkOrderBarcodes(models.Model):
for item in workorder_rfid:
item.write({'rfid_code': barcode})
else:
+ embryo_stock_lot = self.env['stock.lot'].search([('name', '=', barcode)])
+ if embryo_stock_lot:
+ embryo_stock_move_line = self.env['stock.move.line'].search(
+ [('product_id', '=', embryo_stock_lot.product_id.id),
+ ('reference', '=', workorder.production_id.name),
+ ('lot_id', '=', embryo_stock_lot.id),
+ ('product_category_name', '=', '坯料')])
+ if embryo_stock_move_line:
+ bom_production = self.env['mrp.production'].search(
+ [('product_id', '=', embryo_stock_lot.product_id.id),
+ ('origin', '=', workorder.production_id.name)], limit=1, order='id asc')
+ workpiece_delivery = self.env['sf.workpiece.delivery'].search(
+ [('workorder_id', '=', workorder.id)], limit=1, order='id asc')
+ if workpiece_delivery:
+ embryo_workpiece_code = workpiece_delivery.workpiece_code
+ if bom_production:
+ if workpiece_delivery.workpiece_code and bom_production.name not in \
+ workpiece_delivery.workpiece_code:
+ embryo_workpiece_code = workpiece_delivery.workpiece_code + ',' + \
+ bom_production.name
+ if not workpiece_delivery.workpiece_code:
+ embryo_workpiece_code = bom_production.name
+ workpiece_delivery.write({'workpiece_code': embryo_workpiece_code})
+ else:
+ raise UserError('工件生产线不一致,请重新确认')
+ else:
+ workorder_rfid = self.env['mrp.workorder'].search(
+ [('production_id', '=', workorder.production_id.id)])
+ if workorder_rfid:
+ for item in workorder_rfid:
+ if item.state == "progress":
+ item.write({'rfid_code': barcode})
raise UserError('该托盘信息不存在!!!')
# stock_move_line = self.env['stock.move.line'].search([('lot_name', '=', barcode)])
# if stock_move_line.product_id.categ_type == '夹具':
diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py
index 1489cddd..f3cba150 100644
--- a/sf_manufacturing/models/product_template.py
+++ b/sf_manufacturing/models/product_template.py
@@ -6,11 +6,11 @@ import os
from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
from odoo.modules import get_resource_path
-
from OCC.Extend.DataExchange import read_step_file
from OCC.Extend.DataExchange import write_stl_file
+
class ResProductMo(models.Model):
_inherit = 'product.template'
diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py
index 5833b095..80a334ce 100644
--- a/sf_manufacturing/models/stock.py
+++ b/sf_manufacturing/models/stock.py
@@ -17,6 +17,50 @@ from io import BytesIO
from odoo.exceptions import ValidationError
+class stockWarehouse(models.Model):
+ _inherit = 'stock.warehouse'
+
+ subcontracting_surface_technology_pull_out_id = fields.Many2one(
+ 'stock.rule', '表面工艺规则1')
+ subcontracting_surface_technology_pull_in_id = fields.Many2one(
+ 'stock.rule', '表面工艺规则2'
+ )
+
+ def _get_global_route_rules_values(self):
+ rules = super(stockWarehouse, self)._get_global_route_rules_values()
+ location_virtual_id = self.env.ref(
+ 'sf_manufacturing.stock_location_locations_virtual_outcontract').id,
+ location_pre_id = self.env['stock.location'].search(
+ [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id,
+ rules.update({
+ 'subcontracting_surface_technology_pull_in_id': {
+ 'create_values': {
+ 'action': 'pull',
+ 'picking_type_id': self.env.ref('sf_manufacturing.outcontract_picking_in').id,
+ 'group_propagation_option': 'none',
+ 'company_id': self.company_id.id,
+ 'location_src_id': location_virtual_id,
+ 'location_dest_id': location_pre_id,
+ 'route_id': self._find_global_route('sf_manufacturing.route_surface_technology_outsourcing',
+ _('表面工艺外协')).id,
+ }
+ },
+ 'subcontracting_surface_technology_pull_out_id': {
+ 'create_values': {
+ 'action': 'pull',
+ 'picking_type_id': self.env.ref('sf_manufacturing.outcontract_picking_out').id,
+ 'group_propagation_option': 'none',
+ 'company_id': self.company_id.id,
+ 'location_src_id': location_pre_id,
+ 'location_dest_id': location_virtual_id,
+ 'route_id': self._find_global_route('sf_manufacturing.route_surface_technology_outsourcing',
+ _('表面工艺外协')).id,
+ }
+ }
+ })
+ return rules
+
+
class StockRule(models.Model):
_inherit = 'stock.rule'
diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml
index b1ca9946..9a747791 100644
--- a/sf_manufacturing/views/mrp_workorder_view.xml
+++ b/sf_manufacturing/views/mrp_workorder_view.xml
@@ -104,18 +104,14 @@
-
+
+ groups="sf_base.group_sf_mrp_user"/>
+ groups="sf_base.group_sf_mrp_user" confirm="是否确认完工"/>
+
@@ -436,16 +433,17 @@
-
+
+
-
-
-
+
+
+
+
+
diff --git a/sf_mrs_connect/models/res_config_setting.py b/sf_mrs_connect/models/res_config_setting.py
index cbefba19..f34ab06f 100644
--- a/sf_mrs_connect/models/res_config_setting.py
+++ b/sf_mrs_connect/models/res_config_setting.py
@@ -13,10 +13,11 @@ class ResConfigSettings(models.TransientModel):
token = fields.Char(string='TOKEN', default='b811ac06-3f00-11ed-9aed-0242ac110003')
sf_secret_key = fields.Char(string='密钥', default='wBmxej38OkErKhD6')
sf_url = fields.Char(string='访问地址', default='https://sf.cs.jikimo.com')
- agv_rcms_url = fields.Char(string='avg_rcms访问地址',
- default='http://IP:PORT/rcms/services/rest/hikRpcService/genAgvSchedulingTask')
- agv_rcs_url = fields.Char(string='avg_rcs访问地址', default='http://IP:PORT/xxx/agv/agvCallbackService/agvCallback')
+ agv_rcs_url = fields.Char(string='avg_rcs访问地址',
+ default='http://172.16.10.114:8182/rcms/services/rest/hikRpcService/genAgvSchedulingTask')
wbcode = fields.Char('地码')
+ agv_code = fields.Char(string='agv编号')
+ task_type_no = fields.Char('任务单类型编号')
model_parser_url = fields.Char('特征识别路径')
ftp_host = fields.Char(string='FTP的ip')
ftp_port = fields.Char(string='FTP端口')
@@ -95,8 +96,9 @@ class ResConfigSettings(models.TransientModel):
token = config.get_param('token', default='')
sf_secret_key = config.get_param('sf_secret_key', default='')
sf_url = config.get_param('sf_url', default='')
- agv_rcms_url = config.get_param('agv_rcms_url', default='')
agv_rcs_url = config.get_param('agv_rcs_url', default='')
+ agv_code = config.get_param('agv_code', default='')
+ task_type_no = config.get_param('task_type_no', 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='')
@@ -106,8 +108,9 @@ class ResConfigSettings(models.TransientModel):
token=token,
sf_secret_key=sf_secret_key,
sf_url=sf_url,
- agv_rcms_url=agv_rcms_url,
agv_rcs_url=agv_rcs_url,
+ agv_code=agv_code,
+ task_type_no=task_type_no,
ftp_host=ftp_host,
ftp_port=ftp_port,
ftp_user=ftp_user,
@@ -121,9 +124,18 @@ class ResConfigSettings(models.TransientModel):
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_url", self.sf_url or "")
- ir_config.set_param("agv_rcms_url", self.agv_rcms_url or "")
ir_config.set_param("agv_rcs_url", self.agv_rcs_url or "")
+ ir_config.set_param("agv_code", self.agv_code or "")
+ ir_config.set_param("task_type_no", self.task_type_no 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 "")
+
+
+class ResAgvSite(models.Model):
+ _name = 'res.agv.site'
+ _description = 'agv站点'
+
+ type = fields.Selection([('00', '位置编号'), ('01', '库区编号'), ('02', '货架编号')], '类型')
+ content = fields.Char('内容')
diff --git a/sf_mrs_connect/security/ir.model.access.csv b/sf_mrs_connect/security/ir.model.access.csv
index 0ed43a62..f512ec84 100644
--- a/sf_mrs_connect/security/ir.model.access.csv
+++ b/sf_mrs_connect/security/ir.model.access.csv
@@ -1,5 +1,6 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_sf_static_resource_datasync,sf_static_resource_datasync,model_sf_static_resource_datasync,base.group_user,1,1,1,1
+access_res_agv_site,access_res_agv_site,model_res_agv_site,base.group_system,1,1,1,1
diff --git a/sf_mrs_connect/views/res_config_settings_views.xml b/sf_mrs_connect/views/res_config_settings_views.xml
index 5f457b4f..e297f0eb 100644
--- a/sf_mrs_connect/views/res_config_settings_views.xml
+++ b/sf_mrs_connect/views/res_config_settings_views.xml
@@ -1,6 +1,26 @@
+
+ agv站点集合
+ res.agv.site
+
+
+
+
+
+
+
+
+
+ 站点集合
+ res.agv.site
+ tree
+
+
+
+
res.config.settings.view.form.inherit.sf_sync
res.config.settings
@@ -84,10 +104,22 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sf_sale/models/__init__.py b/sf_sale/models/__init__.py
index 99b143c7..97400237 100644
--- a/sf_sale/models/__init__.py
+++ b/sf_sale/models/__init__.py
@@ -1,5 +1,6 @@
from . import sale_order
-from . import quick_easy_order
+# from . import quick_easy_order
+from . import quick_easy_order_old
from . import auto_quatotion_common
from . import parser_and_calculate_work_time
from . import preload_datas_functions
diff --git a/sf_sale/models/auto_quatotion_common.py b/sf_sale/models/auto_quatotion_common.py
index 4feaa7dd..104cd50c 100644
--- a/sf_sale/models/auto_quatotion_common.py
+++ b/sf_sale/models/auto_quatotion_common.py
@@ -2,7 +2,7 @@
import logging
from odoo.modules import get_resource_path
from odoo import fields, models, api
-from quatotion import readSql, feature_recognize, auto_quatotion
+# from quatotion import readSql, feature_recognize, auto_quatotion
__author__ = 'jinling.yang'
_logger = logging.getLogger(__name__)
diff --git a/sf_sale/models/quick_easy_order.py b/sf_sale/models/quick_easy_order.py
index 1ece6b86..ed52d9de 100644
--- a/sf_sale/models/quick_easy_order.py
+++ b/sf_sale/models/quick_easy_order.py
@@ -8,8 +8,8 @@ from datetime import datetime
import requests
from odoo import http
from odoo.http import request
-from OCC.Extend.DataExchange import read_step_file
-from OCC.Extend.DataExchange import write_stl_file
+# from OCC.Extend.DataExchange import read_step_file
+# from OCC.Extend.DataExchange import write_stl_file
from odoo import models, fields, api
from odoo.modules import get_resource_path
from odoo.exceptions import ValidationError, UserError
diff --git a/sf_sale/models/quick_easy_order_old.py b/sf_sale/models/quick_easy_order_old.py
new file mode 100644
index 00000000..28618488
--- /dev/null
+++ b/sf_sale/models/quick_easy_order_old.py
@@ -0,0 +1,326 @@
+import logging
+import base64
+import hashlib
+import os
+import platform
+import json
+from datetime import datetime
+import requests
+from odoo import http
+from odoo.http import request
+from OCC.Extend.DataExchange import read_step_file
+from OCC.Extend.DataExchange import write_stl_file
+from odoo import models, fields, api
+from odoo.modules import get_resource_path
+from odoo.exceptions import ValidationError, UserError
+from odoo.addons.sf_base.commons.common import Common
+from . import parser_and_calculate_work_time as pc
+
+
+class QuickEasyOrder(models.Model):
+ _name = 'quick.easy.order'
+ _description = '简易下单'
+ _order = 'id desc'
+
+ name = fields.Char('订单编号', default=lambda self: self.env['ir.sequence'].next_by_code('quick.easy.order'))
+ model_length = fields.Float('长(mm)', digits=(16, 3))
+ model_width = fields.Float('宽(mm)', digits=(16, 3))
+ model_height = fields.Float('高(mm)', digits=(16, 3))
+ model_volume = fields.Float('体积(mm³)', digits=(16, 3))
+ model_processing_side = fields.Char('加工面', default='A')
+ model_feature = fields.Char('特征')
+ machining_precision = fields.Selection([
+ ('0.10', '±0.10mm'),
+ ('0.05', '±0.05mm'),
+ ('0.03', '±0.03mm'),
+ ('0.02', '±0.02mm'),
+ ('0.01', '±0.01mm')], string='加工精度', default='0.10')
+ material_id = fields.Many2one('sf.production.materials', '材料')
+ material_model_id = fields.Many2one('sf.materials.model', '型号')
+ # process_id = fields.Many2one('sf.production.process', string='表面工艺')
+ parameter_ids = fields.Many2many('sf.production.process.parameter', 'process_item_order_rel', string='可选参数')
+ quantity = fields.Integer('数量', default=1)
+ unit_price = fields.Float('单价')
+ price = fields.Float('总价')
+ model_file = fields.Binary('glb模型文件')
+ upload_model_file = fields.Many2many('ir.attachment', 'upload_qf_model_file_attachment_ref', string='上传模型文件')
+ delivery_time = fields.Date('交货日期')
+ customer_id = fields.Many2one('res.partner', string='客户', default=lambda self: self.env.user.partner_id.id)
+ state = fields.Selection([('草稿', '草稿'), ('待派单', '待派单'),
+ ('待接单', '待接单'), ('加工中', '加工中'),
+ ('物流中', '物流中'), ('已交付', '已交付')], string='订单状态', default='草稿',
+ readonly=True)
+ model_color_state = fields.Selection([
+ ('success', '成功'),
+ ('fail', '失败')], string='模型上色状态')
+ processing_time = fields.Integer('加工时长(min)')
+
+ @api.depends('unit_price', 'quantity')
+ def _compute_total_amount(self):
+ for item in self:
+ item.price = item.unit_price * item.quantity
+
+ @api.depends('material_id', 'material_model_id')
+ def _compute_material_model(self):
+ for item in self:
+ materials = self.env['sf.production.materials'].search([], limit=1, order='id desc')
+ item.material_id = materials.id
+ item.material_model_id = self.env['sf.materials.model'].search(
+ [('materials_id', '=', materials.id)],
+ limit=1, order='id desc')
+
+ @api.model
+ def create(self, vals):
+ if vals.get('upload_model_file'):
+ logging.info('create-attachment:%s' % vals['upload_model_file'][0])
+ for item in vals['upload_model_file']:
+ print(len(item[2]))
+ if len(item[2]) > 0:
+ logging.info('create-attachment:%s' % int(item[2][0]))
+ attachment = self.env['ir.attachment'].sudo().search([('id', '=', int(item[2][0]))])
+ base64_data = base64.b64encode(attachment.datas)
+ base64_datas = base64_data.decode('utf-8')
+ model_code = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest()
+ report_path = attachment._full_path(attachment.store_fname)
+ vals['model_file'] = self.transition_glb_file(report_path, model_code)
+ logging.info('create-model_file:%s' % len(vals['model_file']))
+ obj = super(QuickEasyOrder, self).create(vals)
+ self.model_coloring(obj)
+ logging.info('---------开始派单到工厂-------')
+ self.distribute_to_factory(obj)
+ obj.state = '待接单'
+ return obj
+
+ # 将attach的datas内容转为glb文件
+ def transition_glb_file(self, report_path, model_code):
+ shapes = read_step_file(report_path)
+ output_file = os.path.join('/tmp', str(model_code) + '.stl')
+ write_stl_file(shapes, output_file, 'binary', 0.03, 0.5)
+ # 转化为glb
+ output_glb_file = os.path.join('/tmp', str(model_code) + '.glb')
+ util_path = get_resource_path('sf_base', 'static/util')
+ cmd = 'python3 %s/stl2gltf.py %s %s -b' % (util_path, output_file, output_glb_file)
+ os.system(cmd)
+ # 转base64
+ with open(output_glb_file, 'rb') as fileObj:
+ image_data = fileObj.read()
+ base64_data = base64.b64encode(image_data)
+ return base64_data
+
+ # return False
+
+ @api.onchange('upload_model_file')
+ def onchange_model_file(self):
+ for item in self:
+ if len(item.upload_model_file) > 1:
+ raise ValidationError('只允许上传一个文件')
+ if item.upload_model_file:
+ file_attachment_id = item.upload_model_file[0]
+ # 附件路径
+ report_path = file_attachment_id._full_path(file_attachment_id.store_fname)
+ logging.info("模型路径: %s" % report_path)
+ base64_data = base64.b64encode(file_attachment_id.datas)
+ base64_datas = base64_data.decode('utf-8')
+ model_code = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest()
+ logging.info("模型编码: %s" % model_code)
+ item.model_file = self.transition_glb_file(report_path, model_code)
+ else:
+ item.model_file = False
+ item.model_feature = False
+ item.model_length = 0
+ item.model_width = 0
+ item.model_height = 0
+ item.model_volume = 0
+
+ def distribute_to_factory(self, obj):
+ """
+ 派单到工厂
+ :return:
+ """
+ try:
+ logging.info('---------派单到工厂-------')
+ res = {'bfm_process_order_list': []}
+ for item in obj:
+ attachment = item.upload_model_file[0]
+ base64_data = base64.b64encode(attachment.datas)
+ base64_datas = base64_data.decode('utf-8')
+ barcode = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest()
+ # logging.info('model_file-size: %s' % len(item.model_file))
+ res['bfm_process_order_list'].append({
+ 'model_long': item.model_length,
+ 'model_width': item.model_width,
+ 'model_height': item.model_height,
+ 'model_volume': item.model_volume,
+ 'model_machining_precision': item.machining_precision,
+ 'model_name': attachment.name,
+ 'model_data': base64_datas,
+ 'model_file': base64.b64encode(item.model_file).decode('utf-8'),
+ 'texture_code': item.material_id.materials_no,
+ 'texture_type_code': item.material_model_id.materials_no,
+ # 'surface_process_code': self.env['jikimo.surface.process']._json_surface_process_code(item),
+ 'process_parameters_code': self.env[
+ 'sf.production.process.parameter']._json_production_process_item_code(
+ item),
+ 'price': item.price,
+ 'number': item.quantity,
+ 'total_amount': item.price,
+ 'remark': '',
+ 'barcode': barcode
+ })
+ # res['bfm_process_order_list'] = json.dumps(res['bfm_process_order_list'])
+ product_id = self.env.ref('sf_dlm.product_template_sf').sudo()
+ self_machining_id = self.env.ref('sf_dlm.product_embryo_sf_self_machining').sudo()
+ outsource_id = self.env.ref('sf_dlm.product_embryo_sf_outsource').sudo()
+ purchase_id = self.env.ref('sf_dlm.product_embryo_sf_purchase').sudo()
+ company_id = self.env.ref('base.main_company').sudo()
+ # user_id = request.env.ref('base.user_admin').sudo()
+ order_id = self.env['sale.order'].sale_order_create(company_id, 'XXXXX', 'XXXXX', 'XXXXX',
+ str(datetime.now()), '现结', '支付宝')
+ i = 1
+ # 给sale_order的default_code字段赋值
+ aa = self.env['sale.order'].sudo().search([('name', '=', order_id.name)])
+ logging.info('---------aa------- %s' % aa.name)
+ aa.default_code = obj.name
+ for item in res['bfm_process_order_list']:
+ product = self.env['product.template'].sudo().product_create(product_id, item, order_id,
+ obj.name, i)
+ bom_data = self.env['mrp.bom'].get_bom(product)
+ logging.info('bom_data:%s' % bom_data)
+ if bom_data:
+ bom = self.env['mrp.bom'].bom_create(product, 'normal', False)
+ bom.bom_create_line_has(bom_data)
+ else:
+ if product.materials_type_id.gain_way == '自加工':
+ # 创建坯料
+ self_machining_embryo = self.env['product.template'].sudo().no_bom_product_create(
+ self_machining_id,
+ item, order_id,
+ 'self_machining',
+ i)
+ # 创建坯料的bom
+ self_machining_bom = self.env['mrp.bom'].bom_create(self_machining_embryo, 'normal', False)
+ # 创建坯料里bom的组件
+ self_machining_bom_line = self_machining_bom.bom_create_line(self_machining_embryo)
+ if self_machining_bom_line is False:
+ self.cr.rollback()
+ return UserError('该订单模型的材料型号在您分配的工厂里暂未有原材料,请先配置再进行分配')
+ # 产品配置bom
+ product_bom_self_machining = self.env['mrp.bom'].bom_create(product, 'normal', False)
+ product_bom_self_machining.bom_create_line_has(self_machining_embryo)
+ elif product.materials_type_id.gain_way == '外协':
+ # 创建坯料
+ outsource_embryo = self.env['product.template'].sudo().no_bom_product_create(outsource_id, item,
+ order_id,
+ 'subcontract', i)
+ # 创建坯料的bom
+ outsource_bom = self.env['mrp.bom'].bom_create(outsource_embryo, 'subcontract', True)
+ # 创建坯料的bom的组件
+ outsource_bom_line = outsource_bom.with_user(
+ self.env.ref("base.user_admin")).bom_create_line(outsource_embryo)
+ if outsource_bom_line is False:
+ self.cr.rollback()
+ return UserError('该订单模型的材料型号在您分配的工厂里暂未有原材料,请先配置再进行分配')
+ # 产品配置bom
+ product_bom_outsource = self.env['mrp.bom'].bom_create(product, 'normal', False)
+ product_bom_outsource.bom_create_line_has(outsource_embryo)
+ elif product.materials_type_id.gain_way == '采购':
+ purchase_embryo = self.env['product.template'].sudo().no_bom_product_create(purchase_id, item,
+ order_id,
+ 'purchase', i)
+ # 产品配置bom
+ product_bom_purchase = self.env['mrp.bom'].bom_create(product, 'normal', False)
+ product_bom_purchase.bom_create_line_has(purchase_embryo)
+ order_id.with_user(self.env.ref("base.user_admin")).sale_order_create_line(product, item)
+ except Exception as e:
+ # self.cr.rollback()
+ return UserError('工厂创建销售订单和产品失败,请联系管理员')
+
+ # 特征识别
+ def feature_recognition(self, report_path, model_code):
+ feature_path = self.env['sf.auto_quatotion.common'].sudo().get_feature_full_path()
+ process_time_db_path = self.env['sf.auto_quatotion.common'].sudo().get_process_time_db_path()
+ ret = self.env['sf.auto_quatotion.common'].sudo().get_auto_quatotion(report_path, feature_path,
+ process_time_db_path,
+ model_code)
+ return ret
+
+ # 模型上色
+ def model_coloring(self, order):
+ url = '/api/library_of_models/create'
+ config = self.env['res.config.settings'].get_values()
+ config_header = Common.get_headers(self, config['token'], config['sf_secret_key'])
+ logging.info('order: %s' % order.name)
+ if order:
+ attachment = order.upload_model_file[0]
+ base64_data = base64.b64encode(attachment.datas)
+ base64_datas = base64_data.decode('utf-8')
+ model_code = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest()
+ logging.info('model_file-size: %s' % len(order.model_file))
+ logging.info('attachment.datas-size: %s' % len(attachment.datas))
+ vals = {
+ 'model_code': model_code,
+ 'model_data': base64_data,
+ 'model_name': attachment.name,
+ 'model_long': order.model_length,
+ 'model_width': order.model_width,
+ 'model_height': order.model_height,
+ 'model_volume': order.model_volume,
+ 'model_order_no': order.name,
+ 'remark': '订单号:%s 客户:%s' % (order.name, order.customer_id.name)
+ }
+ try:
+ ret = requests.post((config['sf_url'] + url), json={}, data=vals, headers=config_header,
+ timeout=60)
+ ret = ret.json()
+ # result = json.loads(ret['result'])
+ if ret['status'] == 1:
+ order.model_color_state = 'success'
+ else:
+ order.model_color_state = 'fail'
+ raise UserError(ret['message'])
+ except Exception as e:
+ order.model_color_state = 'fail'
+ raise UserError("模型上色失败")
+
+ # 自动报价
+ def _get_price(self, order):
+ url = '/api/automatic_quotes'
+ config = self.env['res.config.settings'].sudo().get_values()
+ config_header = Common.get_headers(self, config['token'], config['sf_secret_key'])
+ logging.info("报价接口..........% s" % order.name)
+ try:
+ if order:
+ vals = {}
+ # mrs合作伙伴token
+ vals['token'] = config['token']
+ vals['accuracy'] = order.machining_precision
+ vals['number'] = order.quantity
+ vals['process_code'] = 0
+ vals['texture_code'] = order.material_model_id.materials_no
+ vals['delivery_days'] = 15
+ if order.model_file:
+ for item in order.upload_model_file:
+ if item.ids[0]:
+ logging.info('create-attachment:%s' % int(item.ids[0]))
+ attachment = self.env['ir.attachment'].sudo().search([('id', '=', int(item.ids[0]))])
+ vals['attachment_id'] = attachment.id
+ else:
+ vals['attachment_id'] = ''
+ vals['feature_infos'] = order.model_feature
+ vals['model_long'] = order.model_length
+ vals['model_width'] = order.model_width
+ vals['model_height'] = order.model_height
+ logging.info('vals:%s' % vals)
+ ret = requests.post((config['sf_url'] + url), json={}, data=vals, headers=config_header)
+ result = json.dumps(json.loads(ret.text), ensure_ascii=False, indent=4, separators=(',', ':'))
+ logging.info('报价接口返回:%s' % result)
+ price_result = json.loads(result)
+ # random.randint(0, 10000)
+ order.write({'price': price_result.get('price')})
+ else:
+ raise UserError("订单不存在")
+ except Exception as e:
+ if ret['status'] != 1:
+ raise UserError(e)
+ else:
+ raise UserError("自动报价失败,请联系管理员")
diff --git a/sf_sale/models/sale_order.py b/sf_sale/models/sale_order.py
index a55f9fb3..e2313ba3 100644
--- a/sf_sale/models/sale_order.py
+++ b/sf_sale/models/sale_order.py
@@ -85,11 +85,16 @@ class ReSaleOrder(models.Model):
self.check_status = 'pending'
def get_customer(self):
+ partner_tag = self.env['res.partner.category'].search([('name', '=', '业务平台')], limit=1, order='id asc')
+ if not partner_tag:
+ partner_tag = self.env['res.partner.category'].create({'name': '平台客户'})
customer = self.env['res.partner'].search([('name', '=', '业务平台')], limit=1, order='id asc')
if customer:
+ if not customer.vat:
+ customer.write({'name': '业务平台', 'vat': '91430103MA7BRH9K4M', 'phone': '0731-85115515',
+ 'email': 'jikimo@jikimo.com', 'category_id': [Command.set([partner_tag.id])]})
return customer
else:
- partner_tag = self.env['res.partner.category'].create({'name': '平台客户'})
partner = self.env['res.partner'].create(
{'name': '业务平台', 'vat': '91430103MA7BRH9K4M', 'phone': '0731-85115515',
'email': 'jikimo@jikimo.com', 'category_id': [Command.set([partner_tag.id])]})
diff --git a/sf_warehouse/models/model.py b/sf_warehouse/models/model.py
index cc2e20c8..b7a8b9d7 100644
--- a/sf_warehouse/models/model.py
+++ b/sf_warehouse/models/model.py
@@ -21,13 +21,6 @@ class SfLocation(models.Model):
name = fields.Char('Location Name', required=True, size=20)
barcode = fields.Char('Barcode', copy=False, size=15)
- check_state = fields.Selection([
- ('enable', '启用'),
- ('close', '关闭')
- ], string='审核状态', default='close')
-
- def action_check(self):
- self.check_state = 'enable'
# 仓库类别(selection:库区、库位、货位)
# location_type = fields.Selection([
@@ -835,112 +828,15 @@ class SfProcurementGroup(models.Model):
return res
-class SfWarehouse(models.Model):
- _inherit = 'stock.warehouse'
-
- check_state = fields.Selection([
- ('enable', '启用'),
- ('close', '关闭')
- ], string='审核状态', default='close')
-
- def action_check(self):
- self.check_state = 'enable'
-
-
-class SfRule(models.Model):
- _inherit = 'stock.rule'
-
- check_state = fields.Selection([
- ('enable', '启用'),
- ('close', '关闭')
- ], string='审核状态', default='close')
-
- def action_check(self):
- self.check_state = 'enable'
-
-
-class SfRoute(models.Model):
- _inherit = 'stock.route'
-
- check_state = fields.Selection([
- ('enable', '启用'),
- ('close', '关闭')
- ], string='审核状态', default='close')
-
- def action_check(self):
- self.check_state = 'enable'
-
-
class SfPickingType(models.Model):
_inherit = 'stock.picking.type'
- check_state = fields.Selection([
- ('enable', '启用'),
- ('close', '关闭')
- ], string='审核状态', default='close')
-
- def action_check(self):
- self.check_state = 'enable'
-
-
-class SfBarcodeNomenclature(models.Model):
- _inherit = 'barcode.nomenclature'
-
- check_state = fields.Selection([
- ('enable', '启用'),
- ('close', '关闭')
- ], string='审核状态', default='close')
-
- def action_check(self):
- self.check_state = 'enable'
-
-
-class SfPutawayRule(models.Model):
- _inherit = 'stock.putaway.rule'
-
- check_state = fields.Selection([
- ('enable', '同意'),
- ('close', '不同意')
- ], string='审核状态', default='close')
-
- def action_check(self):
- self.check_state = 'enable'
-
-
-class SfWarehouseOrderpoint(models.Model):
- _inherit = 'stock.warehouse.orderpoint'
-
- check_state = fields.Selection([
- ('enable', '同意'),
- ('close', '不同意')
- ], string='审核状态', default='close')
-
- def action_check(self):
- self.check_state = 'enable'
-
-
-class SfStockQuant(models.Model):
- _inherit = 'stock.quant'
-
- check_state = fields.Selection([
- ('enable', '同意'),
- ('close', '不同意')
- ], string='审核状态', default='close')
-
- def action_check(self):
- self.check_state = 'enable'
-
-
-class SfStockScrap(models.Model):
- _inherit = 'stock.scrap'
-
- check_state = fields.Selection([
- ('enable', '启用'),
- ('close', '关闭')
- ], string='审核状态', default='close')
-
- def action_check(self):
- self.check_state = 'enable'
+ def _default_show_operations(self):
+ return self.user_has_groups('stock.group_production_lot,'
+ 'stock.group_stock_multi_locations,'
+ 'stock.group_tracking_lot',
+ 'sf_warehouse.group_sf_stock_user',
+ 'sf_warehouse.group_sf_stock_manager')
class CustomStockMove(models.Model):
diff --git a/sf_warehouse/views/view.xml b/sf_warehouse/views/view.xml
index 39d5a8c0..aa3293ce 100644
--- a/sf_warehouse/views/view.xml
+++ b/sf_warehouse/views/view.xml
@@ -67,16 +67,16 @@
-
-
+
+
+
+
+
+
+
+
-
+
@@ -188,23 +188,23 @@
-
- stock.warehouse.form.sf.inherit
- stock.warehouse
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
@@ -220,23 +220,23 @@
-
- stock.route.form.sf.inherit
- stock.route
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
@@ -251,23 +251,23 @@
-
- stock.rule.form.sf.inherit
- stock.rule
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
@@ -282,23 +282,23 @@
-
- stock.picking.type.form.sf.inherit
- stock.picking.type
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+