+
+
+
@@ -877,12 +990,15 @@
-
+
- from
- to
+ from
+
+ to
+
@@ -895,95 +1011,96 @@
- No quality control point found
-
- Quality control points define the quality checks which should be
- performed at each operation, for your different products.
+ No quality control point found
+
+
+ Quality control points define the quality checks which should be
+ performed at each operation, for your different products.
+ id="menu_quality_root"
+ name="Quality"
+ web_icon="quality_control,static/description/icon.svg"
+ sequence="150"
+ groups="quality.group_quality_user"/>
+ id="menu_quality_dashboard"
+ name="Overview"
+ action="quality_alert_team_action"
+ parent="menu_quality_root"
+ sequence="5"/>
+ id="menu_quality_control"
+ name="Quality Control"
+ parent="menu_quality_root"
+ sequence="15"/>
+ id="menu_quality_control_points"
+ name="Control Points"
+ parent="menu_quality_control"
+ action="quality_point_action"
+ groups="quality.group_quality_manager"
+ sequence="17"/>
+ id="menu_quality_checks"
+ name="Quality Checks"
+ action="quality_check_action_main"
+ parent="menu_quality_control"
+ sequence="18"/>
+ id="menu_quality_alert"
+ name="Quality Alerts"
+ action="quality_alert_action_check"
+ parent="menu_quality_control"
+ sequence="20"/>
+ id="menu_quality_configuration"
+ name="Configuration"
+ groups="quality.group_quality_manager"
+ parent="menu_quality_root"
+ sequence="25"/>
+ id="menu_quality_config_alert_team"
+ name="Quality Teams"
+ action="quality_alert_team_action_config"
+ parent="menu_quality_configuration"
+ sequence="5"/>
+ id="menu_quality_config_alert_stage"
+ name="Quality Alert Stages"
+ action="quality_alert_stage_action"
+ parent="menu_quality_configuration"
+ groups="base.group_no_one"
+ sequence="15"/>
+ id="menu_config_quality_tags"
+ name="Quality Tags"
+ groups="base.group_no_one"
+ action="quality_tag_action"
+ parent="menu_quality_configuration"
+ sequence="25"/>
+ id="menu_quality_reporting"
+ name="Reporting"
+ groups="quality.group_quality_manager"
+ parent="menu_quality_root"
+ sequence="20"/>
+ id="menu_quality_alert_report"
+ action="quality_alert_action_report"
+ parent="menu_quality_reporting"
+ sequence="6"/>
+ id="menu_quality_check_report"
+ action="quality_check_action_report"
+ parent="menu_quality_reporting"
+ sequence="5"/>
diff --git a/sf_base/commons/common.py b/sf_base/commons/common.py
index 6bf597cc..b423e160 100644
--- a/sf_base/commons/common.py
+++ b/sf_base/commons/common.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-import time
+import time, datetime
import hashlib
from odoo import models
diff --git a/sf_base/models/tool_base_new.py b/sf_base/models/tool_base_new.py
index 97c4b47a..03a3678b 100644
--- a/sf_base/models/tool_base_new.py
+++ b/sf_base/models/tool_base_new.py
@@ -189,9 +189,9 @@ class MaintenanceStandardImage(models.Model):
('压紧方式', '压紧方式'), ('刀片形状', '刀片形状'), ('冷却方式', '冷却方式')],
string='特征')
equipment_id = fields.Many2many('maintenance.equipment', 'image_id', string='设备')
- equipment_lq_id = fields.Many2many('maintenance.equipment', 'image_lq_id', string='设备')
+ equipment_lq_id = fields.Many2many('maintenance.equipment', 'image_lq_id', string='设备能力特征')
jg_equipment_id = fields.Many2many('sf.machine_tool.type', 'jg_image_id', string='机床型号')
- lq_equipment_id = fields.Many2many('sf.machine_tool.type', 'lq_image_id', string='机床型号')
+ lq_equipment_id = fields.Many2many('sf.machine_tool.type', 'lq_image_id', string='机床型号能力特征')
def _get_ids(self, name_arr):
ability_feature_ids = []
@@ -254,6 +254,8 @@ class ToolGroups(models.Model):
equipment_ids = fields.Many2many('maintenance.equipment', 'ref_maintenance_equipment', string='机台号')
remark = fields.Char('备注', size=50)
+ active = fields.Boolean(string='已归档', default=True)
+
# ==========机床刀具组接口==========
# def _register_tool_groups(self, obj):
# # create_url = '/AutoDeviceApi/MachineToolGroup'
diff --git a/sf_base/security/ir.model.access.csv b/sf_base/security/ir.model.access.csv
index 0a319f34..ac0c1880 100644
--- a/sf_base/security/ir.model.access.csv
+++ b/sf_base/security/ir.model.access.csv
@@ -37,7 +37,6 @@ access_sf_cutting_tool_type_admin,sf_cutting_tool_type_admin,model_sf_cutting_to
access_sf_cutting_tool_type_group_purchase_director,sf_cutting_tool_type_group_purchase_director,model_sf_cutting_tool_type,sf_base.group_purchase_director,1,1,0,0
access_sf_cutting_tool_type_group_sale_director,sf_cutting_tool_type_group_sale_director,model_sf_cutting_tool_type,sf_base.group_sale_director,1,1,0,0
access_sf_cutting_tool_type_group_plan_director,sf_cutting_tool_type_group_plan_director,model_sf_cutting_tool_type,sf_base.group_plan_director,1,1,0,0
-
access_sf_functional_cutting_tool,sf_functional_cutting_tool,model_sf_functional_cutting_tool,base.group_user,1,1,1,0
access_sf_functional_cutting_tool_admin,sf_functional_cutting_tool_admin,model_sf_functional_cutting_tool,base.group_system,1,1,1,0
access_sf_functional_cutting_tool_model,sf_functional_cutting_tool_model,model_sf_functional_cutting_tool_model,base.group_user,1,1,1,0
@@ -60,6 +59,12 @@ access_sf_international_standards,sf_international_standards,model_sf_internatio
access_sf_international_standards_admin,sf_international_standards_admin,model_sf_international_standards,base.group_system,1,1,1,0
access_material_apply,material_apply,model_material_apply,base.group_user,1,1,1,0
access_material_apply_admin,material_apply_admin,model_material_apply,base.group_system,1,1,1,0
+access_material_apply_group_purchase_director,material_apply_group_purchase_director,model_material_apply,sf_base.group_purchase_director,1,0,0,0
+access_material_apply_group_sale_director,material_apply_group_sale_director,model_material_apply,sf_base.group_sale_director,1,0,0,0
+access_material_apply_group_plan_director,material_apply_group_plan_director,model_material_apply,sf_base.group_plan_director,1,0,0,0
+access_material_apply_group_purchase_director,material_apply_group_purchase_director,model_material_apply,sf_base.group_purchase_director,1,0,0,0
+access_material_apply_group_sale_salemanager,material_apply_group_sale_salemanager,model_material_apply,sf_base.group_sale_salemanager,1,0,0,0
+
access_sf_cutting_tool_standard_library,sf_cutting_tool_standard_library,model_sf_cutting_tool_standard_library,base.group_user,1,1,1,0
access_sf_cutting_tool_standard_library_admin,sf_cutting_tool_standard_library_admin,model_sf_cutting_tool_standard_library,base.group_system,1,1,1,0
access_sf_tool_materials_basic_parameters,sf_tool_materials_basic_parameters,model_sf_tool_materials_basic_parameters,base.group_user,1,1,1,0
@@ -72,6 +77,7 @@ access_sf_cutting_speed_group_plan_director,sf_cutting_speed_group_plan_director
access_sf_feed_per_tooth_group_purchase_director,sf_feed_per_tooth_group_purchase_director,model_sf_feed_per_tooth,sf_base.group_purchase_director,1,1,0,0
access_sf_feed_per_tooth_group_sale_director,sf_feed_per_tooth_group_sale_director,model_sf_feed_per_tooth,sf_base.group_sale_director,1,1,0,0
access_sf_feed_per_tooth_group_plan_director,sf_feed_per_tooth_group_plan_director,model_sf_feed_per_tooth,sf_base.group_plan_director,1,1,0,0
+access_sf_feed_per_tooth_group_sale_salemanager,sf_feed_per_tooth_group_sale_salemanager,model_sf_feed_per_tooth,sf_base.group_sale_salemanager,1,0,0,0
access_sf_feed_per_tooth,sf_feed_per_tooth,model_sf_feed_per_tooth,base.group_user,1,1,1,0
access_sf_feed_per_tooth_admin,sf_feed_per_tooth_admin,model_sf_feed_per_tooth,base.group_system,1,1,1,0
access_sf_ramping_angle,sf_ramping_angle,model_sf_ramping_angle,base.group_user,1,1,1,1
@@ -116,47 +122,35 @@ access_sf_functional_fixture,sf_functional_fixture,model_sf_functional_fixture,s
access_sf_sync_common,sf_sync_common,model_sf_sync_common,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_international_standards,sf_international_standards,model_sf_international_standards,sf_base.group_sf_mrp_user,1,0,0,0
access_material_apply,material_apply,model_material_apply,sf_base.group_sf_mrp_user,1,0,0,0
-
access_sf_cutting_tool_standard_library_group_sf_mrp_user,sf_cutting_tool_standard_library_group_sf_mrp_user,model_sf_cutting_tool_standard_library,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_cutting_tool_standard_library_group_purchase_director,sf_cutting_tool_standard_library_group_purchase_director,model_sf_cutting_tool_standard_library,sf_base.group_purchase_director,1,0,1,0
access_sf_cutting_tool_standard_library_group_plan_director,sf_cutting_tool_standard_library_group_plan_director,model_sf_cutting_tool_standard_library,sf_base.group_plan_director,1,0,1,0
access_sf_cutting_tool_standard_library_group_sale_director,sf_cutting_tool_standard_library_group_sale_director,model_sf_cutting_tool_standard_library,sf_base.group_sale_director,1,0,1,0
-
access_sf_tool_groups,sf_tool_groups,model_sf_tool_groups,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_tool_materials_basic_parameters_group_sale_director,sf_tool_materials_basic_parameters_group_sale_director,model_sf_tool_materials_basic_parameters,sf_base.group_sale_director,1,0,1,0
access_sf_tool_materials_basic_parameters_group_plan_director,sf_tool_materials_basic_parameters_group_plan_director,model_sf_tool_materials_basic_parameters,sf_base.group_plan_director,1,0,1,0
access_sf_tool_materials_basic_parameters_group_purchase_director,sf_tool_materials_basic_parameters_group_purchase_director,model_sf_tool_materials_basic_parameters,sf_base.group_purchase_director,1,0,1,0
-
access_sf_cutting_speed,sf_cutting_speed,model_sf_cutting_speed,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_cutting_speed_group_purchase,sf_cutting_speed_group_purchase,model_sf_cutting_speed,sf_base.group_purchase,1,0,0,0
access_sf_cutting_speed_group_sale_salemanager,sf_cutting_speed_group_sale_salemanager,model_sf_cutting_speed,sf_base.group_sale_salemanager,1,0,0,0
-
-
access_sf_feed_per_tooth,sf_feed_per_tooth,model_sf_feed_per_tooth,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_feed_per_tooth_group_purchase,sf_feed_per_tooth_group_purchase,model_sf_feed_per_tooth,sf_base.group_purchase,1,0,0,0
access_sf_ramping_angle,sf_ramping_angle,model_sf_ramping_angle,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_ramping_angle_group_purchase,sf_ramping_angle_group_purchase,model_sf_ramping_angle,sf_base.group_purchase,1,0,0,0
access_sf_cutting_width_depth,sf_cutting_width_depth,model_sf_cutting_width_depth,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_cutting_width_depth_group_purchase,sf_cutting_width_depth_group_purchase,model_sf_cutting_width_depth,sf_base.group_purchase,1,0,0,0
-
access_maintenance_equipment_image,maintenance_equipment_image,model_maintenance_equipment_image,base.group_user,1,1,1,1
access_purchase_order_group_purchase,access_purchase_order_group_purchase,purchase.model_purchase_order,sf_base.group_purchase,1,1,1,0
access_purchase_order_group_purchase_director,access_purchase_order_group_purchase_director,purchase.model_purchase_order,sf_base.group_purchase_director,1,1,1,0
access_purchase_order_line_group_purchase,access_purchase_order_line_group_purchase,purchase.model_purchase_order_line,sf_base.group_purchase,1,1,1,0
access_purchase_order_line_group_purchase_director,access_purchase_order_line_group_purchase_director,purchase.model_purchase_order_line,sf_base.group_purchase_director,1,1,1,0
access_spindle_taper_type,spindle_taper_type,model_spindle_taper_type,base.group_user,1,1,1,1
-
access_sf_tool_groups_group_plan_dispatch,sf_tool_groups,model_sf_tool_groups,sf_base.group_plan_dispatch,1,0,0,0
access_sf_tool_groups_group_sf_tool_user,sf_tool_groups,model_sf_tool_groups,sf_base.group_sf_tool_user,1,1,1,1
-
-
-
access_purchase_order,purchase.order,purchase.model_purchase_order,sf_base.group_plan_dispatch,1,0,0,0
access_res_partner,res.partner,base.model_res_partner,sf_base.group_plan_dispatch,1,0,0,0
access_purchase_order_line,purchase.order.line,purchase.model_purchase_order_line,sf_base.group_plan_dispatch,1,0,0,0
access_account_move_line,account.move.line,account.model_account_move_line,sf_base.group_plan_dispatch,1,0,0,0
-
-
access_sf_machine_tool,sf_machine_tool,model_sf_machine_tool,sf_base.group_sf_mrp_user,1,1,0,0
access_sf_machine_tool_type,sf_machine_tool_type,model_sf_machine_tool_type,sf_base.group_sf_mrp_user,1,1,0,0
access_sf_machine_brand,sf_machine_brand,model_sf_machine_brand,sf_base.group_sf_mrp_user,1,1,0,0
@@ -179,10 +173,18 @@ access_sf_fixture_material,sf_fixture_material,model_sf_fixture_material,sf_base
access_sf_fixture_materials_basic_parameters,sf_fixture_materials_basic_parameters,model_sf_fixture_materials_basic_parameters,sf_base.group_sf_mrp_user,1,1,0,0
access_mrp_production_group_sale_salemanager,mrp_production_group_sale_salemanager,mrp.model_mrp_production,sf_base.group_sale_salemanager,1,0,0,0
access_mrp_production_group_sale_director,mrp_production_group_sale_director,mrp.model_mrp_production,sf_base.group_sale_director,1,0,0,0
-
-
access_material_apply_group_plan_dispatch,material_apply,model_material_apply,sf_base.group_plan_dispatch,1,0,0,0
access_sf_machine_brand_tags_group_plan_dispatch,sf_machine_brand_tags,model_sf_machine_brand_tags,sf_base.group_plan_dispatch,1,0,0,0
access_ir_actions_act_window_group_plan_dispatch,ir.actions.act_window,base.model_ir_actions_act_window,sf_base.group_plan_dispatch,1,0,0,0
access_ir_actions_act_window_view_group_plan_dispatch,ir.actions.act_window.view,base.model_ir_actions_act_window_view,sf_base.group_plan_dispatch,1,0,0,0
-access_sf_supplier_sort_group_plan_dispatch,sf.supplier.sort,model_sf_supplier_sort,sf_base.group_plan_dispatch,1,0,0,0
\ No newline at end of file
+access_sf_supplier_sort_group_plan_dispatch,sf.supplier.sort,model_sf_supplier_sort,sf_base.group_plan_dispatch,1,0,0,0
+access_sf_international_standards_group_sale_salemanager,sf_international_standards_group_sale_salemanager,model_sf_international_standards,sf_base.group_sale_salemanager,1,0,0,0
+access_sf_international_standards_group_sale_director,sf_international_standards_group_sale_director,model_sf_international_standards,sf_base.group_sale_director,1,0,0,0
+access_sf_international_standards_group_plan_director,sf_international_standards_group_plan_director,model_sf_international_standards,sf_base.group_plan_director,1,0,0,0
+access_sf_international_standards_group_purchase,sf_international_standards_group_purchase,model_sf_international_standards,sf_base.group_purchase,1,0,0,0
+access_sf_international_standards_group_purchase_director,sf_international_standards_group_purchase_director,model_sf_international_standards,sf_base.group_purchase_director,1,0,0,0
+access_sf_machine_brand_tags_group_sale_salemanager,sf_machine_brand_tags_group_sale_salemanager,model_sf_machine_brand_tags,sf_base.group_sale_salemanager,1,0,0,0
+access_sf_machine_brand_tags_group_sale_director,sf_machine_brand_tags_group_sale_director,model_sf_machine_brand_tags,sf_base.group_sale_director,1,0,0,0
+access_sf_machine_brand_tags_group_plan_director,sf_machine_brand_tags_group_plan_director,model_sf_machine_brand_tags,sf_base.group_plan_director,1,0,0,0
+access_sf_machine_brand_tags_group_purchase,sf_machine_brand_tags_group_purchase,model_sf_machine_brand_tags,sf_base.group_purchase,1,0,0,0
+access_sf_machine_brand_tags_group_purchase_director,sf_machine_brand_tags_group_purchase_director,model_sf_machine_brand_tags,sf_base.group_purchase_director,1,0,0,0
diff --git a/sf_base/views/tool_views.xml b/sf_base/views/tool_views.xml
index 5763b3a0..d1c0c510 100644
--- a/sf_base/views/tool_views.xml
+++ b/sf_base/views/tool_views.xml
@@ -505,11 +505,23 @@
+
+ 刀具组搜索
+ sf.tool.groups
+
+
+
+
+
+
+
+
+
刀具组
ir.actions.act_window
sf.tool.groups
- tree
+ tree,search
diff --git a/sf_bf_connect/controllers/controllers.py b/sf_bf_connect/controllers/controllers.py
index aa31b8b6..c5b57ba3 100644
--- a/sf_bf_connect/controllers/controllers.py
+++ b/sf_bf_connect/controllers/controllers.py
@@ -16,7 +16,7 @@ class Sf_Bf_Connect(http.Controller):
:return:
"""
res = {'status': 1, 'factory_order_no': ''}
- logging.info('get_bfm_process_order_list:%s' % kw)
+ logging.info('get_bfm_process_order_list:%s' % kw['order_number'])
try:
product_id = request.env.ref('sf_dlm.product_template_sf').sudo()
self_machining_id = request.env.ref('sf_dlm.product_embryo_sf_self_machining').sudo()
@@ -143,3 +143,17 @@ class jdElcp(http.Controller):
aa.bill_url = kw['bill']
logging.info('get_jd_bill================:%s' %
aa.bill_url)
+
+ @http.route('/api/update/order/status', type='http', auth='none', methods=['GET', 'POST'], csrf=False,
+ cors="*")
+ def update_order_status(self, **kw):
+ """
+ 根据拿到的商家单号,修改订单状态
+ """
+ logging.info('change_sale_order_state================:%s', kw)
+ if not kw.get('orderNo'):
+ return json.dumps({'statusCode': 415, 'statusMessage': '订单号不能为空'}, ensure_ascii=False)
+ aa = request.env['sale.order'].sudo().search([('name', '=', kw['orderNo'])])
+ if aa:
+ aa.schedule_status = 'received'
+ return json.dumps({'statusCode': 200, 'statusMessage': '修改成功'}, ensure_ascii=False)
diff --git a/sf_bf_connect/models/jd_eclp.py b/sf_bf_connect/models/jd_eclp.py
index 45fae2d8..c740869a 100644
--- a/sf_bf_connect/models/jd_eclp.py
+++ b/sf_bf_connect/models/jd_eclp.py
@@ -164,6 +164,9 @@ class JdEclp(models.Model):
self.is_bill = True
self.logistics_status = '1'
+ # 京东物流下单后,销售订单状态改为待收货
+ self.env['sale.order'].search([('name', '=', self.origin)]).write({'scheduled_status': 'to receive'})
+
# else:
# raise UserError("选择京东物流才能下单呦")
diff --git a/sf_dlm/data/product_data.xml b/sf_dlm/data/product_data.xml
index 95d19c39..55c5d616 100644
--- a/sf_dlm/data/product_data.xml
+++ b/sf_dlm/data/product_data.xml
@@ -35,14 +35,14 @@
功能刀具
-
-
-
-
+
+ 业务平台
+
+
-
+
diff --git a/sf_dlm_management/views/product_template_management_view.xml b/sf_dlm_management/views/product_template_management_view.xml
index b1d0f50f..1c56ad77 100644
--- a/sf_dlm_management/views/product_template_management_view.xml
+++ b/sf_dlm_management/views/product_template_management_view.xml
@@ -17,31 +17,33 @@
attrs="{'invisible': ['|','|', ('categ_type', '!=', '成品'),('categ_type', '=', False),('model_file', '=', False)]}"/>
-
-
-
-
-
-
+
-
+
@@ -352,7 +354,7 @@
attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀杆','刀盘'))],'readonly': [('id', '!=', False)]}"/>
-
diff --git a/sf_manufacturing/controllers/controllers.py b/sf_manufacturing/controllers/controllers.py
index f77450f9..9063f518 100644
--- a/sf_manufacturing/controllers/controllers.py
+++ b/sf_manufacturing/controllers/controllers.py
@@ -72,14 +72,16 @@ class Manufacturing_Connect(http.Controller):
date_planned_start = ''
date_planned_finished = ''
if item.date_planned_start is not False:
+ logging.info('date_planned_start:%s' % item.date_planned_start)
planned_start = item.date_planned_start.strftime("%Y-%m-%d %H:%M:%S")
date_planned_start = request.env['sf.sync.common'].sudo().get_add_time(planned_start)
if item.date_planned_finished is not False:
+ logging.info('date_planned_finished:%s' % item.date_planned_finished)
planned_finished = item.date_planned_finished.strftime("%Y-%m-%d %H:%M:%S")
date_planned_finished = request.env['sf.sync.common'].sudo().get_add_time(planned_finished)
res['Datas'].append({
'BillId': item.production_id.name,
- 'RfidCode': item.RfidCode,
+ 'RfidCode': item.rfid_code,
'CraftName': item.name,
'Quantity': 1,
'WortkStart': date_planned_start,
@@ -87,7 +89,7 @@ class Manufacturing_Connect(http.Controller):
'MaterialId': item.product_id.default_code,
'MaterialName': item.product_id.name,
# 'Spec':item.mat,
- 'Material': item.materials_type_id.name
+ 'Material': item.product_id.materials_type_id.name
})
except Exception as e:
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
@@ -164,6 +166,13 @@ class Manufacturing_Connect(http.Controller):
return json.JSONEncoder().encode(res)
workorder.equipment_id = work_equipment_id
workorder.button_start()
+
+ # 根据工单的实际开始时间修改排程单的开始时间、状态
+ if workorder.date_start:
+ request.env['sf.production.plan'].sudo().search([('production_id', '=', production_id)]).write(
+ {'actual_start_time': workorder.date_start,
+ 'state': 'processing'})
+
except Exception as e:
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
logging.info('button_Work_START error:%s' % e)
@@ -193,6 +202,19 @@ class Manufacturing_Connect(http.Controller):
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '该工单未开始'}
return json.JSONEncoder().encode(res)
workorder.button_finish()
+
+ # 根据工单的实际结束时间修改排程单的结束时间、状态,同时修改销售订单的状态
+ if workorder.date_finished:
+ request.env['sf.production.plan'].sudo().search([('production_id', '=', production_id)]).write(
+ {'actual_end_time': workorder.date_finished,
+ 'state': 'finished'})
+ production_obj = request.env['mrp.production'].sudo().search([('name', '=', production_id)])
+ if production_obj:
+ production_obj.sudo().schedule_state = '已完成'
+ production_obj.write({'state': 'completed'})
+ request.env['sale.order'].sudo().search(
+ [('name', '=', production_obj.origin)]).write({'schedule_status': 'to deliver'})
+
except Exception as e:
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
logging.info('button_Work_End error:%s' % e)
@@ -208,7 +230,7 @@ class Manufacturing_Connect(http.Controller):
"""
logging.info('PartQualityInspect:%s' % kw)
try:
- res = {'Succeed': True, 'Datas': []}
+ res = {'Succeed': True}
datas = request.httprequest.data
ret = json.loads(datas)
production_id = ret['BillId']
@@ -216,17 +238,40 @@ 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']
+ logging.info('制造订单:%s' % workorder.production_id.name)
if 'ReportPaht' in ret:
download_state = request.env['mrp.workorder'].with_user(
request.env.ref("base.user_admin")).download_reportfile_tmp(workorder,
ret['ReportPaht'])
- if download_state is not False:
- request.env['mrp.workorder'].with_user(
+ if download_state == 1:
+ detection_ret = request.env['mrp.workorder'].with_user(
request.env.ref("base.user_admin")).get_detection_file(workorder, ret['ReportPaht'])
+ if detection_ret is True:
+ stock_picking_type = request.env['stock.picking.type'].sudo().search(
+ [('sequence_code', '=', 'SFP')])
+ if stock_picking_type:
+ stock_picking = request.env['stock.picking'].sudo().search(
+ [('product_id', '=', workorder.product_id.id),
+ ('origin', '=', workorder.production_id.origin),
+ ('picking_type_id', '=', stock_picking_type.id)])
+ if stock_picking:
+ quality_check = request.env['quality.check'].sudo().search(
+ [('product_id', '=', workorder.product_id.id),
+ ('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})
+ elif download_state == 2:
+ res = {'Succeed': False, 'ErrorCode': 205,
+ 'Error': 'ReportPaht中的工件号与制造订单%s不匹配,请检查ReportPaht是否正确' % workorder.production_id.name}
else:
res = {'Succeed': False, 'ErrorCode': 204, 'Error': '检测报告文件从FTP拉取失败'}
else:
res = {'Succeed': False, 'ErrorCode': 203, 'Error': '未传ReportPaht字段'}
+ else:
+ res = {'Succeed': False, 'ErrorCode': 206, 'Error': '未查询到工单'}
except Exception as e:
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
logging.info('PartQualityInspect error:%s' % e)
@@ -362,7 +407,6 @@ class Manufacturing_Connect(http.Controller):
old_localtion.location_status = '空闲'
old_localtion.production_id = False
-
# return json.JSONEncoder().encode(res)
# else:
# res = {'Succeed': False, 'ErrorCode': 201, 'Error': '未传RfidCode字段'}
diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py
index b740704e..2ca0dbc6 100644
--- a/sf_manufacturing/models/mrp_production.py
+++ b/sf_manufacturing/models/mrp_production.py
@@ -92,7 +92,9 @@ class MrpProduction(models.Model):
# 新添加的状态逻辑
if production.state == 'progress' and production.schedule_state == '已排':
production.state = 'pending_processing'
- elif production.state == 'progress' and production.schedule_state == '已完成':
+ # elif production.state == 'progress' and production.schedule_state == '已完成':
+ # production.state = 'completed'
+ elif production.state == 'pending_processing' and production.schedule_state == '已完成':
production.state = 'completed'
def action_check(self):
diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py
index 2cb292e1..a7408be8 100644
--- a/sf_manufacturing/models/mrp_workorder.py
+++ b/sf_manufacturing/models/mrp_workorder.py
@@ -95,8 +95,7 @@ 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_results = fields.Selection([("合格", "合格"), ("返工", "返工"), ("报废", "报废")], default='合格',
- string="检测结果")
+ test_result = fields.Char("检测结果")
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,15 +142,17 @@ class ResMrpWorkOrder(models.Model):
def get_plan_workorder(self, production_line):
tomorrow = (date.today() + timedelta(days=+1)).strftime("%Y-%m-%d")
+ tomorrow_start = tomorrow + ' 00:00:00'
+ tomorrow_end = tomorrow + ' 23:59:59'
+ logging.info('tomorrow:%s' % tomorrow)
sql = """
SELECT *
FROM mrp_workorder
- WHERE date_planned_start = %s::timestamp
- AND date_planned_start < (%s::timestamp + interval '1 day')
- AND date_planned_finished >= %s::timestamp
- AND date_planned_finished < (%s::timestamp + interval '1 day')
+ WHERE
+ to_char(date_planned_start::timestamp + '8 hour','YYYY-MM-DD HH:mm:SS')>= %s
+ AND to_char(date_planned_finished::timestamp + '8 hour','YYYY-MM-DD HH:mm:SS')<= %s
"""
- params = [tomorrow, tomorrow, tomorrow, tomorrow]
+ params = [tomorrow_start, tomorrow_end]
if production_line:
sql += "AND production_line_id = %s"
params.append(production_line)
@@ -432,7 +433,7 @@ class ResMrpWorkOrder(models.Model):
"""
重新生成制造订单或者重新生成工单
"""
- if self.test_results == '报废':
+ if self.test_result == '报废':
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(
@@ -464,7 +465,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_results == '返工':
+ if self.test_result == '返工':
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())
@@ -631,39 +632,46 @@ class ResMrpWorkOrder(models.Model):
# 将FTP的检测报告文件下载到临时目录
def download_reportfile_tmp(self, workorder, reportpath):
+ logging.info('reportpath:%s' % reportpath)
+ production_no_ftp = reportpath.split('/')
production_no = workorder.production_id.name.replace('/', '_')
- remotepath = os.path.join('/', production_no, 'detection')
- serverdir = os.path.join('/tmp', production_no, 'detection')
- ftp_resconfig = self.env['res.config.settings'].get_values()
- ftp = FtpController(str(ftp_resconfig['ftp_host']), int(ftp_resconfig['ftp_port']),
- ftp_resconfig['ftp_user'],
- ftp_resconfig['ftp_password'])
- download_state = ftp.download_reportfile_tree(remotepath, serverdir, reportpath)
- logging.info('download_state:%s' % download_state)
+ # ftp地址
+ remotepath = os.path.join('/', production_no_ftp[1], 'detection')
+ logging.info('ftp地址:%s' % remotepath)
+ if reportpath.find(production_no) != -1:
+ # 服务器内临时地址
+ serverdir = os.path.join('/tmp', production_no_ftp[1], 'detection')
+ ftp_resconfig = self.env['res.config.settings'].get_values()
+ ftp = FtpController(str(ftp_resconfig['ftp_host']), int(ftp_resconfig['ftp_port']),
+ ftp_resconfig['ftp_user'],
+ ftp_resconfig['ftp_password'])
+ download_state = ftp.download_reportfile_tree(remotepath, serverdir, reportpath)
+ logging.info('download_state:%s' % download_state)
+ else:
+ download_state = 2
return download_state
# 根据中控系统提供的检测文件地址去ftp里对应的制造订单里获取
def get_detection_file(self, workorder, reportPath):
- logging.info('workorder:%s' % workorder.name)
- logging.info('制造订单:%s' % workorder.production_id.name)
- logging.info('reportPath:%s' % reportPath)
- serverdir = os.path.join('/tmp', reportPath).replace('//', '/')
- logging.info('serverdir:%s' % serverdir)
- for root, dirs, files in os.walk(serverdir):
- for f in files:
- logging.info('f:%s' % f)
- if os.path.splitext(f)[1] == ".pdf":
- full_path = os.path.join(serverdir, root, f)
- logging.info('检测文件路径:%s' % full_path)
- if full_path is not False:
- workorder.detection_report = base64.b64encode(
- open(full_path, 'rb').read())
+ if reportPath.startswith('/'):
+ reportPath = reportPath[1:]
+ serverdir = os.path.join('/tmp', reportPath)
+ logging.info('get_detection_file-serverdir:%s' % serverdir)
+ serverdir_prefix = os.path.dirname(serverdir)
+ for root, dirs, files in os.walk(serverdir_prefix):
+ for filename in files:
+ if filename == os.path.basename(reportPath):
+ report_file_path = os.path.join(root, filename)
+ logging.info('get_detection_file-report_file_path:%s' % report_file_path)
+ workorder.detection_report = base64.b64encode(open(report_file_path, 'rb').read())
+ return True
class CNCprocessing(models.Model):
_name = 'sf.cnc.processing'
_description = "CNC加工"
_rec_name = 'program_name'
+ _order = 'sequence_number,id'
cnc_id = fields.Many2one('ir.attachment')
sequence_number = fields.Char('序号')
@@ -686,15 +694,11 @@ class CNCprocessing(models.Model):
# mrs下发编程单创建CNC加工
def cnc_processing_create(self, cnc_workorder, ret, program_path, program_path_tmp):
- logging.info('ret:%s' % ret)
- logging.info('program_path_tmp:%s' % program_path_tmp)
- logging.info('program_path:%s' % program_path)
for obj in ret['programming_list']:
workorder = self.env['mrp.workorder'].search([('production_id.name', '=', ret['production_order_no']),
('processing_panel', '=', obj['processing_panel']),
('routing_type', '=', 'CNC加工')])
- logging.info('workorder:%s' % workorder.name)
- logging.info('obj:%s' % obj)
+ logging.info('workorder:%s' % workorder.id)
if obj['program_name'] in program_path:
logging.info('obj:%s' % obj['program_name'])
cnc_processing = self.env['sf.cnc.processing'].create({
@@ -711,7 +715,7 @@ class CNCprocessing(models.Model):
'cutting_tool_handle_type': obj['cutting_tool_handle_type'],
'estimated_processing_time': obj['estimated_processing_time'],
'remark': obj['remark'],
- 'program_path': program_path
+ 'program_path': program_path.replace('/tmp', '')
})
cnc_processing.get_cnc_processing_file(program_path_tmp, cnc_processing, program_path)
# cnc_workorder.state = 'done'
@@ -722,15 +726,11 @@ class CNCprocessing(models.Model):
# 根据程序名和加工面匹配到ftp里对应的Nc程序名
def get_cnc_processing_file(self, serverdir, cnc_processing, program_path):
- # logging.info('program_path_tmp:%s' % program_path_tmp)
- # serverdir = os.path.join('/tmp', folder_name, 'return', processing_panel)
logging.info('serverdir:%s' % serverdir)
for root, dirs, files in os.walk(serverdir):
for f in files:
- logging.info('f:%s' % f)
if os.path.splitext(f)[1] == ".pdf":
full_path = os.path.join(serverdir, root, f)
- logging.info('pdf:%s' % full_path)
if full_path is not False:
if not cnc_processing.workorder_id.cnc_worksheet:
cnc_processing.workorder_id.cnc_worksheet = base64.b64encode(
@@ -739,9 +739,6 @@ class CNCprocessing(models.Model):
if f in program_path:
# if cnc_processing.program_name == f.split('.')[0]:
cnc_file_path = os.path.join(serverdir, root, f)
- logging.info('cnc_file_path:%s' % cnc_file_path)
- logging.info('program_path:%s' % program_path)
- logging.info('f:%s' % f)
self.write_file(cnc_file_path, cnc_processing)
# 创建附件(nc文件)
diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py
index 5cb51953..c9c2ebf2 100644
--- a/sf_manufacturing/models/stock.py
+++ b/sf_manufacturing/models/stock.py
@@ -14,6 +14,7 @@ from odoo.addons.stock.models.stock_rule import ProcurementException
from odoo.addons.sf_base.commons.common import Common
from odoo.exceptions import UserError
from io import BytesIO
+from odoo.exceptions import ValidationError
class StockRule(models.Model):
@@ -250,6 +251,22 @@ class ProductionLot(models.Model):
))
return lot_names
+ def get_tool_generate_lot_names1(self, company, product):
+ """
+ 采购时生成刀具物料序列号
+ """
+ now = datetime.now().strftime("%Y%m%d")
+ last_serial = self.env['stock.lot'].search(
+ [('company_id', '=', company.id), ('product_id', '=', product.id), ('name', 'like', now)],
+ limit=1, order='id DESC')
+ if product.cutting_tool_model_id:
+ if not last_serial:
+ return "%s-%s%03d" % (product.cutting_tool_model_id.code[:-12], now, 1)
+ else:
+ return "%s-%s%03d" % (product.cutting_tool_model_id.code[:-12], now, int(last_serial.name[-3:]) + 1)
+ else:
+ raise ValidationError('该刀具物料产品的型号字段为空,请补充完整!!!')
+
@api.model
def _get_next_serial(self, company, product):
"""Return the next serial number to be attributed to the product."""
@@ -258,12 +275,13 @@ class ProductionLot(models.Model):
[('company_id', '=', company.id), ('product_id', '=', product.id)],
limit=1, order='id DESC')
if last_serial:
- return self.env['stock.lot'].generate_lot_names1(product.name, last_serial.name, 2)[
- 1]
- now = datetime.now().strftime("%Y-%m-%d")
- # formatted_date = now.strftime("%Y-%m-%d")
+ if product.categ_id.name == '刀具':
+ return self.env['stock.lot'].get_tool_generate_lot_names1(company, product)
+ else:
+ return self.env['stock.lot'].generate_lot_names1(product.name, last_serial.name, 2)[1]
+ now = datetime.now().strftime("%Y%m%d")
if product.cutting_tool_model_id:
- return "%s-%s-%03d" % (product.cutting_tool_model_id.code, now, 1)
+ return "%s-%s%03d" % (product.cutting_tool_model_id.code[:-12], now, 1)
return "%s-%03d" % (product.name, 1)
qr_code_image = fields.Binary(string='二维码', compute='_generate_qr_code')
diff --git a/sf_manufacturing/security/ir.model.access.csv b/sf_manufacturing/security/ir.model.access.csv
index c3fceb02..a54f6bf5 100644
--- a/sf_manufacturing/security/ir.model.access.csv
+++ b/sf_manufacturing/security/ir.model.access.csv
@@ -4,6 +4,7 @@ access_sf_cnc_processing_manager,sf_cnc_processing,model_sf_cnc_processing,sf_ba
access_sf_cmm_program_group_sf_mrp_user,sf_cmm_program_group_sf_mrp_user,model_sf_cmm_program,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_cmm_program_group_sf_mrp_manager,sf_cmm_program_group_sf_mrp_manager,model_sf_cmm_program,sf_base.group_sf_mrp_manager,1,0,0,0
access_sf_model_type,sf_model_type,model_sf_model_type,sf_base.group_sf_mrp_user,1,0,0,0
+access_sf_model_type_admin,sf_model_type_admin,model_sf_model_type,base.group_system,1,1,1,0
access_sf_model_type_manager,sf_model_type,model_sf_model_type,sf_base.group_sf_mrp_manager,1,1,1,0
access_sf_model_type_group_sale_director,sf_model_type_group_sale_director,model_sf_model_type,sf_base.group_sale_director,1,0,0,0
access_sf_model_type_group_purchase_director,sf_model_type_group_purchase_director,model_sf_model_type,sf_base.group_purchase_director,1,0,0,0
diff --git a/sf_manufacturing/static/src/js/customRFID.js b/sf_manufacturing/static/src/js/customRFID.js
index 174b60d7..8f775350 100644
--- a/sf_manufacturing/static/src/js/customRFID.js
+++ b/sf_manufacturing/static/src/js/customRFID.js
@@ -7,7 +7,7 @@ $(document).on('keydown', '.modal.d-block.o_technical_modal,body.o_web_client',
setTimeout(() => {
RFID = ''
}, 200)
- if(e.key == 'Enter' && e.keyCode == 13){
+ if(e.key == 'Enter' && e.keyCode == 13 || e.key == 'Tab' && e.keyCode == 9){
if(!RFID || RFID.length <= 3) return;
dom.children('span').text(RFID)
RFID = ''
diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml
index ee1eb751..db40cfeb 100644
--- a/sf_manufacturing/views/mrp_workorder_view.xml
+++ b/sf_manufacturing/views/mrp_workorder_view.xml
@@ -143,10 +143,10 @@
-
+
-
+
计划加工时间
@@ -434,9 +434,10 @@
-
+
-
+