Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/修改机床参数bug

This commit is contained in:
qihao.gong@jikimo.com
2024-02-04 15:57:16 +08:00
60 changed files with 2233 additions and 1325 deletions

View File

@@ -19,3 +19,13 @@ class Common(models.Model):
'TIMESTAMP': str(timestamp),
'checkstr': check_sf_str}
return headers
def get_add_time(self, parse_time):
"""
把时间增加8小时
:return:
"""
dt = datetime.datetime.strptime(parse_time, "%Y-%m-%d %H:%M:%S")
d = dt + datetime.timedelta(hours=8)
nTime = d.strftime("%Y-%m-%d %H:%M:%S")
return nTime

View File

@@ -61,7 +61,7 @@ class MrsMaterialModel(models.Model):
supplier_ids = fields.One2many('sf.supplier.sort', 'materials_model_id', string='供应商')
active = fields.Boolean('有效', default=True)
@api.constrains('gain_way', 'supplier_ids')
@api.constrains('supplier_ids')
def _check_gain_way(self):
if not self.gain_way:
raise UserError("请输入获取方式")

View File

@@ -1,5 +1,9 @@
# -*- coding: utf-8 -*-
import json
import requests
from odoo import fields, models, api
from odoo.exceptions import ValidationError
from odoo.addons.sf_base.commons.common import Common
class CuttingToolMaterial(models.Model):
@@ -249,3 +253,37 @@ class ToolGroups(models.Model):
name = fields.Char('名称')
equipment_ids = fields.Many2many('maintenance.equipment', 'ref_maintenance_equipment', string='机台号')
remark = fields.Char('备注', size=50)
# ==========机床刀具组接口==========
def _register_tool_groups(self, obj):
create_url = '/AutoDeviceApi/FeedBackOut'
sf_sync_config = self.env['res.config.settings'].get_values()
token = sf_sync_config['token']
sf_secret_key = sf_sync_config['sf_secret_key']
headers = Common.get_headers(obj, token, sf_secret_key)
strurl = sf_sync_config['sf_url'] + create_url
device_id = ''
for equipment_id in obj.equipment_ids:
device_id = '%s,%s' % (device_id, equipment_id.name)
val = {
'DeviceId': device_id,
'GroupName': obj.name,
}
kw = json.dumps(val, ensure_ascii=False)
r = requests.post(strurl, json={}, data={'kw': kw, 'token': token}, headers=headers)
ret = r.json()
if r == 200:
return "机床刀具组发送成功"
else:
raise ValidationError("机床刀具组发送失败")
# def write(self, vals):
# obj = super().write(vals)
# self._register_tool_groups(obj)
# return obj
#
# @api.model_create_multi
# def create(self, vals_list):
# records = super(ToolGroups, self).create(vals_list)
# self._register_tool_groups(records)
# return records

View File

@@ -1,40 +1,76 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_sf_machine_tool,sf_machine_tool,model_sf_machine_tool,base.group_user,1,1,1,1
access_sf_machine_tool_type,sf_machine_tool_type,model_sf_machine_tool_type,base.group_user,1,1,1,1
access_sf_machine_brand,sf_machine_brand,model_sf_machine_brand,base.group_user,1,1,1,1
access_sf_machine_brand_tags,sf_machine_brand_tags,model_sf_machine_brand_tags,base.group_user,1,1,1,1
access_sf_machine_control_system,sf_machine_control_system,model_sf_machine_control_system,base.group_user,1,1,1,1
access_sf_processing_order,sf_processing_order,model_sf_processing_order,base.group_user,1,1,1,1
access_sf_production_process,sf_production_process,model_sf_production_process,base.group_user,1,1,1,1
access_sf_production_materials,sf_production_materials,model_sf_production_materials,base.group_user,1,1,1,1
access_sf_materials_model,sf_materials_model,model_sf_materials_model,base.group_user,1,1,1,1
access_sf_processing_technology,sf_processing_technology,model_sf_processing_technology,base.group_user,1,1,1,1
access_sf_supplier_sort,sf_supplier_sort,model_sf_supplier_sort,base.group_user,1,1,1,1
access_sf_production_process_parameter,sf_production_process_parameter,model_sf_production_process_parameter,base.group_user,1,1,1,1
access_sf_production_process_category,sf_production_process_category,model_sf_production_process_category,base.group_user,1,1,1,1
access_sf_machine_tool_category,sf_machine_tool_category,model_sf_machine_tool_category,base.group_user,1,1,1,1
access_sf_cutting_tool_material,sf_cutting_tool_material,model_sf_cutting_tool_material,base.group_user,1,1,1,1
access_sf_cutting_tool_type,sf_cutting_tool_type,model_sf_cutting_tool_type,base.group_user,1,1,1,1
access_sf_functional_cutting_tool,sf_functional_cutting_tool,model_sf_functional_cutting_tool,base.group_user,1,1,1,1
access_sf_functional_cutting_tool_model,sf_functional_cutting_tool_model,model_sf_functional_cutting_tool_model,base.group_user,1,1,1,1
access_sf_fixture_material,sf_fixture_material,model_sf_fixture_material,base.group_user,1,1,1,1
access_sf_fixture_materials_basic_parameters,sf_fixture_materials_basic_parameters,model_sf_fixture_materials_basic_parameters,base.group_user,1,1,1,1
access_sf_multi_mounting_type,sf_multi_mounting_type,model_sf_multi_mounting_type,base.group_user,1,1,1,1
access_sf_fixture_model,sf_fixture_model,model_sf_fixture_model,base.group_user,1,1,1,1
access_sf_machine_tool,sf_machine_tool,model_sf_machine_tool,base.group_user,1,1,1,0
access_sf_machine_tool_admin,sf_machine_tool_admin,model_sf_machine_tool,base.group_system,1,1,1,0
access_sf_machine_tool_type,sf_machine_tool_type,model_sf_machine_tool_type,base.group_user,1,1,1,0
access_sf_machine_tool_type_admin,sf_machine_tool_type_admin,model_sf_machine_tool_type,base.group_system,1,1,1,0
access_sf_machine_brand,sf_machine_brand,model_sf_machine_brand,base.group_user,1,1,1,0
access_sf_machine_brand_admin,sf_machine_brand_admin,model_sf_machine_brand,base.group_system,1,1,1,0
access_sf_machine_brand_tags,sf_machine_brand_tags,model_sf_machine_brand_tags,base.group_user,1,1,1,0
access_sf_machine_brand_tags_admin,sf_machine_brand_tags_admin,model_sf_machine_brand_tags,base.group_system,1,1,1,0
access_sf_machine_control_system,sf_machine_control_system,model_sf_machine_control_system,base.group_user,1,1,1,0
access_sf_machine_control_system_admin,sf_machine_control_system_admin,model_sf_machine_control_system,base.group_system,1,1,1,0
access_sf_processing_order,sf_processing_order,model_sf_processing_order,base.group_user,1,1,1,0
access_sf_processing_order_admin,sf_processing_order_admin,model_sf_processing_order,base.group_system,1,1,1,0
access_sf_production_process,sf_production_process,model_sf_production_process,base.group_user,1,1,1,0
access_sf_production_process_admin,sf_production_process_admin,model_sf_production_process,base.group_system,1,1,1,0
access_sf_production_materials,sf_production_materials,model_sf_production_materials,base.group_user,1,1,1,0
access_sf_production_materials_admin,sf_production_materials_admin,model_sf_production_materials,base.group_system,1,1,1,0
access_sf_materials_model,sf_materials_model,model_sf_materials_model,base.group_user,1,1,1,0
access_sf_materials_model_admin,sf_materials_model_admin,model_sf_materials_model,base.group_system,1,1,1,0
access_sf_processing_technology,sf_processing_technology,model_sf_processing_technology,base.group_user,1,1,1,0
access_sf_processing_technology_admin,sf_processing_technology_admin,model_sf_processing_technology,base.group_system,1,1,1,0
access_sf_supplier_sort,sf_supplier_sort,model_sf_supplier_sort,base.group_user,1,1,1,0
access_sf_supplier_sort_admin,sf_supplier_sort_admin,model_sf_supplier_sort,base.group_system,1,1,1,0
access_sf_production_process_parameter,sf_production_process_parameter,model_sf_production_process_parameter,base.group_user,1,1,1,0
access_sf_production_process_parameter_admin,sf_production_process_parameter_admin,model_sf_production_process_parameter,base.group_system,1,1,1,0
access_sf_production_process_category,sf_production_process_category,model_sf_production_process_category,base.group_user,1,1,1,0
access_sf_production_process_category_admin,sf_production_process_category_admin,model_sf_production_process_category,base.group_system,1,1,1,0
access_sf_machine_tool_category,sf_machine_tool_category,model_sf_machine_tool_category,base.group_user,1,1,1,0
access_sf_machine_tool_category_admin,sf_machine_tool_category_admin,model_sf_machine_tool_category,base.group_system,1,1,1,0
access_sf_cutting_tool_material,sf_cutting_tool_material,model_sf_cutting_tool_material,base.group_user,1,1,1,0
access_sf_cutting_tool_material_admin,sf_cutting_tool_material_admin,model_sf_cutting_tool_material,base.group_system,1,1,1,0
access_sf_cutting_tool_type,sf_cutting_tool_type,model_sf_cutting_tool_type,base.group_user,1,1,1,0
access_sf_cutting_tool_type_admin,sf_cutting_tool_type_admin,model_sf_cutting_tool_type,base.group_system,1,1,1,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
access_sf_functional_cutting_tool_model_admin,sf_functional_cutting_tool_model_admin,model_sf_functional_cutting_tool_model,base.group_system,1,1,1,0
access_sf_fixture_material,sf_fixture_material,model_sf_fixture_material,base.group_user,1,1,1,0
access_sf_fixture_material_admin,sf_fixture_material_admin,model_sf_fixture_material,base.group_system,1,1,1,0
access_sf_fixture_materials_basic_parameters,sf_fixture_materials_basic_parameters,model_sf_fixture_materials_basic_parameters,base.group_user,1,1,1,0
access_sf_fixture_materials_basic_parameters_admin,sf_fixture_materials_basic_parameters_admin,model_sf_fixture_materials_basic_parameters,base.group_system,1,1,1,0
access_sf_multi_mounting_type,sf_multi_mounting_type,model_sf_multi_mounting_type,base.group_user,1,1,1,0
access_sf_multi_mounting_type_admin,sf_multi_mounting_type_admin,model_sf_multi_mounting_type,base.group_system,1,1,1,0
access_sf_fixture_model,sf_fixture_model,model_sf_fixture_model,base.group_user,1,1,1,0
access_sf_fixture_model_admin,sf_fixture_model_admin,model_sf_fixture_model,base.group_system,1,1,1,0
access_sf_functional_fixture_type,sf_functional_fixture_type,model_sf_functional_fixture_type,base.group_user,1,1,1,1
access_sf_functional_fixture,sf_functional_fixture,model_sf_functional_fixture,base.group_user,1,1,1,1
access_sf_sync_common,sf_sync_common,model_sf_sync_common,base.group_user,1,1,1,1
access_sf_international_standards,sf_international_standards,model_sf_international_standards,base.group_user,1,1,1,1
access_material_apply,material_apply,model_material_apply,base.group_user,1,1,1,1
access_sf_cutting_tool_standard_library,sf_cutting_tool_standard_library,model_sf_cutting_tool_standard_library,base.group_user,1,1,1,1
access_sf_tool_groups,sf_tool_groups,model_sf_tool_groups,base.group_user,1,1,1,1
access_sf_tool_materials_basic_parameters,sf_tool_materials_basic_parameters,model_sf_tool_materials_basic_parameters,base.group_user,1,1,1,1
access_sf_cutting_speed,sf_cutting_speed,model_sf_cutting_speed,base.group_user,1,1,1,1
access_sf_feed_per_tooth,sf_feed_per_tooth,model_sf_feed_per_tooth,base.group_user,1,1,1,1
access_sf_functional_fixture_type_admin,sf_functional_fixture_type_admin,model_sf_functional_fixture_type,base.group_system,1,1,1,0
access_sf_functional_fixture,sf_functional_fixture,model_sf_functional_fixture,base.group_user,1,1,1,0
access_sf_functional_fixture_admin,sf_functional_fixture_admin,model_sf_functional_fixture,base.group_system,1,1,1,0
access_sf_sync_common,sf_sync_common,model_sf_sync_common,base.group_user,1,1,1,0
access_sf_sync_common,sf_sync_common_admin,model_sf_sync_common,base.group_system,1,1,1,0
access_sf_international_standards,sf_international_standards,model_sf_international_standards,base.group_user,1,1,1,0
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_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
access_sf_tool_materials_basic_parameters_admin,sf_tool_materials_basic_parameters_admin,model_sf_tool_materials_basic_parameters,base.group_system,1,1,1,0
access_sf_cutting_speed,sf_cutting_speed,model_sf_cutting_speed,base.group_user,1,1,1,0
access_sf_cutting_speed_admin,sf_cutting_speed_admin,model_sf_cutting_speed,base.group_system,1,1,1,0
access_sf_cutting_speed_group_purchase_director,sf_cutting_speed_group_purchase_director,model_sf_cutting_speed,sf_base.group_purchase_director,1,0,1,0
access_sf_cutting_speed_group_sale_director,sf_cutting_speed_group_sale_director,model_sf_cutting_speed,sf_base.group_sale_director,1,0,1,0
access_sf_cutting_speed_group_plan_director,sf_cutting_speed_group_plan_director,model_sf_cutting_speed,sf_base.group_plan_director,1,0,1,0
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,0,1,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,0,1,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,0,1,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
access_sf_ramping_angle_admin,sf_ramping_angle_admin,model_sf_ramping_angle,base.group_system,1,1,1,1
access_sf_cutting_width_depth,sf_cutting_width_depth,model_sf_cutting_width_depth,base.group_user,1,1,1,1
access_sf_cutting_width_depth_admin,sf_cutting_width_depth_admin,model_sf_cutting_width_depth,base.group_system,1,1,1,1
access_sf_machine_tool,sf_machine_tool,model_sf_machine_tool,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_machine_tool_type,sf_machine_tool_type,model_sf_machine_tool_type,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_machine_brand,sf_machine_brand,model_sf_machine_brand,sf_base.group_sf_mrp_user,1,0,0,0
@@ -49,7 +85,9 @@ access_sf_supplier_sort,sf_supplier_sort,model_sf_supplier_sort,sf_base.group_sf
access_sf_production_process_parameter,sf_production_process_parameter,model_sf_production_process_parameter,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_production_process_category,sf_production_process_category,model_sf_production_process_category,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_machine_tool_category,sf_machine_tool_category,model_sf_machine_tool_category,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_cutting_tool_material,sf_cutting_tool_material,model_sf_cutting_tool_material,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_cutting_tool_material_group_purchase_director,sf_cutting_tool_material_group_purchase_director,model_sf_cutting_tool_material,sf_base.group_purchase_director,1,0,1,0
access_sf_cutting_tool_material_group_sale_director,sf_cutting_tool_material_group_sale_director,model_sf_cutting_tool_material,sf_base.group_sale_director,1,0,1,0
access_sf_cutting_tool_material_group_plan_director,sf_cutting_tool_material_group_plan_director,model_sf_cutting_tool_material,sf_base.group_plan_director,1,0,1,0
access_sf_cutting_tool_type,sf_cutting_tool_type,model_sf_cutting_tool_type,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_functional_cutting_tool,sf_functional_cutting_tool,model_sf_functional_cutting_tool,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_functional_cutting_tool_model,sf_functional_cutting_tool_model,model_sf_functional_cutting_tool_model,sf_base.group_sf_mrp_user,1,0,0,0
@@ -62,9 +100,17 @@ 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,sf_cutting_tool_standard_library,model_sf_cutting_tool_standard_library,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,sf_tool_materials_basic_parameters,model_sf_tool_materials_basic_parameters,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_feed_per_tooth,sf_feed_per_tooth,model_sf_feed_per_tooth,sf_base.group_sf_mrp_user,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
@@ -77,6 +123,9 @@ access_purchase_order_line_group_purchase,access_purchase_order_line_group_purch
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
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_sf_machine_tool sf_machine_tool model_sf_machine_tool base.group_user 1 1 1 1 0
3 access_sf_machine_tool_type access_sf_machine_tool_admin sf_machine_tool_type sf_machine_tool_admin model_sf_machine_tool_type model_sf_machine_tool base.group_user base.group_system 1 1 1 1 0
4 access_sf_machine_brand access_sf_machine_tool_type sf_machine_brand sf_machine_tool_type model_sf_machine_brand model_sf_machine_tool_type base.group_user 1 1 1 1 0
5 access_sf_machine_brand_tags access_sf_machine_tool_type_admin sf_machine_brand_tags sf_machine_tool_type_admin model_sf_machine_brand_tags model_sf_machine_tool_type base.group_user base.group_system 1 1 1 1 0
6 access_sf_machine_control_system access_sf_machine_brand sf_machine_control_system sf_machine_brand model_sf_machine_control_system model_sf_machine_brand base.group_user 1 1 1 1 0
7 access_sf_processing_order access_sf_machine_brand_admin sf_processing_order sf_machine_brand_admin model_sf_processing_order model_sf_machine_brand base.group_user base.group_system 1 1 1 1 0
8 access_sf_production_process access_sf_machine_brand_tags sf_production_process sf_machine_brand_tags model_sf_production_process model_sf_machine_brand_tags base.group_user 1 1 1 1 0
9 access_sf_production_materials access_sf_machine_brand_tags_admin sf_production_materials sf_machine_brand_tags_admin model_sf_production_materials model_sf_machine_brand_tags base.group_user base.group_system 1 1 1 1 0
10 access_sf_materials_model access_sf_machine_control_system sf_materials_model sf_machine_control_system model_sf_materials_model model_sf_machine_control_system base.group_user 1 1 1 1 0
11 access_sf_processing_technology access_sf_machine_control_system_admin sf_processing_technology sf_machine_control_system_admin model_sf_processing_technology model_sf_machine_control_system base.group_user base.group_system 1 1 1 1 0
12 access_sf_supplier_sort access_sf_processing_order sf_supplier_sort sf_processing_order model_sf_supplier_sort model_sf_processing_order base.group_user 1 1 1 1 0
13 access_sf_production_process_parameter access_sf_processing_order_admin sf_production_process_parameter sf_processing_order_admin model_sf_production_process_parameter model_sf_processing_order base.group_user base.group_system 1 1 1 1 0
14 access_sf_production_process_category access_sf_production_process sf_production_process_category sf_production_process model_sf_production_process_category model_sf_production_process base.group_user 1 1 1 1 0
15 access_sf_machine_tool_category access_sf_production_process_admin sf_machine_tool_category sf_production_process_admin model_sf_machine_tool_category model_sf_production_process base.group_user base.group_system 1 1 1 1 0
16 access_sf_cutting_tool_material access_sf_production_materials sf_cutting_tool_material sf_production_materials model_sf_cutting_tool_material model_sf_production_materials base.group_user 1 1 1 1 0
17 access_sf_cutting_tool_type access_sf_production_materials_admin sf_cutting_tool_type sf_production_materials_admin model_sf_cutting_tool_type model_sf_production_materials base.group_user base.group_system 1 1 1 1 0
18 access_sf_functional_cutting_tool access_sf_materials_model sf_functional_cutting_tool sf_materials_model model_sf_functional_cutting_tool model_sf_materials_model base.group_user 1 1 1 1 0
19 access_sf_functional_cutting_tool_model access_sf_materials_model_admin sf_functional_cutting_tool_model sf_materials_model_admin model_sf_functional_cutting_tool_model model_sf_materials_model base.group_user base.group_system 1 1 1 1 0
20 access_sf_fixture_material access_sf_processing_technology sf_fixture_material sf_processing_technology model_sf_fixture_material model_sf_processing_technology base.group_user 1 1 1 1 0
21 access_sf_fixture_materials_basic_parameters access_sf_processing_technology_admin sf_fixture_materials_basic_parameters sf_processing_technology_admin model_sf_fixture_materials_basic_parameters model_sf_processing_technology base.group_user base.group_system 1 1 1 1 0
22 access_sf_multi_mounting_type access_sf_supplier_sort sf_multi_mounting_type sf_supplier_sort model_sf_multi_mounting_type model_sf_supplier_sort base.group_user 1 1 1 1 0
23 access_sf_fixture_model access_sf_supplier_sort_admin sf_fixture_model sf_supplier_sort_admin model_sf_fixture_model model_sf_supplier_sort base.group_user base.group_system 1 1 1 1 0
24 access_sf_functional_fixture_type access_sf_production_process_parameter sf_functional_fixture_type sf_production_process_parameter model_sf_functional_fixture_type model_sf_production_process_parameter base.group_user 1 1 1 1 0
25 access_sf_production_process_parameter_admin sf_production_process_parameter_admin model_sf_production_process_parameter base.group_system 1 1 1 0
26 access_sf_production_process_category sf_production_process_category model_sf_production_process_category base.group_user 1 1 1 0
27 access_sf_production_process_category_admin sf_production_process_category_admin model_sf_production_process_category base.group_system 1 1 1 0
28 access_sf_machine_tool_category sf_machine_tool_category model_sf_machine_tool_category base.group_user 1 1 1 0
29 access_sf_machine_tool_category_admin sf_machine_tool_category_admin model_sf_machine_tool_category base.group_system 1 1 1 0
30 access_sf_cutting_tool_material sf_cutting_tool_material model_sf_cutting_tool_material base.group_user 1 1 1 0
31 access_sf_cutting_tool_material_admin sf_cutting_tool_material_admin model_sf_cutting_tool_material base.group_system 1 1 1 0
32 access_sf_cutting_tool_type sf_cutting_tool_type model_sf_cutting_tool_type base.group_user 1 1 1 0
33 access_sf_cutting_tool_type_admin sf_cutting_tool_type_admin model_sf_cutting_tool_type base.group_system 1 1 1 0
34 access_sf_functional_cutting_tool sf_functional_cutting_tool model_sf_functional_cutting_tool base.group_user 1 1 1 0
35 access_sf_functional_cutting_tool_admin sf_functional_cutting_tool_admin model_sf_functional_cutting_tool base.group_system 1 1 1 0
36 access_sf_functional_cutting_tool_model sf_functional_cutting_tool_model model_sf_functional_cutting_tool_model base.group_user 1 1 1 0
37 access_sf_functional_cutting_tool_model_admin sf_functional_cutting_tool_model_admin model_sf_functional_cutting_tool_model base.group_system 1 1 1 0
38 access_sf_fixture_material sf_fixture_material model_sf_fixture_material base.group_user 1 1 1 0
39 access_sf_fixture_material_admin sf_fixture_material_admin model_sf_fixture_material base.group_system 1 1 1 0
40 access_sf_fixture_materials_basic_parameters sf_fixture_materials_basic_parameters model_sf_fixture_materials_basic_parameters base.group_user 1 1 1 0
41 access_sf_fixture_materials_basic_parameters_admin sf_fixture_materials_basic_parameters_admin model_sf_fixture_materials_basic_parameters base.group_system 1 1 1 0
42 access_sf_multi_mounting_type sf_multi_mounting_type model_sf_multi_mounting_type base.group_user 1 1 1 0
43 access_sf_multi_mounting_type_admin sf_multi_mounting_type_admin model_sf_multi_mounting_type base.group_system 1 1 1 0
44 access_sf_fixture_model sf_fixture_model model_sf_fixture_model base.group_user 1 1 1 0
45 access_sf_fixture_model_admin sf_fixture_model_admin model_sf_fixture_model base.group_system 1 1 1 0
46 access_sf_functional_fixture access_sf_functional_fixture_type sf_functional_fixture sf_functional_fixture_type model_sf_functional_fixture model_sf_functional_fixture_type base.group_user 1 1 1 1
47 access_sf_sync_common access_sf_functional_fixture_type_admin sf_sync_common sf_functional_fixture_type_admin model_sf_sync_common model_sf_functional_fixture_type base.group_user base.group_system 1 1 1 1 0
48 access_sf_international_standards access_sf_functional_fixture sf_international_standards sf_functional_fixture model_sf_international_standards model_sf_functional_fixture base.group_user 1 1 1 1 0
49 access_material_apply access_sf_functional_fixture_admin material_apply sf_functional_fixture_admin model_material_apply model_sf_functional_fixture base.group_user base.group_system 1 1 1 1 0
50 access_sf_cutting_tool_standard_library access_sf_sync_common sf_cutting_tool_standard_library sf_sync_common model_sf_cutting_tool_standard_library model_sf_sync_common base.group_user 1 1 1 1 0
51 access_sf_tool_groups access_sf_sync_common sf_tool_groups sf_sync_common_admin model_sf_tool_groups model_sf_sync_common base.group_user base.group_system 1 1 1 1 0
52 access_sf_tool_materials_basic_parameters access_sf_international_standards sf_tool_materials_basic_parameters sf_international_standards model_sf_tool_materials_basic_parameters model_sf_international_standards base.group_user 1 1 1 1 0
53 access_sf_cutting_speed access_sf_international_standards_admin sf_cutting_speed sf_international_standards_admin model_sf_cutting_speed model_sf_international_standards base.group_user base.group_system 1 1 1 1 0
54 access_sf_feed_per_tooth access_material_apply sf_feed_per_tooth material_apply model_sf_feed_per_tooth model_material_apply base.group_user 1 1 1 1 0
55 access_sf_ramping_angle access_material_apply_admin sf_ramping_angle material_apply_admin model_sf_ramping_angle model_material_apply base.group_user base.group_system 1 1 1 1 0
56 access_sf_cutting_tool_standard_library sf_cutting_tool_standard_library model_sf_cutting_tool_standard_library base.group_user 1 1 1 0
57 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
58 access_sf_tool_materials_basic_parameters sf_tool_materials_basic_parameters model_sf_tool_materials_basic_parameters base.group_user 1 1 1 0
59 access_sf_tool_materials_basic_parameters_admin sf_tool_materials_basic_parameters_admin model_sf_tool_materials_basic_parameters base.group_system 1 1 1 0
60 access_sf_cutting_speed sf_cutting_speed model_sf_cutting_speed base.group_user 1 1 1 0
61 access_sf_cutting_speed_admin sf_cutting_speed_admin model_sf_cutting_speed base.group_system 1 1 1 0
62 access_sf_cutting_speed_group_purchase_director sf_cutting_speed_group_purchase_director model_sf_cutting_speed sf_base.group_purchase_director 1 0 1 0
63 access_sf_cutting_speed_group_sale_director sf_cutting_speed_group_sale_director model_sf_cutting_speed sf_base.group_sale_director 1 0 1 0
64 access_sf_cutting_speed_group_plan_director sf_cutting_speed_group_plan_director model_sf_cutting_speed sf_base.group_plan_director 1 0 1 0
65 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 0 1 0
66 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 0 1 0
67 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 0 1 0
68 access_sf_feed_per_tooth sf_feed_per_tooth model_sf_feed_per_tooth base.group_user 1 1 1 0
69 access_sf_feed_per_tooth_admin sf_feed_per_tooth_admin model_sf_feed_per_tooth base.group_system 1 1 1 0
70 access_sf_cutting_width_depth access_sf_ramping_angle sf_cutting_width_depth sf_ramping_angle model_sf_cutting_width_depth model_sf_ramping_angle base.group_user 1 1 1 1
71 access_sf_ramping_angle_admin sf_ramping_angle_admin model_sf_ramping_angle base.group_system 1 1 1 1
72 access_sf_machine_tool access_sf_cutting_width_depth sf_machine_tool sf_cutting_width_depth model_sf_machine_tool model_sf_cutting_width_depth sf_base.group_sf_mrp_user base.group_user 1 0 1 0 1 0 1
73 access_sf_machine_tool_type access_sf_cutting_width_depth_admin sf_machine_tool_type sf_cutting_width_depth_admin model_sf_machine_tool_type model_sf_cutting_width_depth sf_base.group_sf_mrp_user base.group_system 1 0 1 0 1 0 1
74 access_sf_machine_brand access_sf_machine_tool sf_machine_brand sf_machine_tool model_sf_machine_brand model_sf_machine_tool sf_base.group_sf_mrp_user 1 0 0 0
75 access_sf_machine_brand_tags access_sf_machine_tool_type sf_machine_brand_tags sf_machine_tool_type model_sf_machine_brand_tags model_sf_machine_tool_type base.group_user sf_base.group_sf_mrp_user 1 1 0 1 0 1 0
76 access_sf_machine_control_system access_sf_machine_brand sf_machine_control_system sf_machine_brand model_sf_machine_control_system model_sf_machine_brand sf_base.group_sf_mrp_user 1 0 0 0
85 access_sf_machine_tool_category access_sf_production_process_parameter sf_machine_tool_category sf_production_process_parameter model_sf_machine_tool_category model_sf_production_process_parameter sf_base.group_sf_mrp_user 1 0 0 0
86 access_sf_cutting_tool_material access_sf_production_process_category sf_cutting_tool_material sf_production_process_category model_sf_cutting_tool_material model_sf_production_process_category sf_base.group_sf_mrp_user 1 0 0 0
87 access_sf_cutting_tool_type access_sf_machine_tool_category sf_cutting_tool_type sf_machine_tool_category model_sf_cutting_tool_type model_sf_machine_tool_category sf_base.group_sf_mrp_user 1 0 0 0
88 access_sf_functional_cutting_tool access_sf_cutting_tool_material_group_purchase_director sf_functional_cutting_tool sf_cutting_tool_material_group_purchase_director model_sf_functional_cutting_tool model_sf_cutting_tool_material sf_base.group_sf_mrp_user sf_base.group_purchase_director 1 0 0 1 0
89 access_sf_cutting_tool_material_group_sale_director sf_cutting_tool_material_group_sale_director model_sf_cutting_tool_material sf_base.group_sale_director 1 0 1 0
90 access_sf_cutting_tool_material_group_plan_director sf_cutting_tool_material_group_plan_director model_sf_cutting_tool_material sf_base.group_plan_director 1 0 1 0
91 access_sf_functional_cutting_tool_model access_sf_cutting_tool_type sf_functional_cutting_tool_model sf_cutting_tool_type model_sf_functional_cutting_tool_model model_sf_cutting_tool_type sf_base.group_sf_mrp_user 1 0 0 0
92 access_sf_fixture_material access_sf_functional_cutting_tool sf_fixture_material sf_functional_cutting_tool model_sf_fixture_material model_sf_functional_cutting_tool sf_base.group_sf_mrp_user 1 0 0 0
93 access_sf_fixture_materials_basic_parameters access_sf_functional_cutting_tool_model sf_fixture_materials_basic_parameters sf_functional_cutting_tool_model model_sf_fixture_materials_basic_parameters model_sf_functional_cutting_tool_model sf_base.group_sf_mrp_user 1 0 0 0
100 access_material_apply access_sf_sync_common material_apply sf_sync_common model_material_apply model_sf_sync_common sf_base.group_sf_mrp_user 1 0 0 0
101 access_sf_cutting_tool_standard_library access_sf_international_standards sf_cutting_tool_standard_library sf_international_standards model_sf_cutting_tool_standard_library model_sf_international_standards sf_base.group_sf_mrp_user 1 0 0 0
102 access_sf_tool_groups access_material_apply sf_tool_groups material_apply model_sf_tool_groups model_material_apply sf_base.group_sf_mrp_user 1 0 0 0
103 access_sf_tool_materials_basic_parameters access_sf_cutting_tool_standard_library_group_sf_mrp_user sf_tool_materials_basic_parameters sf_cutting_tool_standard_library_group_sf_mrp_user model_sf_tool_materials_basic_parameters model_sf_cutting_tool_standard_library sf_base.group_sf_mrp_user 1 0 0 0
104 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
105 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
106 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
107 access_sf_tool_groups sf_tool_groups model_sf_tool_groups sf_base.group_sf_mrp_user 1 0 0 0
108 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
109 access_sf_cutting_speed access_sf_tool_materials_basic_parameters_group_plan_director sf_cutting_speed sf_tool_materials_basic_parameters_group_plan_director model_sf_cutting_speed model_sf_tool_materials_basic_parameters sf_base.group_sf_mrp_user sf_base.group_plan_director 1 0 0 1 0
110 access_sf_feed_per_tooth access_sf_tool_materials_basic_parameters_group_purchase_director sf_feed_per_tooth sf_tool_materials_basic_parameters_group_purchase_director model_sf_feed_per_tooth model_sf_tool_materials_basic_parameters sf_base.group_sf_mrp_user sf_base.group_purchase_director 1 0 0 1 0
111 access_sf_cutting_speed sf_cutting_speed model_sf_cutting_speed sf_base.group_sf_mrp_user 1 0 0 0
112 access_sf_feed_per_tooth sf_feed_per_tooth model_sf_feed_per_tooth sf_base.group_sf_mrp_user 1 0 0 0
113 access_sf_ramping_angle sf_ramping_angle model_sf_ramping_angle sf_base.group_sf_mrp_user 1 0 0 0
114 access_sf_ramping_angle access_sf_cutting_width_depth sf_ramping_angle sf_cutting_width_depth model_sf_ramping_angle model_sf_cutting_width_depth sf_base.group_sf_mrp_user 1 0 0 0
115 access_sf_cutting_width_depth access_maintenance_equipment_image sf_cutting_width_depth maintenance_equipment_image model_sf_cutting_width_depth model_maintenance_equipment_image sf_base.group_sf_mrp_user base.group_user 1 0 1 0 1 0 1
116 access_maintenance_equipment_image access_purchase_order_group_purchase maintenance_equipment_image access_purchase_order_group_purchase model_maintenance_equipment_image purchase.model_purchase_order base.group_user sf_base.group_purchase 1 1 1 1 0
123 access_res_partner access_purchase_order res.partner purchase.order base.model_res_partner purchase.model_purchase_order sf_base.group_plan_dispatch 1 0 0 0
124 access_purchase_order_line access_res_partner purchase.order.line res.partner purchase.model_purchase_order_line base.model_res_partner sf_base.group_plan_dispatch 1 0 0 0
125 access_account_move_line access_purchase_order_line account.move.line purchase.order.line account.model_account_move_line purchase.model_purchase_order_line sf_base.group_plan_dispatch 1 0 0 0
126 access_account_move_line account.move.line account.model_account_move_line sf_base.group_plan_dispatch 1 0 0 0
127 access_sf_machine_tool sf_machine_tool model_sf_machine_tool sf_base.group_sf_mrp_user 1 1 0 0
128 access_sf_machine_tool_type sf_machine_tool_type model_sf_machine_tool_type sf_base.group_sf_mrp_user 1 1 0 0
129 access_sf_machine_tool access_sf_machine_brand sf_machine_tool sf_machine_brand model_sf_machine_tool model_sf_machine_brand sf_base.group_sf_mrp_user 1 1 0 0
130 access_sf_machine_tool_type access_sf_machine_brand_tags sf_machine_tool_type sf_machine_brand_tags model_sf_machine_tool_type model_sf_machine_brand_tags sf_base.group_sf_mrp_user 1 1 0 0
131 access_sf_machine_brand access_sf_machine_control_system sf_machine_brand sf_machine_control_system model_sf_machine_brand model_sf_machine_control_system sf_base.group_sf_mrp_user 1 1 0 0

View File

@@ -495,7 +495,7 @@
<field name="name">刀具组</field>
<field name="model">sf.tool.groups</field>
<field name="arch" type="xml">
<tree create="1" edit="1" delete="1" editable="bottom">
<tree editable="bottom">
<field name="name"/>
<field name="equipment_ids" widget="many2many_tags"/>
<field name="remark"/>

View File

@@ -33,6 +33,7 @@ class Sf_Bf_Connect(http.Controller):
aa = request.env['sale.order'].sudo().search([('name', '=', order_id.name)])
logging.info('get_bfm_process_or===================================:%s' % order_id.name)
aa.default_code = kw['order_number']
aa.logistics_way = kw['logistics_way']
logging.info('get_bfm_process_order_listaaaaaaaaaaaaaaaaaaaaaaaaaaaa================:%s' % aa.default_code)
for item in bfm_process_order_list:
product = request.env['product.template'].sudo().product_create(product_id, item, order_id,

View File

@@ -42,6 +42,25 @@ class JdEclp(models.Model):
# bill_show = fields.Binary(string='物流面单展示', readonly=True, related='self.bill.datas')
bill_show = fields.Binary(string='物流面单展示', readonly=True)
check_out = fields.Char(string='查询是否为出库单', compute='_check_is_out')
# 是否下了快递单
is_bill = fields.Boolean(string='是否下了快递单', default=False)
# 物流状态
logistics_status = fields.Selection([('0', '未下单'), ('1', '已下单'), ('2', '已获取物流面单'), ('3', '已打印物流单')],
string='物流状态', default='0', readonly=True)
logistics_way = fields.Selection([('自提', '自提'), ('到付', '到付'), ('在线支付', '在线支付')], string='物流方式', readonly=True)
def button_validate(self):
"""
重写出库方法,获取物流面单
"""
res = super(JdEclp, self).button_validate()
if self.check_out == 'OUT':
if self.logistics_way != '自提':
if self.logistics_status != '3':
raise ValidationError('非自提订单,必须先下物流单,并获取物流面单后才可出库!')
return res
@api.depends('name')
def _check_is_out(self):
@@ -68,6 +87,7 @@ class JdEclp(models.Model):
# if self.receiverName and self.receiverMobile and self.receiverProvinceName and self.receiverCityName and
# self.receiverCountyName and self.receiverTownName:
sale_order_id = self.env['sale.order'].search([('name', '=', self.origin)])
self.logistics_way = sale_order_id.logistics_way
# stock_picking_type_id = self.enc['stock.picking.type'].search([('picking_type_id', '=', '')])
# if sale_order_id.address_of_delivery != False:
# if not sale_order_id:
@@ -141,6 +161,8 @@ class JdEclp(models.Model):
response = requests.post(url2, json=json2, data=None)
# _logger.info('调用成功2', response.json()['result']['wbNo'])
self.carrier_tracking_ref = response.json()['result']['wbNo']
self.is_bill = True
self.logistics_status = '1'
# else:
# raise UserError("选择京东物流才能下单呦")
@@ -180,3 +202,4 @@ class JdEclp(models.Model):
# 'model_name': 'stock.picking',
})
_logger.info(attachment)
self.logistics_status = '2'

View File

@@ -9,8 +9,8 @@
<xpath expr="//page[last()]" position="before">
<page string="token和密钥">
<group>
<field name="sf_token"/>
<field name="sf_secret_key"/>
<field name="sf_token" readonly="1"/>
<field name="sf_secret_key" readonly="1"/>
</group>
</page>
</xpath>

View File

@@ -12,16 +12,30 @@
</field>
</record>
<!-- <record id="sf_bf_connect_vpicktree" model="ir.ui.view"> -->
<!-- <field name="name">sf.bf.connect.vpicktree</field> -->
<!-- <field name="model">stock.picking</field> -->
<!-- <field name="inherit_id" ref="stock.vpicktree"/> -->
<!-- <field name="arch" type="xml"> -->
<!-- <field name="state" position="after"> -->
<!-- <field name="logistics_status" string="物流状态"/> -->
<!-- </field> -->
<!-- </field> -->
<!-- </record> -->
<record id="custom_view_picking_form" model="ir.ui.view">
<field name="name">物流</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_form"/>
<field name="arch" type="xml">
<xpath expr="//form//header//button[@name='action_assign']" position="after">
<field name="is_bill" invisible="True"/>
<field name="logistics_status" invisible="True"/>
<field name="logistics_way" invisible="True"/>
<button string="京东物流下单" name="create_order" type="object" confirm="是否确认物流下单" class="btn-primary"
attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
attrs="{'invisible': ['|', '|', '|', ('check_out', '!=', 'OUT'), ('state', '!=', 'assigned'), ('is_bill', '=', True), ('logistics_way', '=', '自提')]}"/>
<button string="获取物流面单" name="get_bill" type="object" confirm="是否获取物流面单" class="btn-primary"
attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
attrs="{'invisible': ['|', '|', '|', '|', ('check_out', '!=', 'OUT'), ('state', '!=', 'assigned'), ('logistics_status', '=', '2'), ('is_bill', '=', False), ('logistics_way', '=', '自提')]}"/>
</xpath>
</field>
</record>
@@ -31,6 +45,12 @@
<field name="model">stock.picking</field>
<field name="inherit_id" ref="delivery.view_picking_withcarrier_out_form"/>
<field name="arch" type="xml">
<field name="location_id" position="after">
<field name="logistics_status" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
<field name="logistics_way" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
</field>
<xpath expr="//group//field[@name='carrier_id']" position="after">
<!-- <field name="senderNickName" domain="[('self.name', 'like', '%OUT%')]"/> -->
<field name="senderNickName" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
@@ -48,6 +68,7 @@
<field name="grossVolume" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
<field name="pickupBeginTime" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
<field name="bill_show" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>
<field name="logistics_status"/>
</xpath>
<xpath expr="//group//field[@name='group_id']" position="after">
<field name="bill_show" widget="pdf_viewer" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>

View File

@@ -10,6 +10,7 @@
<field name="sequence_number"/>
<field name="program_name"/>
<field name="cnc_id" string="文件"/>
<field name="functional_tool_type_id"/>
<field name="cutting_tool_name"/>
<field name="cutting_tool_no"/>
<field name="processing_type"/>

View File

@@ -10,7 +10,7 @@
<xpath expr="//form//notebook//page[1]" position="after">
<!-- <xpath expr="//page[@name='other']" position="before">-->
<!-- <notebook> -->
<page string="机床监控">
<page string="机床运行状态" attrs="{'invisible': [('equipment_type', '!=', '机床')]}">
<group string='状态监控'>
<group>
<field name="timestamp"/>
@@ -143,7 +143,7 @@
<!-- </div> -->
<!-- </group> -->
</page>
<page string="机床配置">
<page string="机床运行数据" attrs="{'invisible': [('equipment_type', '!=', '机床')]}">
<!-- <group string="机床配置">--> -->
<group string="ftp相关">
<group>

View File

@@ -21,7 +21,8 @@ access_maintenance_equipment_agv_log,maintenance_equipment_agv_log,model_mainten
access_maintenance_equipment_agv_log,maintenance_equipment_agv_log,model_maintenance_equipment_agv_log,base.group_user,1,1,1,1
access_maintenance_request_group_plan_dispatch,maintenance.request,maintenance.model_maintenance_request,sf_base.group_plan_dispatch,1,0,0,0
access_maintenance_system_user,equipment.request system user,maintenance.model_maintenance_request,base.group_user,1,0,0,0
access_maintenance_equipment_group_plan_dispatch,maintenance.equipment,maintenance.model_maintenance_equipment,sf_base.group_plan_dispatch,1,0,0,0
access_sf_maintenance_logs_group_plan_dispatch,sf_maintenance_logs,model_sf_maintenance_logs,sf_base.group_plan_dispatch,1,0,0,0
access_maintenance_standard_image_group_plan_dispatch,maintenance_standard_image,model_maintenance_standard_image,sf_base.group_plan_dispatch,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
21 access_maintenance_equipment_agv_log maintenance_equipment_agv_log model_maintenance_equipment_agv_log base.group_user 1 1 1 1
22 access_maintenance_request_group_plan_dispatch access_maintenance_system_user maintenance.request equipment.request system user maintenance.model_maintenance_request sf_base.group_plan_dispatch base.group_user 1 0 0 0
23 access_maintenance_equipment_group_plan_dispatch maintenance.equipment maintenance.model_maintenance_equipment sf_base.group_plan_dispatch 1 0 0 0
24 access_sf_maintenance_logs_group_plan_dispatch sf_maintenance_logs model_sf_maintenance_logs sf_base.group_plan_dispatch 1 0 0 0
25 access_maintenance_standard_image_group_plan_dispatch maintenance_standard_image model_maintenance_standard_image sf_base.group_plan_dispatch 1 0 0 0
26 access_maintenance_standard_image_group_plan_dispatch access_equipment_maintenance_standards_group_plan_dispatch maintenance_standard_image equipment_maintenance_standards model_maintenance_standard_image model_equipment_maintenance_standards sf_base.group_plan_dispatch 1 0 0 0
27 access_equipment_maintenance_standards_group_plan_dispatch access_maintenance_standards_group_plan_dispatch equipment_maintenance_standards maintenance_standards model_equipment_maintenance_standards model_maintenance_standards sf_base.group_plan_dispatch 1 0 0 0
28 access_maintenance_standards_group_plan_dispatch access_sf_robot_axis_num_group_plan_dispatch maintenance_standards sf.robot.axis.num model_maintenance_standards model_sf_robot_axis_num sf_base.group_plan_dispatch 1 0 0 0

View File

@@ -11,5 +11,18 @@
<field name="perm_create">False</field>
<field name="perm_unlink">False</field>
</record>
<!-- 对维保计划做“最小权限”控制,计划调度岗只能看到所有的维保计划,不能修改,不能删除,不能创建 -->
<record id="maintenance_request_rule_plan_dispatch" model="ir.rule">
<field name="name">Maintenance Request Plan Dispatch Rule</field>
<field name="model_id" ref="maintenance.model_maintenance_request"/>
<field name="groups" eval="[(4, ref('sf_base.group_plan_dispatch'))]"/>
<!-- <field name="domain_force">['|',('user_id','=',user.id),('user_id','=',False)]</field> -->
<field name="perm_read">True</field>
<field name="perm_write">False</field>
<field name="perm_create">False</field>
<field name="perm_unlink">False</field>
</record>
</data>
</odoo>

View File

@@ -1,2 +1,3 @@
from . import models
from . import controllers
from . import wizard

View File

@@ -15,6 +15,7 @@
'data/stock_data.xml',
'security/group_security.xml',
'security/ir.model.access.csv',
'wizard/workpiece_delivery_views.xml',
'views/mrp_views_menus.xml',
'views/mrp_production_addional_change.xml',
'views/mrp_routing_workcenter_view.xml',

View File

@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
import logging
import json
import base64
from odoo import http
from odoo.http import request
@@ -21,9 +20,9 @@ class Manufacturing_Connect(http.Controller):
res = {'Succeed': True, 'Datas': []}
datas = request.httprequest.data
ret = json.loads(datas)
ret = json.loads(ret['result'])
logging.info('RfidCode:%s' % ret)
workorder = request.env['mrp.workorder'].sudo().search([('name', '=', ret['RfidCode'])])
workorder = request.env['mrp.workorder'].sudo().search(
[('production_id.name', '=', 'WH/MO/00071'), ('routing_type', '=', '装夹')])
if workorder:
for item in workorder:
res['Datas'].append({
@@ -33,14 +32,88 @@ class Manufacturing_Connect(http.Controller):
'Quantity': 1,
'MaterialId': item.product_id.default_code,
'MaterialName': item.product_id.name,
# 'Spec':item.mat,
'Material': item.materials_type_id.name
'Spec': '%s×%s×%s' % (item.move_raw_ids.materiel_length, item.move_raw_ids.materiel_width,
item.move_raw_ids.materiel_height),
'Material': item.product_id.materials_type_id.name
})
except Exception as e:
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
logging.info('get_Work_Info error:%s' % e)
return json.JSONEncoder().encode(res)
@http.route('/AutoDeviceApi/GetShiftPlan', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
cors="*")
def get_ShiftPlan(self, **kw):
"""
自动化每天获取机台日计划
:param kw:
:return:
"""
logging.info('get_ShiftPlan:%s' % kw)
try:
res = {'Succeed': True, 'Datas': []}
datas = request.httprequest.data
ret = json.loads(datas)
ret = json.loads(ret['result'])
logging.info('RfidCode:%s' % ret)
workorder = request.env['mrp.workorder'].sudo().search([('name', '=', ret['ProductionLine'])])
if workorder:
for item in workorder:
date_planned_start = ''
date_planned_finished = ''
if item.date_planned_start is not False:
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:
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,
'CraftName': item.name,
'Quantity': 1,
'WortkStart': date_planned_start,
'WorkEnd': date_planned_finished,
'MaterialId': item.product_id.default_code,
'MaterialName': item.product_id.name,
# 'Spec':item.mat,
'Material': item.materials_type_id.name
})
except Exception as e:
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
logging.info('get_ShiftPlan error:%s' % e)
return json.JSONEncoder().encode(res)
@http.route('/AutoDeviceApi/QcCheck', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
cors="*")
def get_qcCheck(self, **kw):
"""
工件预调(前置三元检测)
1、前置三元检测在产线外三元检测设备把测量信息上传给MES
MES生成检测定位数据。中控系统传递RFID编号给MES获取测量偏置结果。来源为三元检测工单上的字段
:param kw:
:return:
"""
logging.info('get_qcCheck:%s' % kw)
try:
res = {'Succeed': True, 'Datas': []}
datas = request.httprequest.data
ret = json.loads(datas)
ret = json.loads(ret['result'])
logging.info('RfidCode:%s' % ret)
workorder = request.env['mrp.workorder'].sudo().search([('routing_type', '=', '前置三元定位检测')])
if workorder:
for item in workorder:
res['Datas'].append({
'XOffset': item.production_id.name,
'YOffset': item.RfidCode,
'ZOffet': item.name,
'COffset': 1
})
except Exception as e:
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
logging.info('get_qcCheck error:%s' % e)
return json.JSONEncoder().encode(res)
@http.route('/AutoDeviceApi/FeedBackStart', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
cors="*")
@@ -50,7 +123,7 @@ class Manufacturing_Connect(http.Controller):
:param kw:
:return:
"""
logging.info('get_Work_Info:%s' % kw)
logging.info('button_Work_START:%s' % kw)
try:
res = {'Succeed': True, 'Datas': []}
datas = request.httprequest.data
@@ -69,11 +142,9 @@ class Manufacturing_Connect(http.Controller):
workorder = request.env['mrp.workorder'].sudo().search(
[('production_id', '=', production_id), ('routing_type', '=', routing_type)], limit=1)
workorder.button_start()
except Exception as e:
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
logging.info('get_Work_Info error:%s' % e)
logging.info('button_Work_START error:%s' % e)
return json.JSONEncoder().encode(res)
@http.route('/AutoDeviceApi/FeedBackEnd', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
@@ -84,7 +155,7 @@ class Manufacturing_Connect(http.Controller):
:param kw:
:return:
"""
logging.info('get_Work_Info:%s' % kw)
logging.info('button_Work_End:%s' % kw)
try:
res = {'Succeed': True, 'Datas': []}
datas = request.httprequest.data
@@ -103,14 +174,11 @@ class Manufacturing_Connect(http.Controller):
workorder = request.env['mrp.workorder'].sudo().search(
[('production_id', '=', production_id), ('routing_type', '=', routing_type)], limit=1)
workorder.button_finish()
except Exception as e:
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
logging.info('get_Work_Info error:%s' % e)
logging.info('button_Work_End error:%s' % e)
return json.JSONEncoder().encode(res)
@http.route('/AutoDeviceApi/QcCheck', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
cors="*")
def Workorder_QcCheck(self, **kw):
@@ -119,7 +187,7 @@ class Manufacturing_Connect(http.Controller):
:param kw:
:return:
"""
logging.info('get_Work_Info:%s' % kw)
logging.info('Workorder_QcCheck:%s' % kw)
try:
res = {'Succeed': True, 'Datas': []}
datas = request.httprequest.data
@@ -143,8 +211,7 @@ class Manufacturing_Connect(http.Controller):
routing_type = ret['CraftId']
request.env['mrp.workorder'].sudo().search(
[('production_id', '=', production_id), ('routing_type', '=', routing_type)], limit=1)
except Exception as e:
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
logging.info('get_Work_Info error:%s' % e)
logging.info('Workorder_QcCheck error:%s' % e)
return json.JSONEncoder().encode(res)

View File

@@ -50,6 +50,9 @@ class MrpProduction(models.Model):
work_state = fields.Char('业务状态')
programming_state = fields.Char('编程状态')
glb_file = fields.Binary("glb模型文件")
production_line_id = fields.Many2one('sf.production.line', string='生产线')
plan_start_processing_time = fields.Datetime('计划开始加工时间')
@api.depends(
'move_raw_ids.state', 'move_raw_ids.quantity_done', 'move_finished_ids.state',

View File

@@ -122,15 +122,17 @@ class ResMrpWorkOrder(models.Model):
chuck_type_id = fields.Char(string="卡盘类型")
chuck_model_id = fields.Char(string="卡盘型号")
tray_serial_number = fields.Char(string="托盘序列号")
tray_name = fields.Char(string="托盘名称")
tray_product_id = fields.Many2one('product.product', string="托盘名称")
tray_brand_id = fields.Many2one('sf.machine.brand', string="托盘品牌")
tray_type_id = fields.Char(string="托盘类型")
tray_model_id = fields.Char(string="托盘型号")
tray_type_id = fields.Many2one('sf.fixture.material', string="托盘类型")
tray_model_id = fields.Many2one('sf.fixture.model', string="托盘型号")
total_wight = fields.Float(string="总重量")
maximum_carrying_weight = fields.Char(string="最大承载重量[kg]")
maximum_clamping_force = fields.Char(string="最大夹持力[n]")
production_line = fields.Char(string="生产线")
preset_program_information = fields.Char(string="预调程序信息")
workpiece_delivery_ids = fields.One2many('sf.workpiece.delivery', 'workorder_id', '工件配送')
is_delivery = fields.Boolean('是否配送完成', default=False)
@api.onchange('is_ok')
def _onchange_inspection_user_id(self):
@@ -195,9 +197,20 @@ class ResMrpWorkOrder(models.Model):
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]
workorder.button_finish()
except:
raise UserError("参数计算有误")
def button_workpiece_delivery(self):
if self.routing_type == '装夹预调':
for item in self.workpiece_delivery_ids:
if not item.feeder_station_start:
raise UserError('【工件配送】明细中请输入起点接驳站')
# if not item.workpiece_code:
# raise UserError('请对【同运工件】进行扫描')
else:
item.write({'task_delivery_time': fields.Datetime.now(), 'status': '待配送'})
# 拼接工单对象属性值
def json_workorder_str(self, k, production, route):
# 计算预计时长duration_expected
@@ -240,7 +253,9 @@ class ResMrpWorkOrder(models.Model):
'date_planned_finished': False,
'duration_expected': duration_expected,
'duration': 0,
'workpiece_delivery_ids': False if not route.routing_type == '装夹预调' else self.env[
'sf.workpiece.delivery'].create(
{'production_id': production.id})
}]
return workorders_values_str
@@ -551,6 +566,9 @@ class ResMrpWorkOrder(models.Model):
raise UserError(_('请先完成上一步工单'))
def button_finish(self):
if self.routing_type == '装夹预调':
if not self.material_center_point and self.X_deviation_angle > 0:
raise UserError("请对前置三元检测定位参数进行计算定位")
if self.picking_out_id:
picking_out = self.env['stock.picking'].search([('id', '=', self.picking_out_id.id)])
if picking_out.workorder_out_id:
@@ -585,10 +603,6 @@ class ResMrpWorkOrder(models.Model):
# self.production_id.state = 'done'
class CNCprocessing(models.Model):
_name = 'sf.cnc.processing'
_description = "CNC加工"
@@ -597,6 +611,7 @@ class CNCprocessing(models.Model):
cnc_id = fields.Many2one('ir.attachment')
sequence_number = fields.Char('序号')
program_name = fields.Char('程序名')
functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型')
cutting_tool_name = fields.Char('刀具名称')
cutting_tool_no = fields.Char('刀号')
processing_type = fields.Char('加工类型')
@@ -723,51 +738,107 @@ class SfWorkOrderBarcodes(models.Model):
_name = "mrp.workorder"
_inherit = ["mrp.workorder", "barcodes.barcode_events_mixin"]
# def on_barcode_scanned(self, barcode):
# workorder = self.env['mrp.workorder'].browse(self.ids)
# if "*" not in barcode:
# if self.routing_type == '装夹':
# tray_code = self.env['sf.tray'].search([('code', '=', barcode)])
# self.tray_code = tray_code.code
# self.tray_id = workorder.gettray_auto(barcode)
# elif self.routing_type == '前置三元定位检测':
# print('我是前置三元检测')
# logging.info('我是前置三元检测')
# elif self.routing_type == 'CNC加工':
# if barcode == 'UP-ALL':
# print("我是一键合并下发")
# logging.info('我是一键合并下发')
# self.up_merge_all()
# else:
# print('CNC加工')
# # print(barcode)
# # a = self.env['sf.tray'].search([('code', '=', barcode)])
# # print(a)
# # # workorder_obj = self.env['mrp.workorder'].search([('tray_code', '=', barcode)], limit=1)
# # workorder_obj = self.env['mrp.workorder'].search([('tray_code', '=', barcode)])
# # e = workorder_obj.id
# # print(workorder_obj)
# # action = {
# # 'name': '工单',
# # 'type': 'ir.actions.act_window',
# # # 'view_type': 'form',
# # 'view_mode': 'form',
# # 'res_model': 'mrp.workorder',
# # 'view_id': self.env.ref('mrp.mrp_production_workorder_form_view_inherit').id,
# # # 'res_id': workorder_obj.id,
# # 'res_id': 1023,
# # 'target': 'current',
# # # 'context': self.env.context,
# # # 'flags': {'initial_mode': 'edit'},
# # }
# # return action
#
# elif self.routing_type == '后置三元质量检测':
# print('后置三元检测')
# elif self.routing_type == '解除装夹':
# print("我是解除装夹")
# else:
# pass
#
# else:
# self.pro_code_ok = workorder.pro_code_is_ok(barcode)
def on_barcode_scanned(self, barcode):
workorder = self.env['mrp.workorder'].browse(self.ids)
# workorder = self.env['mrp.workorder'].search(
# [('routing_type', '=', '装夹预调'), ('production_id', '=', self.production_id.id)])
if workorder:
if workorder.routing_type == '装夹预调':
stock_move_line = self.env['stock.move.line'].search([('lot_name', '=', barcode)])
if stock_move_line.product_id.categ_type == '夹具':
workorder.write({
'tray_serial_number': stock_move_line.lot_name,
'tray_product_id': stock_move_line.product_id.id,
'tray_brand_id': stock_move_line.product_id.brand_id.id,
'tray_type_id': stock_move_line.product_id.fixture_material_id.id,
'tray_model_id': stock_move_line.product_id.fixture_model_id.id
})
workorder.button_start()
# return {
# 'type': 'ir.actions.act_window',
# 'res_model': 'mrp.workorder',
# 'view_mode': 'form',
# 'domain': [('id', 'in', workorder.id)],
# 'target': 'current'
# }
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('工件生产线不一致,请重新确认')
class WorkPieceDelivery(models.Model):
_name = "sf.workpiece.delivery"
_description = '工件配送'
workorder_id = fields.Many2one('mrp.workorder', string='工单', readonly=True)
production_id = fields.Many2one('mrp.production', string='制造订单', readonly=True)
production_line_id = fields.Many2one('sf.production.line', compute='_compute_production_line_id',
string='目的生产线', readonly=True,
store=True)
plan_start_processing_time = fields.Datetime('计划开始加工时间', readonly=True)
workpiece_code = fields.Char('同运工件编码')
feeder_station_start = fields.Char('起点接驳站')
feeder_station_destination = fields.Char('目的接驳站')
task_delivery_time = fields.Datetime('任务下发时间')
task_completion_time = fields.Datetime('任务完成时间')
delivery_duration = fields.Float('配送时长', compute='_compute_delivery_duration')
status = fields.Selection(
[('待下发', '待下发'), ('待配送', '待配送'), ('已配送', '已配送')], string='状态',
default='待下发')
# 工件配送
def button_delivery(self):
if self.status == '待下发':
return {
'name': _('确认'),
'type': 'ir.actions.act_window',
'view_mode': 'form',
'res_model': 'sf.workpiece.delivery.wizard',
'target': 'new',
'context': {
'default_delivery_id': self.id,
}}
else:
raise UserError('状态为【待下发】的工件记录可进行配送')
# 配送至avg小车
def _delivery_avg(self):
self.write({'task_delivery_time': fields.Datetime.now(), 'status': '待配送'})
@api.depends('production_id.production_line_id')
def _compute_production_line_id(self):
if self.production_id.production_line_id:
self.production_line_id = self.production_id.production_line_id.id
self.plan_start_processing_time = self.production_id.plan_start_processing_time
@api.depends('task_delivery_time', 'task_completion_time')
def _compute_delivery_duration(self):
for obj in self:
if obj.task_delivery_time and obj.task_completion_time:
obj.delivery_duration = round(
(obj.task_completion_time - obj.task_delivery_time).total_seconds() / 60.0, 2)
else:
obj.delivery_duration = 0.0

View File

@@ -870,6 +870,11 @@ class SfMaintenanceEquipmentTool(models.Model):
_description = '机床刀位'
equipment_id = fields.Many2one('maintenance.equipment', string='设备')
code = fields.Char('机床刀位号')
name = fields.Char('刀位号', compute='_compute_name')
# 待删除字段
product_template_id = fields.Many2one('product.template', string='功能刀具名称',
domain="[('categ_type', '=', '刀具')]")
image_1920 = fields.Binary('图片', related='product_template_id.image_1920')
@@ -882,9 +887,6 @@ class SfMaintenanceEquipmentTool(models.Model):
life_value_max = fields.Char('最大寿命值')
alarm_value = fields.Char('报警值')
used_value = fields.Char('已使用值')
code = fields.Char('机床刀位号')
name = fields.Char('', compute='_compute_name')
@api.depends('code')
def _compute_name(self):

View File

@@ -359,7 +359,6 @@ class ReStockMove(models.Model):
materiel_height = fields.Float(string='物料高度', digits=(16, 4))
def _get_new_picking_values_Res(self, item, sorted_workorders, rescode):
logging.info('new_picking-rescode: %s' % rescode)
return {
'name': self.env['stock.picking']._get_name_Res(rescode),
'origin': item.name,
@@ -373,165 +372,21 @@ class ReStockMove(models.Model):
'state': 'confirmed',
}
# 将采购到的夹具注册到Cloud
def _register_fixture(self):
create_url = '/api/factory_fixture_material/create'
config = self.env['res.config.settings'].get_values()
headers = Common.get_headers(self, config['token'], config['sf_secret_key'])
strurl = config['sf_url'] + create_url
for item in self:
val = {
'token': config['token'],
'name': item.product_id.name,
'brand_code': self.env['sf.machine.brand'].search([('id', '=', item.product_id.brand_id.id)]).code,
'fixture_material_code': self.env['sf.fixture.material'].search(
[('id', '=', item.product_id.fixture_material_id.id)]).code,
'fixture_materials_type_code': self.env['sf.materials.model'].search(
[('id', '=', item.product_id.materials_type_id.id)]).materials_no,
'fixture_clamping_way': item.product_id.fixture_clamping_way,
'fixture_port_type': item.product_id.fixture_port_type,
'fixture_length': item.product_id.tool_length,
'fixture_width': item.product_id.tool_width,
'fixture_height': item.product_id.tool_height,
'fixture_weight': item.product_id.tool_weight,
'fixture_amount': int(item.quantity_done),
'fixture_model_file': '' if not item.product_id.fixture_model_file else base64.b64encode(
item.product_id.fixture_model_file).decode(
'utf-8'),
'fixture_clamp_workpiece_length_max': item.product_id.fixture_clamp_workpiece_length_max,
'fixture_clamp_workpiece_width_max': item.product_id.fixture_clamp_workpiece_width_max,
'fixture_clamp_workpiece_height_max': item.product_id.fixture_clamp_workpiece_height_max,
'fixture_clamp_workpiece_diameter_max': item.product_id.fixture_clamp_workpiece_diameter_max,
'fixture_maximum_carrying_weight': item.product_id.fixture_maximum_carrying_weight,
'fixture_maximum_clamping_force': item.product_id.fixture_maximum_clamping_force,
'fixture_driving_way': '' if not item.product_id.fixture_driving_way
else item.product_id.fixture_driving_way,
'fixture_apply_machine_tool_type_codes': self.env[
'product.template']._json_apply_machine_tool_type_item_code(item),
'fixture_through_hole_size': item.product_id.fixture_through_hole_size,
'fixture_screw_size': item.product_id.fixture_screw_size,
}
try:
if item.product_id.industry_code:
val['industry_code'] = item.product_id.industry_code
ret = requests.post(strurl, json={}, data=val, headers=headers)
ret = ret.json()
if ret['status'] == 200:
if not item.product_id.industry_code:
item.product_id.write({'register_state': '已注册', 'industry_code': ret['industry_code']})
def print_serial_numbers(self):
if not self.next_serial:
raise UserError(_("请先分配序列号再进行打印"))
label_data = []
for item in self.move_line_ids:
label_data.append({
'item_id': item.id,
})
if label_data:
report_template = self.env.ref('stock.label_package_template')
res = report_template.report_action(label_data)
res['id'] = report_template.id
return res
else:
item.product_id.write({'register_state': '已注册'})
else:
item.product_id.write({'register_state': '注册失败'})
except Exception as e:
raise UserError("注册夹具到云端失败,请联系管理员!")
# 将采购到的刀具注册到Cloud
def _register_cutting_tool(self):
create_url = '/api/factory_cutting_tool_material/create'
config = self.env['res.config.settings'].get_values()
headers = Common.get_headers(self, config['token'], config['sf_secret_key'])
strurl = config['sf_url'] + create_url
for item in self:
val = {
'token': config['token'],
'name': item.product_id.name,
'brand_code': self.env['sf.machine.brand'].search([('id', '=', item.product_id.brand_id.id)]).code,
'cutting_tool_material_code': self.env['sf.cutting.tool.material'].search(
[('id', '=', item.product_id.cutting_tool_material_id.id)]).code,
'cutting_tool_type_code': self.env['sf.cutting.tool.type'].search(
[('id', '=', item.product_id.cutting_tool_type_id.id)]).code,
'material_model_code': self.env['sf.materials.model'].search(
[('id', '=', item.product_id.materials_type_id.id)]).materials_no,
'tool_length': item.product_id.tool_length,
'tool_width': item.product_id.tool_width,
'tool_height': item.product_id.tool_height,
'tool_thickness': item.product_id.tool_thickness,
'tool_weight': item.product_id.tool_weight,
'tool_hardness': item.product_id.tool_hardness,
'coating_material': item.product_id.coating_material,
'amount': int(item.quantity_done),
# 'model_file': '' if not item.product_id.fixture_model_file else base64.b64encode(
# item.product_id.fixture_model_file).decode(
# 'utf-8'),
'total_length': item.product_id.cutting_tool_total_length,
'shank_length': item.product_id.cutting_tool_shank_length,
'blade_length': item.product_id.cutting_tool_blade_length,
'neck_length': item.product_id.cutting_tool_neck_length,
'neck_diameter': item.product_id.cutting_tool_neck_diameter,
'shank_diameter': item.product_id.cutting_tool_shank_diameter,
'blade_tip_diameter': item.product_id.cutting_tool_blade_tip_diameter,
'blade_tip_taper': item.product_id.cutting_tool_blade_tip_taper,
'blade_helix_angle': item.product_id.cutting_tool_blade_helix_angle,
'blade_type': item.product_id.cutting_tool_blade_type,
'coarse_medium_fine': '' if item.product_id.cutting_tool_coarse_medium_fine is False
else item.product_id.cutting_tool_coarse_medium_fine,
'run_out_accuracy_max': item.product_id.cutting_tool_run_out_accuracy_max,
'run_out_accuracy_min': item.product_id.cutting_tool_run_out_accuracy_min,
'head_diameter': item.product_id.cutting_tool_head_diameter,
'diameter': item.product_id.cutting_tool_diameter,
'blade_number': '' if item.product_id.cutting_tool_blade_number is False
else item.product_id.cutting_tool_blade_number,
'front_angle': item.product_id.cutting_tool_front_angle,
'rear_angle': item.product_id.cutting_tool_rear_angle,
'main_included_angle': item.product_id.cutting_tool_main_included_angle,
'chuck_codes': self.env['product.template']._json_chuck_item_code(item),
'cutter_bar_codes': self.env['product.template']._json_cutter_bar_item_code(item),
'cutter_pad_codes': self.env['product.template']._json_cutter_pad_item_code(item),
'blade_codes': self.env['product.template']._json_blade_item_code(item),
'handle_codes': self.env['product.template']._json_handle_item_code(item),
'nut': item.product_id.cutting_tool_nut,
'top_angle': item.product_id.cutting_tool_top_angle,
'jump_accuracy': item.product_id.cutting_tool_jump_accuracy,
'working_hardness': item.product_id.cutting_tool_working_hardness,
'blade_diameter': item.product_id.cutting_tool_blade_diameter,
'wrench': item.product_id.cutting_tool_wrench,
'accuracy_level': item.product_id.cutting_tool_accuracy_level,
'clamping_way': item.product_id.cutting_tool_clamping_way,
'clamping_length': item.product_id.cutting_tool_clamping_length,
'clamping_tolerance': item.product_id.cutting_tool_clamping_tolerance,
'diameter_max': item.product_id.cutting_tool_diameter_max,
'clamping_diameter_min': item.product_id.cutting_tool_clamping_diameter_min,
'clamping_diameter_max': item.product_id.cutting_tool_clamping_diameter_max,
'detection_accuracy_max': item.product_id.cutting_tool_detection_accuracy_max,
'detection_accuracy_min': item.product_id.cutting_tool_detection_accuracy_min,
'is_rough_finish': item.product_id.cutting_tool_is_rough_finish,
'is_finish': item.product_id.cutting_tool_is_finish,
'is_drill_hole': item.product_id.cutting_tool_is_drill_hole,
'is_safety_lock': item.product_id.cutting_tool_is_safety_lock,
'is_high_speed_cutting': item.product_id.cutting_tool_is_high_speed_cutting,
'dynamic_balance_class': item.product_id.cutting_tool_dynamic_balance_class,
'change_time': item.product_id.cutting_tool_change_time,
'standard_speed': item.product_id.cutting_tool_standard_speed,
'speed_max': item.product_id.cutting_tool_speed_max,
'cooling_type': item.product_id.cutting_tool_cooling_type,
'body_accuracy': item.product_id.cutting_tool_body_accuracy,
'apply_lock_nut_model': item.product_id.apply_lock_nut_model,
'apply_lock_wrench_model': item.product_id.apply_lock_wrench_model,
'tool_taper': item.product_id.cutting_tool_taper,
'flange_length': item.product_id.cutting_tool_flange_length,
'flange_diameter': item.product_id.cutting_tool_flange_diameter,
'outer_diameter': item.product_id.cutting_tool_outer_diameter,
'inner_diameter': item.product_id.cutting_tool_inner_diameter,
'cooling_suit_type_ids': item.product_id.cooling_suit_type_ids,
'er_size_model': item.product_id.cutting_tool_er_size_model,
'image': '' if not item.product_id.image_1920 else
base64.b64encode(item.product_id.image_1920).decode('utf-8'),
}
try:
if item.product_id.industry_code:
val['industry_code'] = item.product_id.industry_code
ret = requests.post(strurl, json={}, data=val, headers=headers)
ret = ret.json()
if ret['status'] == 200:
if not item.product_id.industry_code:
item.product_id.write({'register_state': '已注册', 'industry_code': ret['industry_code']})
else:
item.product_id.write({'register_state': '已注册'})
else:
item.product_id.write({'register_state': '注册失败'})
except Exception as e:
raise UserError("注册刀具到云端失败,请联系管理员!")
raise UserError(_("没有可打印的标签数据"))
class ReStockQuant(models.Model):

View File

@@ -22,7 +22,10 @@ access_mrp_workcenter,mrp_workcenter,model_mrp_workcenter,sf_base.group_sf_mrp_u
access_mrp_workcenter_manager,mrp_workcenter,model_mrp_workcenter,sf_base.group_sf_mrp_manager,1,1,1,0
access_mrp_workcenter_productivity,mrp_workcenter_productivity,model_mrp_workcenter_productivity,sf_base.group_sf_mrp_user,1,0,0,0
access_mrp_workcenter_productivity_manager,mrp_workcenter_productivity,model_mrp_workcenter_productivity,sf_base.group_sf_mrp_manager,1,1,1,0
access_sf_workpiece_delivery_group_sf_order_user,sf_workpiece_delivery_group_sf_order_user,model_sf_workpiece_delivery,sf_base.group_sf_order_user,1,1,0,0
access_sf_workpiece_delivery_manager,sf_workpiece_delivery,model_sf_workpiece_delivery,sf_base.group_sf_mrp_manager,1,1,0,0
access_sf_workpiece_delivery_admin,sf_workpiece_delivery_admin,model_sf_workpiece_delivery,base.group_system,1,1,1,0
access_sf_workpiece_delivery_wizard_group_sf_order_user,sf_workpiece_delivery_wizard_group_sf_order_user,model_sf_workpiece_delivery_wizard,sf_base.group_sf_order_user,1,1,1,0
access_mrp_workcenter_productivity_loss_manager,mrp.workcenter.productivity.loss,mrp.model_mrp_workcenter_productivity_loss,sf_base.group_sf_mrp_user,1,1,1,0
access_mrp_workcenter_productivity_loss,mrp.workcenter.productivity.loss,mrp.model_mrp_workcenter_productivity_loss,sf_base.group_sf_mrp_user,1,0,0,0
access_mrp_workcenter_productivity_loss_type,mrp.workcenter.productivity.loss.type,mrp.model_mrp_workcenter_productivity_loss_type,sf_base.group_sf_mrp_user,1,0,0,0
@@ -87,6 +90,7 @@ access_mrp_production_split,access.mrp.production.split,mrp.model_mrp_production
access_mrp_production_split_line,access.mrp.production.split.line,mrp.model_mrp_production_split_line,sf_base.group_sf_mrp_user,1,1,1,0
access_mrp_workcenter_capacity_manager,mrp.workcenter.capacity.manager,mrp.model_mrp_workcenter_capacity,sf_base.group_sf_mrp_user,1,1,1,0
access_mrp_production_group_plan_dispatch,mrp_production,model_mrp_production,sf_base.group_plan_dispatch,1,0,0,0
access_mrp_workorder,mrp_workorder,model_mrp_workorder,sf_base.group_plan_dispatch,1,1,1,0
access_sf_production_line_group_plan_dispatch,sf.production.line,model_sf_production_line,sf_base.group_plan_dispatch,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
22 access_mrp_workcenter_manager mrp_workcenter model_mrp_workcenter sf_base.group_sf_mrp_manager 1 1 1 0
23 access_mrp_workcenter_productivity mrp_workcenter_productivity model_mrp_workcenter_productivity sf_base.group_sf_mrp_user 1 0 0 0
24 access_mrp_workcenter_productivity_manager mrp_workcenter_productivity model_mrp_workcenter_productivity sf_base.group_sf_mrp_manager 1 1 1 0
25 access_mrp_workcenter_productivity_loss_manager access_sf_workpiece_delivery_group_sf_order_user mrp.workcenter.productivity.loss sf_workpiece_delivery_group_sf_order_user mrp.model_mrp_workcenter_productivity_loss model_sf_workpiece_delivery sf_base.group_sf_mrp_user sf_base.group_sf_order_user 1 1 1 0 0
26 access_sf_workpiece_delivery_manager sf_workpiece_delivery model_sf_workpiece_delivery sf_base.group_sf_mrp_manager 1 1 0 0
27 access_sf_workpiece_delivery_admin sf_workpiece_delivery_admin model_sf_workpiece_delivery base.group_system 1 1 1 0
28 access_sf_workpiece_delivery_wizard_group_sf_order_user sf_workpiece_delivery_wizard_group_sf_order_user model_sf_workpiece_delivery_wizard sf_base.group_sf_order_user 1 1 1 0
29 access_mrp_workcenter_productivity_loss access_mrp_workcenter_productivity_loss_manager mrp.workcenter.productivity.loss mrp.model_mrp_workcenter_productivity_loss sf_base.group_sf_mrp_user 1 0 1 0 1 0
30 access_mrp_workcenter_productivity_loss_type access_mrp_workcenter_productivity_loss mrp.workcenter.productivity.loss.type mrp.workcenter.productivity.loss mrp.model_mrp_workcenter_productivity_loss_type mrp.model_mrp_workcenter_productivity_loss sf_base.group_sf_mrp_user 1 0 0 0
31 access_mrp_workcenter_productivity access_mrp_workcenter_productivity_loss_type mrp.workcenter.productivity mrp.workcenter.productivity.loss.type mrp.model_mrp_workcenter_productivity mrp.model_mrp_workcenter_productivity_loss_type sf_base.group_sf_mrp_user 1 1 0 1 0 0
90 access_mrp_workcenter_capacity_manager access_mrp_production_split_line mrp.workcenter.capacity.manager access.mrp.production.split.line mrp.model_mrp_workcenter_capacity mrp.model_mrp_production_split_line sf_base.group_sf_mrp_user 1 1 1 0
91 access_mrp_production_group_plan_dispatch access_mrp_workcenter_capacity_manager mrp_production mrp.workcenter.capacity.manager model_mrp_production mrp.model_mrp_workcenter_capacity sf_base.group_plan_dispatch sf_base.group_sf_mrp_user 1 0 1 0 1 0
92 access_mrp_workorder access_mrp_production_group_plan_dispatch mrp_workorder mrp_production model_mrp_workorder model_mrp_production sf_base.group_plan_dispatch 1 1 0 1 0 0
93 access_mrp_workorder mrp_workorder model_mrp_workorder sf_base.group_plan_dispatch 1 1 1 0
94 access_sf_production_line_group_plan_dispatch sf.production.line model_sf_production_line sf_base.group_plan_dispatch 1 0 0 0
95 access_sf_production_line_group_plan_director sf.production.line model_sf_production_line sf_base.group_plan_director 1 1 1 0
96 access_sf_production_line sf.production.line model_sf_production_line sf_maintenance.sf_group_equipment_user 1 1 1 0

View File

@@ -18,7 +18,8 @@
<field name="product_qty" sum="Total Qty" string="数量" readonly="1" optional="show"/>
</xpath>
<xpath expr="//field[@name='product_qty']" position="after">
<field name="product_uom_id" string="计量单位" options="{'no_open':True,'no_create':True}" groups="uom.group_uom" optional="show"/>
<field name="product_uom_id" string="计量单位" options="{'no_open':True,'no_create':True}"
groups="uom.group_uom" optional="show"/>
</xpath>
<xpath expr="//field[@name='date_planned_start']" position="replace">
<field name="date_planned_start" optional="show"/>
@@ -26,7 +27,8 @@
<!-- <field name="date_deadline" widget="remaining_days" attrs="{'invisible': [('state', 'in', ['done', 'cancel'])]}" optional="show"/> -->
</xpath>
<xpath expr="//field[@name='production_real_duration']" position="after">
<field name="reservation_state" optional="hide" decoration-danger="reservation_state == 'confirmed'" decoration-success="reservation_state == 'assigned'"/>
<field name="reservation_state" optional="hide" decoration-danger="reservation_state == 'confirmed'"
decoration-success="reservation_state == 'assigned'"/>
</xpath>
<!-- <xpath expr="//field[@name='state']" position="before"> -->
<!-- <field name="schedule_state" optional="show"/> -->
@@ -60,23 +62,33 @@
<field name="inherit_id" ref="mrp.mrp_production_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='state']" position="attributes">
<attribute name="statusbar_visible">draft,confirmed,progress,pending_processing,completed,done</attribute>
<attribute name="statusbar_visible">draft,confirmed,progress,pending_processing,completed,done
</attribute>
</xpath>
<xpath expr="//field[@name='user_id']" position="after">
<field name="programming_no"/>
<field name="programming_no" readonly="1"/>
<field name="work_state" invisible="1"/>
<field name="programming_state"/>
<field name="programming_state" readonly="1"/>
<field name="production_line_id" readonly="1"/>
<field name="plan_start_processing_time" readonly="1"/>
</xpath>
<xpath expr="//header//button[@name='action_cancel']" position="replace">
<button name="action_cancel" type="object" string="取消" data-hotkey="z"
attrs="{'invisible': ['|', '|', ('id', '=', False), ('state', 'in', ('done', 'cancel')), ('confirm_cancel', '=', True)]}" groups="sf_base.group_sf_mrp_user"/>
attrs="{'invisible': ['|', '|', ('id', '=', False), ('state', 'in', ('done', 'cancel')), ('confirm_cancel', '=', True)]}"
groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="(//header//button[@name='button_mark_done'])[1]" position="replace">
<button name="button_mark_done" attrs="{'invisible': ['|', '|', ('state', 'in', ('draft', 'cancel', 'done', 'to_close')), ('qty_producing', '=', 0), ('move_raw_ids', '!=', [])]}" string="验证" type="object" class="oe_highlight"
confirm="There are no components to consume. Are you still sure you want to continue?" data-hotkey="g" groups="sf_base.group_sf_mrp_user"/>
<button name="button_mark_done"
attrs="{'invisible': ['|', '|', ('state', 'in', ('draft', 'cancel', 'done', 'to_close')), ('qty_producing', '=', 0), ('move_raw_ids', '!=', [])]}"
string="验证" type="object" class="oe_highlight"
confirm="There are no components to consume. Are you still sure you want to continue?"
data-hotkey="g" groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="(//header//button[@name='button_mark_done'])[2]" position="replace">
<button name="button_mark_done" attrs="{'invisible': ['|', '|', ('state', 'in', ('draft', 'cancel', 'done', 'to_close')), ('qty_producing', '=', 0), ('move_raw_ids', '=', [])]}" string="Validate" type="object" class="oe_highlight" data-hotkey="g" groups="sf_base.group_sf_mrp_user"/>
<button name="button_mark_done"
attrs="{'invisible': ['|', '|', ('state', 'in', ('draft', 'cancel', 'done', 'to_close')), ('qty_producing', '=', 0), ('move_raw_ids', '=', [])]}"
string="验证" type="object" class="oe_highlight" data-hotkey="g"
groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="(//header//button[@name='button_mark_done'])[3]" position="replace">
<button name="button_mark_done" attrs="{'invisible': [
@@ -86,7 +98,8 @@
'|',
('state', 'not in', ('confirmed', 'progress')),
('qty_producing', '!=', 0),
('state', '!=', 'to_close')]}" string="Mark as Done" type="object" class="oe_highlight" data-hotkey="g" groups="sf_base.group_sf_mrp_user"/>
('state', '!=', 'to_close')]}" string="标记完成" type="object" class="oe_highlight"
data-hotkey="g" groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="(//header//button[@name='button_mark_done'])[4]" position="replace">
<button name="button_mark_done" attrs="{'invisible': [
@@ -96,57 +109,131 @@
'|',
('state', 'not in', ('confirmed', 'progress')),
('qty_producing', '!=', 0),
('state', '!=', 'to_close')]}" string="Mark as Done" type="object" class="oe_highlight" data-hotkey="g"
confirm="There are no components to consume. Are you still sure you want to continue?" groups="sf_base.group_sf_mrp_user"/>
('state', '!=', 'to_close')]}" string="标记完成" type="object" class="oe_highlight"
data-hotkey="g"
confirm="There are no components to consume. Are you still sure you want to continue?"
groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//header//button[@name='button_unplan']" position="replace">
<button name="button_unplan" type="object" string="取消安排" attrs="{'invisible': ['|', ('is_planned', '=', False), ('state', '=', 'cancel')]}" data-hotkey="x" groups="sf_base.group_sf_mrp_user"/>
<button name="button_unplan" type="object" string="取消安排"
attrs="{'invisible': ['|', ('is_planned', '=', False), ('state', '=', 'cancel')]}"
data-hotkey="x" groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//header//button[@name='button_scrap']" position="replace">
<button name="button_scrap" type="object" string="报废" attrs="{'invisible': [('state', 'in', ('cancel', 'draft'))]}" data-hotkey="y" groups="sf_base.group_sf_mrp_user"/>
<button name="button_scrap" type="object" string="报废"
attrs="{'invisible': [('state', 'in', ('cancel', 'draft'))]}" data-hotkey="y"
groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//header//button[@name='action_confirm']" position="replace">
<button name="action_confirm" attrs="{'invisible': [('state', '!=', 'draft')]}" string="Confirm" type="object" class="oe_highlight" data-hotkey="v" groups="sf_base.group_sf_mrp_user"/>
<button name="action_confirm" attrs="{'invisible': [('state', '!=', 'draft')]}" string="确认"
type="object" class="oe_highlight" data-hotkey="v" groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//header//button[@name='button_plan']" position="replace">
<button name="button_plan" attrs="{'invisible': ['|', '|', ('state', 'not in', ('confirmed', 'progress', 'to_close')), ('workorder_ids', '=', []), ('is_planned', '=', True)]}" type="object" string="Plan" class="oe_highlight" data-hotkey="x" groups="sf_base.group_sf_mrp_user"/>
<button name="button_plan"
attrs="{'invisible': ['|', '|', ('state', 'not in', ('confirmed', 'progress', 'to_close')), ('workorder_ids', '=', []), ('is_planned', '=', True)]}"
type="object" string="Plan" class="oe_highlight" data-hotkey="x"
groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//header//button[@name='action_assign']" position="replace">
<button name="action_assign" attrs="{'invisible': ['|', ('state', 'in', ('draft', 'done', 'cancel')), ('reserve_visible', '=', False)]}" string="Check availability" type="object" data-hotkey="q" groups="sf_base.group_sf_mrp_user"/>
<button name="action_assign"
attrs="{'invisible': ['|', ('state', 'in', ('draft', 'done', 'cancel')), ('reserve_visible', '=', False)]}"
string="Check availability" type="object" data-hotkey="q"
groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//header//button[@name='do_unreserve']" position="replace">
<button name="do_unreserve" type="object" string="Unreserve" attrs="{'invisible': [('unreserve_visible', '=', False)]}" data-hotkey="w" groups="sf_base.group_sf_mrp_user"/>
<button name="do_unreserve" type="object" string="Unreserve"
attrs="{'invisible': [('unreserve_visible', '=', False)]}" data-hotkey="w"
groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//header//button[@name='action_toggle_is_locked']" position="replace">
<button name="action_toggle_is_locked" attrs="{'invisible': ['|', ('show_lock', '=', False), ('is_locked', '=', False)]}" string="Unlock" groups="sf_base.group_sf_mrp_user" type="object" help="Unlock the manufacturing order to adjust what has been consumed or produced." data-hotkey="l"/>
<button name="action_toggle_is_locked"
attrs="{'invisible': ['|', ('show_lock', '=', False), ('is_locked', '=', False)]}"
string="Unlock" groups="sf_base.group_sf_mrp_user" type="object"
help="Unlock the manufacturing order to adjust what has been consumed or produced."
data-hotkey="l"/>
</xpath>
<xpath expr="//header//button[@name='action_toggle_is_locked']" position="replace">
<button name="action_toggle_is_locked" attrs="{'invisible': ['|', ('show_lock', '=', False), ('is_locked', '=', True)]}" string="Lock" groups="sf_base.group_sf_mrp_user" type="object" help="Lock the manufacturing order to prevent changes to what has been consumed or produced." data-hotkey="l"/>
<button name="action_toggle_is_locked"
attrs="{'invisible': ['|', ('show_lock', '=', False), ('is_locked', '=', True)]}"
string="Lock" groups="sf_base.group_sf_mrp_user" type="object"
help="Lock the manufacturing order to prevent changes to what has been consumed or produced."
data-hotkey="l"/>
</xpath>
<xpath expr="//header//button[@name='action_serial_mass_produce_wizard']" position="replace">
<button name="action_serial_mass_produce_wizard" attrs="{'invisible': [('show_serial_mass_produce', '=', False)]}" string="Mass Produce" type="object" groups="sf_base.group_sf_mrp_user"/>
<button name="action_serial_mass_produce_wizard"
attrs="{'invisible': [('show_serial_mass_produce', '=', False)]}" string="Mass Produce"
type="object" groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//header//button[@name='action_cancel']" position="replace">
<button name="action_cancel" type="object" string="Cancel" data-hotkey="z"
attrs="{'invisible': ['|', '|', ('id', '=', False), ('state', 'in', ('done', 'cancel')), ('confirm_cancel', '=', False)]}"
confirm="Some product moves have already been confirmed, this manufacturing order can't be completely cancelled. Are you still sure you want to process ?" groups="sf_base.group_sf_mrp_user"/>
confirm="Some product moves have already been confirmed, this manufacturing order can't be completely cancelled. Are you still sure you want to process ?"
groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//header//button[@name='button_unbuild']" position="replace">
<button name="button_unbuild" type="object" string="Unbuild" attrs="{'invisible': [('state', '!=', 'done')]}" data-hotkey="shift+v" groups="sf_base.group_sf_mrp_user"/>
<button name="button_unbuild" type="object" string="拆单"
attrs="{'invisible': [('state', '!=', 'done')]}" data-hotkey="shift+v"
groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//header//button[@name='button_plan']" position="replace">
<!-- <button name="button_plan" attrs="{'invisible': ['|', '|', ('state', 'not in', ('confirmed', 'progress', 'to_close')), ('workorder_ids', '=', []), ('is_planned', '=', True)]}" type="object" string="Plan" class="oe_highlight" data-hotkey="x" groups="sf_base.group_sf_mrp_user"/> -->
</xpath>
<xpath expr="//header//button[@name='action_assign']" position="replace">
<button name="action_assign"
attrs="{'invisible': ['|', ('state', 'in', ('draft', 'done', 'cancel')), ('reserve_visible', '=', False)]}"
string="检查可用量" type="object" data-hotkey="q" groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//header//button[@name='do_unreserve']" position="replace">
<button name="do_unreserve" type="object" string="取消保留"
attrs="{'invisible': [('unreserve_visible', '=', False)]}" data-hotkey="w"
groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//header//button[@name='action_toggle_is_locked']" position="replace">
<button name="action_toggle_is_locked"
attrs="{'invisible': ['|', ('show_lock', '=', False), ('is_locked', '=', False)]}"
string="取消阻塞" groups="sf_base.group_sf_mrp_user" type="object"
help="Unlock the manufacturing order to adjust what has been consumed or produced."
data-hotkey="l"/>
</xpath>
<xpath expr="//header//button[@name='action_toggle_is_locked']" position="replace">
<button name="action_toggle_is_locked"
attrs="{'invisible': ['|', ('show_lock', '=', False), ('is_locked', '=', True)]}"
string="阻塞" groups="sf_base.group_sf_mrp_user" type="object"
help="Lock the manufacturing order to prevent changes to what has been consumed or produced."
data-hotkey="l"/>
</xpath>
<xpath expr="//header//button[@name='action_serial_mass_produce_wizard']" position="replace">
<button name="action_serial_mass_produce_wizard"
attrs="{'invisible': [('show_serial_mass_produce', '=', False)]}" string="批量生产"
type="object" groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//header//button[@name='action_cancel']" position="replace">
<button name="action_cancel" type="object" string="取消" data-hotkey="z"
attrs="{'invisible': ['|', '|', ('id', '=', False), ('state', 'in', ('done', 'cancel')), ('confirm_cancel', '=', False)]}"
confirm="Some product moves have already been confirmed, this manufacturing order can't be completely cancelled. Are you still sure you want to process ?"
groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//header//button[@name='button_unbuild']" position="replace">
<button name="button_unbuild" type="object" string="拆单"
attrs="{'invisible': [('state', '!=', 'done')]}" data-hotkey="shift+v"
groups="sf_base.group_sf_mrp_user"/>
</xpath>
</field>
</record>
@@ -157,31 +244,68 @@
<field name="inherit_id" ref="mrp.mrp_production_workorder_tree_editable_view"/>
<field name="arch" type="xml">
<xpath expr="//tree//button[@name='button_start']" position="replace">
<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)]}" groups="sf_base.group_sf_mrp_user"/>
<button name="button_start" type="object" string="开始" class="btn-success"
attrs="{'invisible': ['|', '|', '|', ('production_state','in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('state', 'in', ('done', 'cancel')), ('is_user_working', '!=', False)]}"
groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//tree//button[@name='button_pending']" position="replace">
<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)]}" groups="sf_base.group_sf_mrp_user"/>
attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('is_user_working', '=', False)]}"
groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//tree//button[@name='button_finish']" position="replace">
<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)]}" groups="sf_base.group_sf_mrp_user"/>
attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('is_user_working', '=', False)]}"
groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//tree//button[@name='%(mrp.act_mrp_block_workcenter_wo)d']" position="replace">
<button name="%(mrp.act_mrp_block_workcenter_wo)d" type="action" string="Block" context="{'default_workcenter_id': workcenter_id}" class="btn-danger"
attrs="{'invisible': ['|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked')]}" groups="sf_base.group_sf_mrp_user"/>
<button name="%(mrp.act_mrp_block_workcenter_wo)d" type="action" string="Block"
context="{'default_workcenter_id': workcenter_id}" class="btn-danger"
attrs="{'invisible': ['|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked')]}"
groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//tree//button[@name='button_unblock']" position="replace">
<button name="button_unblock" type="object" string="Unblock" context="{'default_workcenter_id': workcenter_id}" class="btn-danger"
attrs="{'invisible': ['|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '!=', 'blocked')]}" groups="sf_base.group_sf_mrp_user"/>
<button name="button_unblock" type="object" string="Unblock"
context="{'default_workcenter_id': workcenter_id}" class="btn-danger"
attrs="{'invisible': ['|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '!=', 'blocked')]}"
groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//tree//button[@name='action_open_wizard']" position="replace">
<button name="action_open_wizard" type="object" icon="fa-external-link" class="oe_edit_only"
title="Open Work Order"
context="{'default_workcenter_id': workcenter_id}" groups="sf_base.group_sf_mrp_user"/>
=======
<button name="button_start" type="object" string="开始" class="btn-success"
attrs="{'invisible': ['|', '|', '|', ('production_state','in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('state', 'in', ('done', 'cancel')), ('is_user_working', '!=', False)]}"
groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//tree//button[@name='button_pending']" position="replace">
<button name="button_pending" type="object" string="暂停" class="btn-warning"
attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('is_user_working', '=', False)]}"
groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//tree//button[@name='button_finish']" position="replace">
<button name="button_finish" type="object" string="完成" class="btn-success"
attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('is_user_working', '=', False)]}"
groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//tree//button[@name='%(mrp.act_mrp_block_workcenter_wo)d']" position="replace">
<button name="%(mrp.act_mrp_block_workcenter_wo)d" type="action" string="阻塞"
context="{'default_workcenter_id': workcenter_id}" class="btn-danger"
attrs="{'invisible': ['|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked')]}"
groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//tree//button[@name='button_unblock']" position="replace">
<button name="button_unblock" type="object" string="取消阻塞"
context="{'default_workcenter_id': workcenter_id}" class="btn-danger"
attrs="{'invisible': ['|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '!=', 'blocked')]}"
groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="//tree//button[@name='action_open_wizard']" position="replace">
<button name="action_open_wizard" type="object" icon="fa-external-link" class="oe_edit_only"
title="未完成工单"
context="{'default_workcenter_id': workcenter_id}" groups="sf_base.group_sf_mrp_user"/>
</xpath>
</field>
</record>
@@ -205,8 +329,6 @@
</record>
<!-- <record id="custom_mrp_production_form_view" model="ir.ui.view"> -->
<!-- <field name="name">custom.mrp.production.form</field> -->
<!-- <field name="model">mrp.production</field> -->
@@ -272,12 +394,14 @@
<field name="product_variant_count"/>
<field name="currency_id"/>
<field name="activity_state"/>
<progressbar field="activity_state" colors='{"planned": "success", "today": "warning", "overdue": "danger"}'/>
<progressbar field="activity_state"
colors='{"planned": "success", "today": "warning", "overdue": "danger"}'/>
<templates>
<t t-name="kanban-box">
<div class="oe_kanban_card oe_kanban_global_click">
<div class="o_kanban_image me-1">
<img t-att-src="kanban_image('product.template', 'image_128', record.id.raw_value)" alt="Product" class="o_image_64_contain"/>
<img t-att-src="kanban_image('product.template', 'image_128', record.id.raw_value)"
alt="Product" class="o_image_64_contain"/>
</div>
<div class="oe_kanban_details">
<div class="o_kanban_record_top mb-0">
@@ -290,16 +414,22 @@
</div>
<div name="product_specification_id" class="mt-1">
规格: <field name="specification_id"></field>
规格:
<field name="specification_id"></field>
</div>
<t t-if="record.default_code.value">[<field name="default_code"/>]</t>
<div t-if="record.product_variant_count.value &gt; 1" groups="product.group_product_variant">
<t t-if="record.default_code.value">[<field name="default_code"/>]
</t>
<div t-if="record.product_variant_count.value &gt; 1"
groups="product.group_product_variant">
<strong>
<t t-esc="record.product_variant_count.value"/> Variants
<t t-esc="record.product_variant_count.value"/>
Variants
</strong>
</div>
<div name="product_lst_price" class="mt-1">
价格: <field name="list_price" widget="monetary" options="{'currency_field': 'currency_id', 'field_digits': True}"></field>
价格:
<field name="list_price" widget="monetary"
options="{'currency_field': 'currency_id', 'field_digits': True}"></field>
</div>
</div>
</div>

View File

@@ -104,20 +104,29 @@
<field name='user_permissions' invisible="1"/>
<field name='name' invisible="1"/>
<field name='routing_type' invisible="1"/>
<field name='is_delivery' invisible="1"/>
<button name="button_start" type="object" string="开始" class="btn-success"
attrs="{'invisible': ['|', '|', '|','|','|', ('production_state','in', ('draft', 'done',
attrs="{'invisible': ['|', '|', '|','|',('production_state','in', ('draft', 'done',
'cancel')), ('working_state', '=', 'blocked'), ('state', 'in', ('done', 'cancel')),
('is_user_working', '!=', False),('user_permissions','=',False),('name','=','获取CNC加工程序')]}"/>
('is_user_working', '!=', False),('user_permissions','=',False)]}"
groups="sf_base.group_sf_mrp_user"/>
<button name="button_pending" type="object" string="暂停" class="btn-warning"
attrs="{'invisible': ['|', '|','|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('is_user_working', '=', False),('name','=','获取CNC加工程序')]}"/>
groups="sf_base.group_sf_mrp_user"
attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('is_user_working', '=', False)]}"/>
<button name="button_finish" type="object" string="完成" class="btn-success"
groups="sf_base.group_sf_mrp_user"
attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'), ('is_user_working', '=', False)]}"/>
<button name="%(mrp.act_mrp_block_workcenter_wo)d" type="action" string="停工"
context="{'default_workcenter_id': workcenter_id}" class="btn-danger"
attrs="{'invisible': ['|', '|','|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'),('user_permissions','=',False),('name','=','获取CNC加工程序')]}"/>
groups="sf_base.group_sf_mrp_user"
attrs="{'invisible': ['|', '|','|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '=', 'blocked'),('user_permissions','=',False),('state','=','done')]}"/>
<button name="button_unblock" type="object" string="Unblock"
context="{'default_workcenter_id': workcenter_id}" class="btn-danger"
attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '!=', 'blocked'),('name','=','获取CNC加工程序')]}"/>
groups="sf_base.group_sf_mrp_user"
attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '!=', 'blocked'),('state','=','done')]}"/>
<button name="button_workpiece_delivery" type="object" string="工件配送" class="btn-primary"
attrs="{'invisible': ['|',('routing_type','!=','装夹预调'),('is_delivery','=',True)]}"/>
</xpath>
<xpath expr="//page[1]" position="before">
<page string="开料要求" attrs='{"invisible": [("routing_type","!=","切割")]}'>
@@ -229,11 +238,12 @@
<field name="chuck_model_id"/>
</group>
<group string="托盘">
<field name="tray_serial_number"/>
<field name="tray_name"/>
<field name="tray_brand_id"/>
<field name="tray_type_id"/>
<field name="tray_model_id"/>
<field name="_barcode_scanned" widget="barcode_handler"/>
<field name="tray_serial_number" readonly="1" string="序列号"/>
<field name="tray_product_id" readonly="1" string="名称"/>
<field name="tray_brand_id" readonly="1" string="品牌"/>
<field name="tray_type_id" readonly="1" string="类型"/>
<field name="tray_model_id" readonly="1" string="型号"/>
</group>
</group>
<group string="预调程序信息">
@@ -390,15 +400,27 @@
</div>
<group>
<field name="material_center_point"/>
<field name='X_deviation_angle'/>
<field name="material_center_point" readonly="1"/>
<field name='X_deviation_angle' readonly="1"/>
</group>
</page>
<page string="工件配送" attrs='{"invisible": [("routing_type","!=","装夹预调")]}'>
<field name="workpiece_delivery_ids">
<tree editable="bottom">
<field name="production_id" invisible="1"/>
<field name="workpiece_code"/>
<field name="feeder_station_start" force_save="1"/>
<field name="feeder_station_destination"/>
<field name="production_line_id"/>
<field name="task_delivery_time" readonly="1"/>
<field name="task_completion_time" readonly="1"/>
</tree>
</field>
</page>
</xpath>
<xpath expr="//page[1]" position="before">
<field name="results" invisible="1"/>
<page string="后置三元检测" attrs='{"invisible": [("routing_type","!=","CNC加工")]}'>
@@ -488,5 +510,59 @@
<record id="mrp.menu_mrp_workorder_todo" model="ir.ui.menu">
<field name="active" eval="False"/>
</record>
<!--=========================================工件配送单列表======================================-->
<record id="sf_workpiece_delivery_tree" model="ir.ui.view">
<field name="name">工件配送</field>
<field name="model">sf.workpiece.delivery</field>
<field name="arch" type="xml">
<tree string="工件配送">
<header>
<button name="button_delivery" type="object" string="配送"/>
</header>
<field name="status" widget="badge"
decoration-success="status == '已配送'"
decoration-warning="status == '待下发'"
decoration-danger="status == '待配送'"/>
<field name="production_id" string="工件编码"/>
<field name="workpiece_code"/>
<field name="production_line_id"/>
<field name="feeder_station_start"/>
<field name="feeder_station_destination"/>
<field name="task_delivery_time"/>
<field name="task_completion_time"/>
<field name="delivery_duration" widget="float_time"/>
</tree>
</field>
</record>
<record id="sf_workpiece_delivery_search" model="ir.ui.view">
<field name="name">工件配送</field>
<field name="model">sf.workpiece.delivery</field>
<field name="arch" type="xml">
<search string="工件配送">
<field name="production_id"/>
<field name="workpiece_code"/>
<field name="feeder_station_start"/>
<field name="production_line_id"/>
<field name="task_delivery_time"/>
<field name="feeder_station_destination"/>
<field name="task_completion_time"/>
<field name="delivery_duration"/>
<field name="status"/>
<searchpanel>
<field name="production_line_id" icon="fa-building" enable_counters="1"/>
<field name="status" icon="fa-building" enable_counters="1"/>
</searchpanel>
</search>
</field>
</record>
<record id="sf_workpiece_delivery_act" model="ir.actions.act_window">
<field name="name">工件配送</field>
<field name="res_model">sf.workpiece.delivery</field>
<field name="view_mode">tree,search</field>
</record>
</odoo>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- 设备增加刀具库位table-->
设备增加刀具库位table
<record id="sf_manufacturing_hr_equipment_view_form" model="ir.ui.view">
<field name="name">sf_manufacturing_equipment.form</field>
<field name="model">maintenance.equipment</field>
@@ -13,17 +13,6 @@
<field name = 'product_template_ids' >
<tree editable='bottom'>
<field name="code"/>
<field name="product_template_id"/>
<field name="image_1920" widget="image"/>
<field name="categ_type"/>
<field name="diameter"/>
<field name="precision"/>
<field name="tool_code"/>
<field name="hilt_name"/>
<field name="hilt_code"/>
<field name="life_value_max"/>
<field name="alarm_value"/>
<field name="used_value"/>
</tree>
</field>
</page>

View File

@@ -1,6 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<data>
<record id="view_stock_move_operations_inherit_sf" model="ir.ui.view">
<field name="name">stock.move.operations.form.inherit.sf</field>
<field name="model">stock.move</field>
<field name="inherit_id" ref="stock.view_stock_move_operations"/>
<field name="arch" type="xml">
<xpath expr="//button[@name='action_assign_serial_show_details']" position="after">
<button name="print_serial_numbers" string="序列号打印" type="object"/>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="view_picking_form_inherit_sf">
<field name="name">stock.picking.form.inherit.sf</field>
<field name="model">stock.picking</field>

View File

@@ -0,0 +1 @@
from . import workpiece_delivery_wizard

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record model="ir.ui.view" id="workpiece_delivery_wizard_form_view">
<field name="name">sf.workpiece.delivery.wizard.form.view</field>
<field name="model">sf.workpiece.delivery.wizard</field>
<field name="arch" type="xml">
<form>
<field name="delivery_id" invisible="True"/>
<div>
是否确定配送?
</div>
<footer>
<button string="确认" name="confirm" type="object" class="oe_highlight"/>
<button string="取消" class="btn btn-secondary" special="cancel"/>
</footer>
</form>
</field>
</record>
<record id="action_workpiece_delivery_wizard" model="ir.actions.act_window">
<field name="name">工件配送向导</field>
<field name="res_model">sf.workpiece.delivery.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</odoo>

View File

@@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# Part of YiZuo. See LICENSE file for full copyright and licensing details.
from odoo.exceptions import UserError, ValidationError
from datetime import datetime
from odoo import models, api, fields
class WorkpieceDeliveryWizard(models.TransientModel):
_name = 'sf.workpiece.delivery.wizard'
_description = '工件配送'
delivery_id = fields.Many2one('sf.workpiece.delivery', string='配送')
def confirm(self):
self.delivery_id._delivery_avg()

View File

@@ -14,6 +14,7 @@ class ResConfigSettings(models.TransientModel):
sf_secret_key = fields.Char(string='密钥', default='wBmxej38OkErKhD6')
sf_url = fields.Char(string='访问地址', default='https://sf.cs.jikimo.com')
bfm_url = fields.Char(string='业务平台后端访问地址', default='https://bfm.jikimo.com')
agv_url = fields.Char(string='avg访问地址', default='http://IP:PORT/rcms/services/rest')
ftp_host = fields.Char(string='FTP的ip')
ftp_port = fields.Char(string='FTP端口')
ftp_user = fields.Char(string='FTP用户')
@@ -33,8 +34,8 @@ class ResConfigSettings(models.TransientModel):
_logger.info("同步资源库表面工艺类别完成")
self.env['sf.production.process'].sync_all_production_process()
_logger.info("同步资源库表面工艺完成")
# self.env['sf.processing.technology'].sync_all_processing_technology()
# _logger.info("同步资源库加工工艺")
self.env['sf.processing.technology'].sync_all_processing_technology()
_logger.info("同步资源库加工工艺")
self.env['sf.machine.brand.tags'].sync_all_machine_brand_tags()
_logger.info("同步资源库品牌类别完成")
self.env['sf.machine.brand'].sync_all_machine_brand()
@@ -44,23 +45,23 @@ class ResConfigSettings(models.TransientModel):
self.env['sf.machine_tool.category'].sync_all_machine_tool_category()
_logger.info("同步资源库机床类型完成")
self.env['sf.production.process.parameter'].sync_all_production_process_parameter()
_logger.info("同步刀具物料完成")
_logger.info("同步材料型号可选参数完成")
self.env['sf.cutting.tool.material'].sync_all_cutting_tool_material()
_logger.info("同步刀具类型完成")
_logger.info("同步刀具物料完成")
self.env['sf.cutting.tool.type'].sync_all_tool_type()
_logger.info("同步功能刀具类型完成")
_logger.info("同步刀具类型完成")
self.env['sf.functional.cutting.tool.model'].sync_all_functional_cutting_tool_model()
_logger.info("同步夹具物料完成")
_logger.info("同步功能刀具类型完成")
self.env['sf.fixture.material'].sync_all_fixture_material()
_logger.info("同步联装类型完成")
_logger.info("同步夹具物料完成")
self.env['sf.multi_mounting.type'].sync_all_multi_mounting_type()
_logger.info("同步夹具型号完成")
_logger.info("同步联装类型完成")
self.env['sf.fixture.model'].sync_all_fixture_model()
_logger.info("同步夹具型号类型完成")
_logger.info("同步夹具型号完成")
self.env['sf.functional.fixture.type'].sync_all_functional_fixture_type()
_logger.info("同步功能夹具类型完成")
_logger.info("同步夹具型号类型完成")
self.env['sf.machine_tool.type'].sync_all_machine_tool_type()
_logger.info("同步资源库机床型号完成")
_logger.info("同步功能夹具类型完成")
self.env['maintenance.equipment.image'].sync_all_maintenance_equipment_image()
_logger.info("同步能力特征库完成")
self.env['sf.cutting_tool.standard.library'].sync_all_cutting_tool_standard_library()

View File

@@ -92,7 +92,8 @@ class sfProductionMaterials(models.Model):
if result['status'] == 1:
for item in result['production_materials_yesterday_list']:
if item:
materials = self.search([("materials_no", '=', item['materials_no'])])
materials = self.search(
[("materials_no", '=', item['materials_no'], ('active', 'in', [True, False]))])
if materials:
materials.name = item['name']
materials.remark = item['remark']
@@ -118,7 +119,8 @@ class sfProductionMaterials(models.Model):
if result['status'] == 1:
for item in result['production_materials_all_list']:
if item:
materials = self.search([("materials_no", '=', item['materials_no'])])
materials = self.search(
[("materials_no", '=', item['materials_no']), ('active', 'in', [True, False])])
if not materials:
self.create({
"name": item['name'],
@@ -150,7 +152,8 @@ class sfMaterialModel(models.Model):
if result['status'] == 1:
for item in result['materials_model_yesterday_list']:
if item:
materials_model = self.search([("materials_no", '=', item['materials_no'])])
materials_model = self.search(
[("materials_no", '=', item['materials_no']), ('active', 'in', [True, False])])
materials = self.env['sf.production.materials'].search(
[("materials_no", '=', item['materials_id.materials_no'])])
if materials_model:
@@ -196,7 +199,8 @@ class sfMaterialModel(models.Model):
if result['status'] == 1:
for item in result['materials_model_all_list']:
if item:
materials_model = self.search([("materials_no", '=', item['materials_no'])])
materials_model = self.search(
[("materials_no", '=', item['materials_no']), ('active', 'in', [True, False])])
materials = self.env['sf.production.materials'].search(
[("materials_no", '=', item['materials_id.materials_no'])])
if not materials_model:
@@ -256,7 +260,8 @@ class sfProductionProcessCategory(models.Model):
if result['status'] == 1:
for item in result['production_process_category_yesterday_list']:
if item:
production_process_category = self.search([("code", '=', item['code'])])
production_process_category = self.search(
[("code", '=', item['code']), ('active', 'in', [True, False])])
if production_process_category:
production_process_category.name = item['name']
production_process_category.code = item['code']
@@ -281,7 +286,7 @@ class sfProductionProcessCategory(models.Model):
if result['status'] == 1:
for item in result['production_process_category_all_list']:
if item:
category = self.search([("code", '=', item['code'])])
category = self.search([("code", '=', item['code']), ('active', 'in', [True, False])])
if not category:
self.create({
"name": item['name'],
@@ -311,17 +316,7 @@ class sfProductionProcess(models.Model):
if result['status'] == 1:
for item in result['production_process_yesterday_list']:
if item:
brand = self.env['sf.production.process'].search(
[("code", '=', item['code'])])
if brand:
brand.name = item['name'],
brand.category_id = self.env['sf.production.process.category'].search(
[("code", '=', item['category_code'])]).id,
brand.code = item['code'],
brand.remark = item['remark'],
brand.active = item['active'],
brand.remark = item['remark']
production_process = self.search([("code", '=', item['code'])])
production_process = self.search([("code", '=', item['code']), ('active', 'in', [True, False])])
category = self.env['sf.production.process.category'].search(
[("code", '=', item['category_code'])])
if production_process:
@@ -332,8 +327,7 @@ class sfProductionProcess(models.Model):
else:
self.create({
"name": item['name'],
"category_id": self.env['sf.production.process.category'].search(
[("code", '=', item['category_code'])]).id,
"category_id": category.id,
"code": item['code'],
"remark": item['remark'],
"active": item['active'],
@@ -352,7 +346,7 @@ class sfProductionProcess(models.Model):
if result['status'] == 1:
for item in result['production_process_all_list']:
if item:
production_process = self.search([("code", '=', item['code'])])
production_process = self.search([("code", '=', item['code']), ('active', 'in', [True, False])])
category = self.env['sf.production.process.category'].search(
[("code", '=', item['category_code'])])
if not production_process:
@@ -388,7 +382,7 @@ class sfProcessingTechnology(models.Model):
if result['status'] == 1:
for item in result['processing_technology_yesterday_list']:
if item:
processing_technology = self.search([("code", '=', item['code'])])
processing_technology = self.search([("code", '=', item['process_encode']), ('active', 'in', [True, False])])
if processing_technology:
processing_technology.name = item['name']
processing_technology.remark = item['remark']
@@ -396,7 +390,7 @@ class sfProcessingTechnology(models.Model):
else:
self.create({
"name": item['name'],
"code": item['code'],
"code": item['process_encode'],
"remark": item['remark'],
"active": item['active'],
})
@@ -414,11 +408,11 @@ class sfProcessingTechnology(models.Model):
if result['status'] == 1:
for item in result['processing_technology_all_list']:
if item:
processing_technology = self.search([("code", '=', item['code'])])
processing_technology = self.search([("code", '=', item['process_encode']), ('active', 'in', [True, False])])
if not processing_technology:
self.create({
"name": item['name'],
"code": item['code'],
"code": item['process_encode'],
"remark": item['remark'],
"active": item['active'],
})
@@ -496,7 +490,7 @@ class MachineControlSystem(models.Model):
if result['status'] == 1:
for item in result['machine_control_system_yesterday_list']:
if item:
control_system = self.search([("code", '=', item['code'])])
control_system = self.search([("code", '=', item['code']), ('active', 'in', [True, False])])
brand = self.env['sf.machine.brand'].search([('code', '=', item['brand_id'])])
if control_system:
control_system.name = item['name']
@@ -525,7 +519,7 @@ class MachineControlSystem(models.Model):
if result['status'] == 1:
for item in result['machine_control_system_all_list']:
if item:
control_system = self.search([("code", '=', item['code'])])
control_system = self.search([("code", '=', item['code']), ('active', 'in', [True, False])])
brand = self.env['sf.machine.brand'].search([('code', '=', item['brand_id'])])
if not control_system:
self.create({
@@ -559,7 +553,7 @@ class MachineBrand(models.Model):
result = json.loads(r['result'])
if result['status'] == 1:
for item in result['machine_brand_yesterday_list']:
brand = self.search([("code", '=', item['code'])])
brand = self.search([("code", '=', item['code']), ('active', 'in', [True, False])])
if brand:
brand.name = item['name']
brand.image_brand = '' if not item['image_brand'] else base64.b64decode(item['image_brand'])
@@ -588,7 +582,7 @@ class MachineBrand(models.Model):
result = json.loads(r['result'])
if result['status'] == 1:
for item in result['machine_brand_all_list']:
brand = self.search([("code", '=', item['code'])])
brand = self.search([("code", '=', item['code']), ('active', 'in', [True, False])])
if not brand:
self.create({
"name": item['name'],
@@ -628,7 +622,7 @@ class MachineToolType(models.Model):
else:
image = ''
taper_type_id = self.env['spindle.taper.type'].search([('name', '=', item['taper_type_id'])])
machine_tool_type = self.search([("code", '=', item['code'])])
machine_tool_type = self.search([("code", '=', item['code']), ('active', 'in', [True, False])])
control_system = self.env['sf.machine.control_system'].search(
[('code', '=', item['control_system_id'])])
jg_image_id = self.env['maintenance.equipment.image'].search([('name', 'in', item['jg_image_id'])])
@@ -822,7 +816,7 @@ class MachineToolType(models.Model):
'name': item['taper_type_id']
})
machine_tool_type = self.search([("code", '=', item['code'])])
machine_tool_type = self.search([("code", '=', item['code']), ('active', 'in', [True, False])])
control_system = self.env['sf.machine.control_system'].search(
[('code', '=', item['control_system_id'])])
brand = self.env['sf.machine.brand'].search([('code', '=', item['brand_id'])])
@@ -1013,7 +1007,7 @@ class sfProcessingOrder(models.Model):
result = json.loads(r['result'])
if result['status'] == 1:
for item in result['processing_order_yesterday_list']:
processing_order = self.search([("id", '=', item['id'])])
processing_order = self.search([("id", '=', item['id']), ('active', 'in', [True, False])])
if processing_order:
processing_order.sequence = item['sequence']
else:
@@ -1033,7 +1027,7 @@ class sfProcessingOrder(models.Model):
result = json.loads(r['result'])
if result['status'] == 1:
for item in result['processing_order_all_list']:
processing_order = self.search([("id", '=', item['id'])])
processing_order = self.search([("id", '=', item['id']), ('active', 'in', [True, False])])
if not processing_order:
self.create({
"sequence": item['sequence'],
@@ -1060,7 +1054,8 @@ class sfProductionProcessParameter(models.Model):
if result['status'] == 1:
for item in result['mrs_production_process_parameter_yesterday_list']:
if item:
production_process_parameter = self.search([("code", '=', item['code'])])
production_process_parameter = self.search(
[("code", '=', item['code']), ('active', 'in', [True, False])])
process = self.env['sf.production.process'].search(
[('code', '=', item['process_id_code'])])
if production_process_parameter:
@@ -1093,7 +1088,7 @@ class sfProductionProcessParameter(models.Model):
for item in result['mrs_production_process_parameter_all_list']:
if item:
production_process_parameter = self.search(
[("code", '=', item['code'])])
[("code", '=', item['code']), ('active', 'in', [True, False])])
process = self.env['sf.production.process'].search(
[('code', '=', item['process_id_code'])], limit=1)
if not production_process_parameter:
@@ -1130,7 +1125,7 @@ class MachineToolCategory(models.Model):
result = json.loads(r['result'])
if result['status'] == 1:
for item in result['machine_tool_category_yesterday_list']:
machine_tool_category = self.search([("code", '=', item['code'])])
machine_tool_category = self.search([("code", '=', item['code']), ('active', 'in', [True, False])])
if machine_tool_category:
machine_tool_category.name = item['name']
machine_tool_category.category = item['category']
@@ -1157,7 +1152,7 @@ class MachineToolCategory(models.Model):
result = json.loads(r['result'])
if result['status'] == 1:
for item in result['machine_tool_category_all_list']:
machine_tool_category = self.search([("code", '=', item['code'])])
machine_tool_category = self.search([("code", '=', item['code']), ('active', 'in', [True, False])])
if not machine_tool_category:
self.create({
"name": item['name'],
@@ -1195,7 +1190,8 @@ class sfSyncCutting_tool_Material(models.Model):
if result.get('mrs_cutting_tool_material_yesterday_list'):
for item in result['mrs_cutting_tool_material_yesterday_list']:
if item:
cutting_tool_material = self.search([("code", '=', item['code'])])
cutting_tool_material = self.search(
[("code", '=', item['code']), ('active', 'in', [True, False])])
if not cutting_tool_material:
self.create({
"name": item['name'],
@@ -1225,7 +1221,8 @@ class sfSyncCutting_tool_Material(models.Model):
if result.get('mrs_cutting_tool_material_all_list'):
for item in result['mrs_cutting_tool_material_all_list']:
if item:
cutting_tool_material = self.search([("code", '=', item['code'])])
cutting_tool_material = self.search(
[("code", '=', item['code']), ('active', 'in', [True, False])])
if not cutting_tool_material:
self.create({
"name": item['name'],
@@ -1262,7 +1259,8 @@ class SyncFunctionalCuttingToolModel(models.Model):
if result.get('mrs_functional_cutting_tool_model_yesterday_list'):
for item in result['mrs_functional_cutting_tool_model_yesterday_list']:
if item:
functional_cutting_tool_model = self.search([("code", '=', item['code'])])
functional_cutting_tool_model = self.search(
[("code", '=', item['code']), ('active', 'in', [True, False])])
if not functional_cutting_tool_model:
self.create({
"name": item['name'],
@@ -1292,7 +1290,8 @@ class SyncFunctionalCuttingToolModel(models.Model):
if result.get('mrs_functional_cutting_tool_model_all_list'):
for item in result['mrs_functional_cutting_tool_model_all_list']:
if item:
functional_cutting_tool_model = self.search([("code", '=', item['code'])])
functional_cutting_tool_model = self.search(
[("code", '=', item['code']), ('active', 'in', [True, False])])
if not functional_cutting_tool_model:
self.create({
"name": item['name'],
@@ -1329,7 +1328,7 @@ class SyncFixtureMaterial(models.Model):
if result.get('fixture_material_yesterday_list'):
for item in result['fixture_material_yesterday_list']:
if item:
fixture_material = self.search([("code", '=', item['code'])])
fixture_material = self.search([("code", '=', item['code']), ('active', 'in', [True, False])])
if not fixture_material:
self.create({
"name": item['name'],
@@ -1361,7 +1360,7 @@ class SyncFixtureMaterial(models.Model):
if result.get('fixture_material_all_list'):
for item in result['fixture_material_all_list']:
if item:
fixture_material = self.search([("code", '=', item['code'])])
fixture_material = self.search([("code", '=', item['code']), ('active', 'in', [True, False])])
if not fixture_material:
self.create({
"name": item['name'],
@@ -1399,7 +1398,8 @@ class SyncMulti_Mounting_Type(models.Model):
if result.get('multi_mounting_type_yesterday_list'):
for item in result['multi_mounting_type_yesterday_list']:
if item:
multi_mounting_type = self.search([("code", '=', item['code'])])
multi_mounting_type = self.search(
[("code", '=', item['code']), ('active', 'in', [True, False])])
if not multi_mounting_type:
self.create({
"name": item['name'],
@@ -1429,7 +1429,8 @@ class SyncMulti_Mounting_Type(models.Model):
if result.get('multi_mounting_type_all_list'):
for item in result['multi_mounting_type_all_list']:
if item:
multi_mounting_type = self.search([("code", '=', item['code'])])
multi_mounting_type = self.search(
[("code", '=', item['code']), ('active', 'in', [True, False])])
if not multi_mounting_type:
self.create({
"name": item['name'],
@@ -1674,7 +1675,8 @@ class SyncFunctionalFixtureType(models.Model):
if result.get('functional_fixture_type_yesterday_list'):
for item in result['functional_fixture_type_yesterday_list']:
if item:
functional_fixture_type = self.search([("code", '=', item['code'])])
functional_fixture_type = self.search(
[("code", '=', item['code']), ('active', 'in', [True, False])])
if not functional_fixture_type:
self.create({
"name": item['name'],
@@ -1703,7 +1705,8 @@ class SyncFunctionalFixtureType(models.Model):
if result.get('functional_fixture_type_all_list'):
for item in result['functional_fixture_type_all_list']:
if item:
functional_fixture_type = self.search([("code", '=', item['code'])])
functional_fixture_type = self.search(
[("code", '=', item['code']), ('active', 'in', [True, False])])
if not functional_fixture_type:
self.create({
"name": item['name'],
@@ -1739,7 +1742,7 @@ class SfToolType(models.Model):
if result['status'] == 1:
for item in result['mrs_cutting_tool_type_yesterday_list']:
if item:
cutting_tool_type = self.search([("code", '=', item['code'])])
cutting_tool_type = self.search([("code", '=', item['code']), ('active', 'in', [True, False])])
cutting_tool_material = self.env['sf.cutting.tool.material'].search(
[("code", '=', item['cutting_tool_material_code'])])
if not cutting_tool_type:
@@ -1771,7 +1774,7 @@ class SfToolType(models.Model):
if result['status'] == 1:
for item in result['mrs_cutting_tool_type_all_list']:
if item:
cutting_tool_type = self.search([("code", '=', item['code'])])
cutting_tool_type = self.search([("code", '=', item['code']), ('active', 'in', [True, False])])
cutting_tool_material = self.env['sf.cutting.tool.material'].search(
[("code", '=', item['cutting_tool_material_code'])])
if not cutting_tool_type:
@@ -1811,7 +1814,8 @@ class SfMaintenanceEquipmentImage(models.Model):
if result['status'] == 1:
for item in result['ability_feature_library_yesterday_list']:
if item:
ability_feature_library = self.search([("name", '=', item['name'])])
ability_feature_library = self.search(
[("name", '=', item['name']), ('active', 'in', [True, False])])
if not ability_feature_library:
self.create({
"name": item['name'],
@@ -1839,7 +1843,8 @@ class SfMaintenanceEquipmentImage(models.Model):
if result['status'] == 1:
for item in result['ability_feature_library_all_list']:
if item:
ability_feature_library = self.search([("name", '=', item['name'])])
ability_feature_library = self.search(
[("name", '=', item['name']), ('active', 'in', [True, False])])
if not ability_feature_library:
self.create({
"name": item['name'],
@@ -1872,7 +1877,7 @@ class MaterialApply(models.Model):
result = json.loads(r['result'])
if result['status'] == 1:
for item in result['material_apply_yesterday_list']:
material_apply = self.search([("name", '=', item['name'])])
material_apply = self.search([("name", '=', item['name']), ('active', 'in', [True, False])])
if material_apply:
material_apply.name = item['name']
material_apply.active = item['active']
@@ -1894,7 +1899,7 @@ class MaterialApply(models.Model):
result = json.loads(r['result'])
if result['status'] == 1:
for item in result['material_apply_all_list']:
material_apply = self.search([("name", '=', item['name'])])
material_apply = self.search([("name", '=', item['name']), ('active', 'in', [True, False])])
if not material_apply:
self.create({
"name": item['name'],
@@ -1922,7 +1927,7 @@ class ModelInternationalStandards(models.Model):
result = json.loads(r['result'])
if result['status'] == 1:
for item in result['mrs_international_standards_yesterday_list']:
international_standards = self.search([("name", '=', item['name'])])
international_standards = self.search([("name", '=', item['name']), ('active', 'in', [True, False])])
if international_standards:
international_standards.name = item['name']
international_standards.active = item['active']
@@ -1945,7 +1950,7 @@ class ModelInternationalStandards(models.Model):
result = json.loads(r['result'])
if result['status'] == 1:
for item in result['mrs_international_standards_all_list']:
international_standards = self.search([("name", '=', item['name'])])
international_standards = self.search([("name", '=', item['name']), ('active', 'in', [True, False])])
if not international_standards:
self.create({
"name": item['name'],
@@ -1973,7 +1978,7 @@ class CuttingSpeed(models.Model):
result = json.loads(r['result'])
if result['status'] == 1:
for item in result['cutting_speed_yesterday_list']:
cutting_speed = self.search([("name", '=', item['name'])])
cutting_speed = self.search([("name", '=', item['name']), ('active', 'in', [True, False])])
if not cutting_speed:
self.create({
'name': item['name'],
@@ -2027,7 +2032,7 @@ class CuttingSpeed(models.Model):
result = json.loads(r['result'])
if result['status'] == 1:
for item in result['cutting_speed_all_list']:
cutting_speed = self.search([("name", '=', item['name'])])
cutting_speed = self.search([("name", '=', item['name']), ('active', 'in', [True, False])])
if not cutting_speed:
self.create({
'name': item['name'],
@@ -2087,7 +2092,7 @@ class CuttingWidthDepth(models.Model):
result = json.loads(r['result'])
if result['status'] == 1:
for item in result['cutting_width_depth_yesterday_list']:
cutting_width_depth = self.search([("name", '=', item['name'])])
cutting_width_depth = self.search([("name", '=', item['name']), ('active', 'in', [True, False])])
if not cutting_width_depth:
self.create({
'name': item['name'],
@@ -2104,7 +2109,7 @@ class CuttingWidthDepth(models.Model):
result = json.loads(r['result'])
if result['status'] == 1:
for item in result['cutting_width_depth_all_list']:
cutting_width_depth = self.search([("name", '=', item['name'])])
cutting_width_depth = self.search([("name", '=', item['name']), ('active', 'in', [True, False])])
if not cutting_width_depth:
self.create({
'name': item['name'],
@@ -2127,7 +2132,7 @@ class CuttingSpeed(models.Model):
result = json.loads(r['result'])
if result['status'] == 1:
for item in result['feed_per_tooth_yesterday_list']:
feed_per_tooth = self.search([("name", '=', item['name'])])
feed_per_tooth = self.search([("name", '=', item['name']), ('active', 'in', [True, False])])
if not feed_per_tooth:
self.create({
'name': item['name'],
@@ -2165,7 +2170,7 @@ class CuttingSpeed(models.Model):
result = json.loads(r['result'])
if result['status'] == 1:
for item in result['feed_per_tooth_all_list']:
feed_per_tooth = self.search([("name", '=', item['name'])])
feed_per_tooth = self.search([("name", '=', item['name']), ('active', 'in', [True, False])])
if not feed_per_tooth:
self.create({
'name': item['name'],
@@ -2211,7 +2216,8 @@ class Cutting_tool_standard_library(models.Model):
if result['status'] == 1:
for item in result['cutting_tool_standard_library_yesterday_list']:
cutting_tool_standard_library = self.search(
[("code", '=', item['code'].replace("JKM", result['factory_short_name']))])
[("code", '=', item['code'].replace("JKM", result['factory_short_name']),
('active', 'in', [True, False]))])
cutting_tool_type = self.env['sf.cutting.tool.type'].search(
[("code", '=', item['cutting_tool_type_code'])])
cutting_tool_material = self.env['sf.cutting.tool.material'].search(
@@ -2317,7 +2323,8 @@ class Cutting_tool_standard_library(models.Model):
if result['status'] == 1:
for item in result['cutting_tool_standard_library_all_list']:
cutting_tool_standard_library = self.search(
[("code", '=', item['code'].replace("JKM", result['factory_short_name']))])
[("code", '=', item['code'].replace("JKM", result['factory_short_name']),
('active', 'in', [True, False]))])
cutting_tool_type = self.env['sf.cutting.tool.type'].search(
[("code", '=', item['cutting_tool_type_code'])])
cutting_tool_material = self.env['sf.cutting.tool.material'].search(
@@ -2431,7 +2438,8 @@ class CuttingToolBasicParameters(models.Model):
result['cutting_tool_basic_parameters_all_list']['basic_parameters_integral_tool'])
if basic_parameters_integral_tool_list:
for integral_tool_item in basic_parameters_integral_tool_list:
integral_tool = self.search([('code', '=', integral_tool_item['code'])])
integral_tool = self.search(
[('code', '=', integral_tool_item['code']), ('active', 'in', [True, False])])
if not integral_tool:
self.create({
'name': integral_tool_item['name'],
@@ -2483,7 +2491,7 @@ class CuttingToolBasicParameters(models.Model):
result['cutting_tool_basic_parameters_all_list']['basic_parameters_blade'])
if basic_parameters_blade_list:
for blade_item in basic_parameters_blade_list:
blade = self.search([('code', '=', blade_item['code'])])
blade = self.search([('code', '=', blade_item['code']), ('active', 'in', [True, False])])
if not blade:
self.create({
'name': blade_item['name'],
@@ -2547,7 +2555,7 @@ class CuttingToolBasicParameters(models.Model):
result['cutting_tool_basic_parameters_all_list']['basic_parameters_chuck'])
if basic_parameters_chuck_list:
for chuck_item in basic_parameters_chuck_list:
chuck = self.search([('code', '=', chuck_item['code'])])
chuck = self.search([('code', '=', chuck_item['code']), ('active', 'in', [True, False])])
if not chuck:
self.create({
'name': chuck_item['name'],
@@ -2591,7 +2599,8 @@ class CuttingToolBasicParameters(models.Model):
result['cutting_tool_basic_parameters_all_list']['basic_parameters_cutter_arbor'])
if basic_parameters_cutter_arbor_list:
for cutter_arbor_item in basic_parameters_cutter_arbor_list:
cutter_arbor = self.search([('code', '=', cutter_arbor_item['code'])])
cutter_arbor = self.search(
[('code', '=', cutter_arbor_item['code']), ('active', 'in', [True, False])])
if not cutter_arbor:
self.create({
'name': cutter_arbor_item['name'],
@@ -2659,7 +2668,8 @@ class CuttingToolBasicParameters(models.Model):
result['cutting_tool_basic_parameters_all_list']['basic_parameters_cutter_head'])
if basic_parameters_cutter_head_list:
for cutter_head_item in basic_parameters_cutter_head_list:
cutter_head = self.search([('code', '=', cutter_head_item['code'])])
cutter_head = self.search(
[('code', '=', cutter_head_item['code']), ('active', 'in', [True, False])])
if not cutter_head:
self.create({
'name': cutter_head_item['name'],
@@ -2713,7 +2723,8 @@ class CuttingToolBasicParameters(models.Model):
result['cutting_tool_basic_parameters_all_list']['basic_parameters_knife_handle'])
if basic_parameters_knife_handle_list:
for knife_handle_item in basic_parameters_knife_handle_list:
knife_handle = self.search([('code', '=', knife_handle_item['code'])])
knife_handle = self.search(
[('code', '=', knife_handle_item['code']), ('active', 'in', [True, False])])
if not knife_handle:
self.create({
'name': knife_handle_item['name'],
@@ -2780,7 +2791,8 @@ class CuttingToolBasicParameters(models.Model):
result['cutting_tool_basic_parameters_all_list']['basic_parameters_integral_tool'])
if basic_parameters_integral_tool_list:
for integral_tool_item in basic_parameters_integral_tool_list:
integral_tool = self.search([('code', '=', integral_tool_item['code'])])
integral_tool = self.search(
[('code', '=', integral_tool_item['code']), ('active', 'in', [True, False])])
if not integral_tool:
self.create({
'name': integral_tool_item['name'],
@@ -2835,7 +2847,7 @@ class CuttingToolBasicParameters(models.Model):
result['cutting_tool_basic_parameters_all_list']['basic_parameters_blade'])
if basic_parameters_blade_list:
for blade_item in basic_parameters_blade_list:
blade = self.search([('code', '=', blade_item['code'])])
blade = self.search([('code', '=', blade_item['code']), ('active', 'in', [True, False])])
if not blade:
self.create({
'name': blade_item['name'],
@@ -2901,7 +2913,7 @@ class CuttingToolBasicParameters(models.Model):
result['cutting_tool_basic_parameters_all_list']['basic_parameters_chuck'])
if basic_parameters_chuck_list:
for chuck_item in basic_parameters_chuck_list:
chuck = self.search([('code', '=', chuck_item['code'])])
chuck = self.search([('code', '=', chuck_item['code']), ('active', 'in', [True, False])])
if not chuck:
self.create({
'name': chuck_item['name'],
@@ -2947,7 +2959,8 @@ class CuttingToolBasicParameters(models.Model):
result['cutting_tool_basic_parameters_all_list']['basic_parameters_cutter_arbor'])
if basic_parameters_cutter_arbor_list:
for cutter_arbor_item in basic_parameters_cutter_arbor_list:
cutter_arbor = self.search([('code', '=', cutter_arbor_item['code'])])
cutter_arbor = self.search(
[('code', '=', cutter_arbor_item['code']), ('active', 'in', [True, False])])
if not cutter_arbor:
self.create({
'name': cutter_arbor_item['name'],
@@ -3017,7 +3030,8 @@ class CuttingToolBasicParameters(models.Model):
result['cutting_tool_basic_parameters_all_list']['basic_parameters_cutter_head'])
if basic_parameters_cutter_head_list:
for cutter_head_item in basic_parameters_cutter_head_list:
cutter_head = self.search([('code', '=', cutter_head_item['code'])])
cutter_head = self.search(
[('code', '=', cutter_head_item['code']), ('active', 'in', [True, False])])
if not cutter_head:
self.create({
'name': cutter_head_item['name'],
@@ -3073,7 +3087,8 @@ class CuttingToolBasicParameters(models.Model):
result['cutting_tool_basic_parameters_all_list']['basic_parameters_knife_handle'])
if basic_parameters_knife_handle_list:
for knife_handle_item in basic_parameters_knife_handle_list:
knife_handle = self.search([('code', '=', knife_handle_item['code'])])
knife_handle = self.search(
[('code', '=', knife_handle_item['code']), ('active', 'in', [True, False])])
if not knife_handle:
self.create({
'name': knife_handle_item['name'],

View File

@@ -67,6 +67,12 @@ class sf_production_plan(models.Model):
sequence = fields.Integer(string='序号', copy=False, readonly=True, index=True)
current_operation_name = fields.Char(string='当前工序名称', size=64, default='生产计划')
@api.onchange('production_line_id')
def _compute_production_line_id(self):
for item in self:
item.production_id.production_line_id = item.production_line_id.id
item.production_id.plan_start_processing_time = item.date_planned_start
@api.onchange('state')
def _onchange_state(self):
if self.state == 'finished':
@@ -194,7 +200,8 @@ class sf_production_plan(models.Model):
record.date_planned_start, record.date_planned_finished = \
item.date_planned_start, item.date_planned_finished
record.state = 'done'
record.production_id.schedule_state = '已排'
# record.production_id.schedule_state = '已排'
record.sudo().production_id.schedule_state = '已排'
# self.env['sale.order'].browse(record.production_id.origin).schedule_status = 'to process'
sale_obj = self.env['sale.order'].search([('name', '=', record.origin)])
if 'S' in sale_obj.name:
@@ -202,7 +209,7 @@ class sf_production_plan(models.Model):
mrp_production_ids = record.production_id._get_children().ids
print('mrp_production_ids', mrp_production_ids)
for i in mrp_production_ids:
record.env['mrp.production'].browse(i).schedule_state = '已排'
record.env['mrp.production'].sudo().browse(i).schedule_state = '已排'
# record.production_id.date_planned_start = record.date_planned_start
# record.production_id.date_planned_finished = record.date_planned_finished
else:
@@ -323,33 +330,6 @@ class sf_production_plan(models.Model):
raise UserError(e)
# # sf生产排程
# class sf_produce_plan(models.Model):
# _name = 'sf.produce.plan'
# _description = 'sf生产排程'
# # 重写create方法使得创建坯料预制排程时如果给出了计划结束时间则计划开始时间为计划结束时间减去坯料预制时间
# @api.model
# def create(self, vals):
# # 评估结束时间
# vals['plan_end_time'] = self._get_plan_end_time(vals['plan_start_time'], vals['quantity'])
# return super(sf_pl_plan, self).create(vals)
# # 当不设置计划结束时间时,增加计算计划结束时间的方法
# @api.onchange('plan_start_time', 'quantity')
# def _onchange_plan_start_time(self):
# if self.plan_start_time and self.quantity:
# self.plan_end_time = self._get_plan_end_time(self.plan_start_time, self.quantity)
#
# # 计算计划结束时间
# def _get_plan_end_time(self, plan_start_time, quantity):
# # 坯料预制时间
# pl_time = 0.5
# # 计划结束时间 = 计划开始时间 + 坯料预制时间
# plan_end_time = plan_start_time + pl_time
# return plan_end_time
#
# 机台作业计划
class machine_work_schedule(models.Model):
_name = 'sf.machine.schedule'

View File

@@ -12,7 +12,8 @@
<field name="check_status" invisible="1"/>
<!-- <button name="archive" type="object" string="归档" icon="fa-archive" class="oe_highlight" attrs="{'invisible': [('active', '=', False)]}"/> -->
<!-- <button name="unarchive" type="object" string="取消归档" icon="fa-archive" class="oe_highlight" attrs="{'invisible': [('active', '=', True)]}"/> -->
<button name="action_check" string="审核" type="object" class="oe_highlight" attrs="{'invisible': [('check_status', '=', True)]}" groups="sf_base.group_plan_director"/>
<button name="action_check" string="审核" type="object" class="oe_highlight"
attrs="{'invisible': [('check_status', '=', True)]}" groups="sf_base.group_plan_director"/>
<!-- <button name="action_uncheck" string="禁用" type="object" class="oe_highlight" attrs="{'invisible': [('check_status', '=', False)]}" groups="sf_base.group_plan_director"/> -->
</xpath>
</field>
@@ -29,7 +30,8 @@
<field name="check_status" invisible="1"/>
<!-- <button name="archive" type="object" string="归档" icon="fa-archive" class="oe_highlight" attrs="{'invisible': [('active', '=', False)]}"/> -->
<!-- <button name="unarchive" type="object" string="取消归档" icon="fa-archive" class="oe_highlight" attrs="{'invisible': [('active', '=', True)]}"/> -->
<button name="action_check" string="审核" type="object" class="oe_highlight" attrs="{'invisible': [('check_status', '=', True)]}" groups="sf_base.group_plan_director"/>
<button name="action_check" string="审核" type="object" class="oe_highlight"
attrs="{'invisible': [('check_status', '=', True)]}" groups="sf_base.group_plan_director"/>
<!-- <button name="action_uncheck" string="禁用" type="object" class="oe_highlight" attrs="{'invisible': [('check_status', '=', False)]}" groups="sf_base.group_plan_director"/> -->
</xpath>
</field>
@@ -64,7 +66,9 @@
<field name="check_status" invisible="1"/>
<!-- <button name="archive" type="object" string="归档" icon="fa-archive" class="oe_highlight" attrs="{'invisible': [('active', '=', False)]}"/> -->
<!-- <button name="unarchive" type="object" string="取消归档" icon="fa-archive" class="oe_highlight" attrs="{'invisible': [('active', '=', True)]}"/> -->
<button name="action_check" string="审核" type="object" class="oe_highlight" attrs="{'invisible': [('check_status', '=', True)]}" groups="sf_base.group_plan_director"/>
<button name="action_check" string="审核" type="object" class="oe_highlight"
attrs="{'invisible': [('check_status', '=', True)]}"
groups="sf_base.group_plan_director"/>
<!-- <button name="action_uncheck" string="禁用" type="object" class="oe_highlight" attrs="{'invisible': [('check_status', '=', False)]}" groups="sf_base.group_plan_director"/> -->
</header>
</xpath>
@@ -83,7 +87,9 @@
<field name="check_status" invisible="1"/>
<!-- <button name="archive" type="object" string="归档" icon="fa-archive" class="oe_highlight" attrs="{'invisible': [('active', '=', False)]}"/> -->
<!-- <button name="unarchive" type="object" string="取消归档" icon="fa-archive" class="oe_highlight" attrs="{'invisible': [('active', '=', True)]}"/> -->
<button name="action_check" string="审核" type="object" class="oe_highlight" attrs="{'invisible': [('check_status', '=', True)]}" groups="sf_base.group_plan_director"/>
<button name="action_check" string="审核" type="object" class="oe_highlight"
attrs="{'invisible': [('check_status', '=', True)]}"
groups="sf_base.group_plan_director"/>
<!-- <button name="action_uncheck" string="禁用" type="object" class="oe_highlight" attrs="{'invisible': [('check_status', '=', False)]}" groups="sf_base.group_plan_director"/> -->
</header>
</xpath>
@@ -102,7 +108,9 @@
<field name="check_status" invisible="1"/>
<!-- <button name="archive" type="object" string="归档" icon="fa-archive" class="oe_highlight" attrs="{'invisible': [('active', '=', False)]}"/> -->
<!-- <button name="unarchive" type="object" string="取消归档" icon="fa-archive" class="oe_highlight" attrs="{'invisible': [('active', '=', True)]}"/> -->
<button name="action_check" string="审核" type="object" class="oe_highlight" attrs="{'invisible': [('check_status', '=', True)]}" groups="sf_base.group_plan_director"/>
<button name="action_check" string="审核" type="object" class="oe_highlight"
attrs="{'invisible': [('check_status', '=', True)]}"
groups="sf_base.group_plan_director"/>
<!-- <button name="action_uncheck" string="禁用" type="object" class="oe_highlight" attrs="{'invisible': [('check_status', '=', False)]}" groups="sf_base.group_plan_director"/> -->
</header>
</xpath>
@@ -121,7 +129,9 @@
<field name="check_status" invisible="1"/>
<!-- <button name="archive" type="object" string="归档" icon="fa-archive" class="oe_highlight" attrs="{'invisible': [('active', '=', False)]}"/> -->
<!-- <button name="unarchive" type="object" string="取消归档" icon="fa-archive" class="oe_highlight" attrs="{'invisible': [('active', '=', True)]}"/> -->
<button name="action_check" string="审核" type="object" class="oe_highlight" attrs="{'invisible': [('check_status', '=', True)]}" groups="sf_base.group_plan_director"/>
<button name="action_check" string="审核" type="object" class="oe_highlight"
attrs="{'invisible': [('check_status', '=', True)]}"
groups="sf_base.group_plan_director"/>
<!-- <button name="action_uncheck" string="禁用" type="object" class="oe_highlight" attrs="{'invisible': [('check_status', '=', False)]}" groups="sf_base.group_plan_director"/> -->
</header>
</xpath>
@@ -140,7 +150,9 @@
<field name="check_status" invisible="1"/>
<!-- <button name="archive" type="object" string="归档" icon="fa-archive" class="oe_highlight" attrs="{'invisible': [('active', '=', False)]}"/> -->
<!-- <button name="unarchive" type="object" string="取消归档" icon="fa-archive" class="oe_highlight" attrs="{'invisible': [('active', '=', True)]}"/> -->
<button name="action_check" string="审核" type="object" class="oe_highlight" attrs="{'invisible': [('check_status', '=', True)]}" groups="sf_base.group_plan_director"/>
<button name="action_check" string="审核" type="object" class="oe_highlight"
attrs="{'invisible': [('check_status', '=', True)]}"
groups="sf_base.group_plan_director"/>
<!-- <button name="action_uncheck" string="禁用" type="object" class="oe_highlight" attrs="{'invisible': [('check_status', '=', False)]}" groups="sf_base.group_plan_director"/> -->
</header>
</xpath>
@@ -159,7 +171,9 @@
<field name="check_status" invisible="1"/>
<!-- <button name="archive" type="object" string="归档" icon="fa-archive" class="oe_highlight" attrs="{'invisible': [('active', '=', False)]}"/> -->
<!-- <button name="unarchive" type="object" string="取消归档" icon="fa-archive" class="oe_highlight" attrs="{'invisible': [('active', '=', True)]}"/> -->
<button name="action_check" string="审核" type="object" class="oe_highlight" attrs="{'invisible': [('check_status', '=', True)]}" groups="sf_base.group_plan_director"/>
<button name="action_check" string="审核" type="object" class="oe_highlight"
attrs="{'invisible': [('check_status', '=', True)]}"
groups="sf_base.group_plan_director"/>
<!-- <button name="action_uncheck" string="禁用" type="object" class="oe_highlight" attrs="{'invisible': [('check_status', '=', False)]}" groups="sf_base.group_plan_director"/> -->
</header>
</xpath>

View File

@@ -9,9 +9,12 @@
<tree string="订单计划">
<header>
<!-- <button name="do_production_schedule" type="object" string="批量排程"/> -->
<button string="批量排程" name="%(sf_plan.action_plan_some)d" type="action" class="btn-primary"/>
<button string="批量排程" name="%(sf_plan.action_plan_some)d" type="action"
class="btn-primary"/>
</header>
<field name="state" widget="badge" decoration-warning="state == 'draft'" decoration-success="state == 'done'" decoration-info="state == 'processing'" decoration-danger="state == 'finished'"/>
<field name="state" widget="badge" decoration-warning="state == 'draft'"
decoration-success="state == 'done'" decoration-info="state == 'processing'"
decoration-danger="state == 'finished'"/>
<field name="name"/>
<field name="origin"/>
<field name="order_deadline"/>
@@ -20,8 +23,12 @@
<field name="date_planned_start"/>
<field name="date_planned_finished"/>
<field name="schedule_setting"/>
<button name="do_production_schedule" class="btn schedule_done" string="生产排程" type="object" attrs="{'invisible': [('state', 'not in', ['draft'])]}" groups="sf_base.group_plan_dispatch"/>
<button name="cancel_production_schedule" class="btn schedule_cancel" string="取消排程" type="object" attrs="{'invisible': [('state', 'not in', ['done'])]}" groups="sf_base.group_plan_dispatch"/>
<button name="do_production_schedule" class="btn schedule_done" string="生产排程" type="object"
attrs="{'invisible': [('state', 'not in', ['draft'])]}"
groups="sf_base.group_plan_dispatch"/>
<button name="cancel_production_schedule" class="btn schedule_cancel" string="取消排程"
type="object" attrs="{'invisible': [('state', 'not in', ['done'])]}"
groups="sf_base.group_plan_dispatch"/>
</tree>
</field>
</record>
@@ -33,8 +40,11 @@
<form string="订单计划">
<header>
<!-- <button string="执行排程" name="do_production_schedule" type="object" class="oe_highlight" icon="fa-step-forward"/> -->
<button string="执行排程" name="do_production_schedule" type="object" class="oe_highlight" options='{"calendar_view": true, "date_begin": "2020-01-01", "date_end": "2020-12-31"}' groups="sf_base.group_plan_dispatch" attrs="{'invisible': [('state', '=', 'done')]}"/>
<button string="取消排程" name="cancel_production_schedule" type="object" class="oe_highlight" groups="sf_base.group_plan_dispatch" attrs="{'invisible': [('state', '=', 'draft')]}"/>
<button string="执行排程" name="do_production_schedule" type="object" class="oe_highlight"
options='{"calendar_view": true, "date_begin": "2020-01-01", "date_end": "2020-12-31"}'
groups="sf_base.group_plan_dispatch" attrs="{'invisible': [('state', '=', 'done')]}"/>
<button string="取消排程" name="cancel_production_schedule" type="object" class="oe_highlight"
groups="sf_base.group_plan_dispatch" attrs="{'invisible': [('state', '=', 'draft')]}"/>
<!-- <button name="archive" type="object" string="归档" icon="fa-archive" class="oe_highlight" attrs="{'invisible': [('active', '=', False)]}"/> -->
<!-- <button name="unarchive" type="object" string="取消归档" icon="fa-archive" class="oe_highlight" attrs="{'invisible': [('active', '=', True)]}"/> -->
@@ -191,65 +201,6 @@
</field>
</record>
<!-- <record id="sf_pl_plan_action" model="ir.actions.act_window"> -->
<!-- <field name="name">制造订单生产计划</field> -->
<!-- <field name="type">ir.actions.act_window</field> -->
<!-- <field name="res_model">sf.pl.plan</field> -->
<!-- <field name="view_mode">tree,form,gantt</field> -->
<!-- </record> -->
<!-- <record id="sf_production_gantt_view" model="ir.ui.view"> -->
<!-- <field name="name">sf.production.plan.gantt</field> -->
<!-- <field name="model">mrp.production</field> -->
<!-- <field name="arch" type="xml"> -->
<!-- <gantt class="o_mrp_workorder_gantt" date_stop="date_planned_finished" date_start="date_planned_start" -->
<!-- string="制造订单生产计划" default_group_by="production_line_id" create="0" -->
<!-- delete="0" sample="1" plan="0" -->
<!-- display_unavailability="1" -->
<!-- decoration-success="state == 'done'" -->
<!-- decoration-secondary="state == 'cancel'" -->
<!-- color="production_line_id" -->
<!-- progress_bar="state" -->
<!-- form_view_id="mrp.mrp_production_form_view"> -->
<!-- <field name="name"/> -->
<!-- <field name="product_qty"/> -->
<!-- <field name="date_planned_start"/> -->
<!-- <field name="date_planned_finished" string="计划结束时间"/> -->
<!-- <field name="state"/> -->
<!-- <templates> -->
<!-- <div t-name="gantt-popover" class="container-fluid"> -->
<!-- <div class="row g-0"> -->
<!-- <div class="col"> -->
<!-- <ul class="ps-1 mb-0 list-unstyled"> -->
<!-- <li> -->
<!-- <strong>开始时间:</strong> -->
<!-- <t t-out="userTimezoneStartDate.format('L LTS')"/> -->
<!-- </li> -->
<!-- <li> -->
<!-- <strong>结束时间:</strong> -->
<!-- <t t-out="userTimezoneStopDate.format('L LTS')"/> -->
<!-- </li> -->
<!-- <li> -->
<!-- <strong>数量:</strong> -->
<!-- <t t-out="product_qty"/> -->
<!-- </li> -->
<!-- <li> -->
<!-- <strong>状态:</strong> -->
<!-- <t t-if="state === 'cancel'">已取消</t> -->
<!-- <t t-elif="state === 'done'">已完成</t> -->
<!-- <t t-elif="state === '已排程'">已排程</t> -->
<!-- <t t-else="">其他状态</t> -->
<!-- <t t-out="state"/> -->
<!-- </li> -->
<!-- </ul> -->
<!-- </div> -->
<!-- </div> -->
<!-- </div> -->
<!-- </templates> -->
<!-- </gantt> -->
<!-- </field> -->
<!-- </record> -->
<record id="sf_machine_schedule_tree" model="ir.ui.view">
<field name="name">sf.machine.schedule.tree</field>
<field name="model">sf.machine.schedule</field>
@@ -327,6 +278,14 @@
action="mrp_custom_action"
parent="sf_production_plan_menu"
/>
<menuitem
id="sf_workpiece_delivery_menu"
name="工件配送"
sequence="10"
action="sf_manufacturing.sf_workpiece_delivery_act"
parent="mrp.menu_mrp_manufacturing"
/>
<!-- <menuitem -->
<!-- id="sale_custom_menu" -->
<!-- name="报价单" -->
@@ -341,22 +300,6 @@
action="sf_production_plan_action1"
parent="sf_production_plan_menu"
/>
<!-- <menuitem -->
<!-- id="machine_work_schedule" -->
<!-- name="机台作业计划" -->
<!-- sequence="200" -->
<!-- action="action_machine_work_schedule" -->
<!-- parent="sf_production_plan_menu" -->
<!-- /> -->
<!-- --><!-- 在现有菜单结构后面加入自定义的动作 -->
<!-- <menuitem -->
<!-- id="mrp_custom_menuitem" -->
<!-- name="My Custom Menuitem" -->
<!-- sequence="20" -->
<!-- action="mrp_custom_action"/> -->
<!-- --><!-- 自定义额外的菜单项 --><!-- -->
<!-- </field> -->
</data>
</odoo>

View File

@@ -2,3 +2,4 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import custom_quality
from . import quality

View File

@@ -0,0 +1,34 @@
import json
import requests
from odoo import fields, models, api
from odoo.exceptions import ValidationError
from odoo.addons.sf_base.commons.common import Common
class QualityCheck(models.Model):
_inherit = "quality.check"
_description = '零件特采'
# ==========零件特采接口==========
def _register_tool_groups(self):
create_url = '/AutoDeviceApi/FeedBackOut'
sf_sync_config = self.env['res.config.settings'].get_values()
token = sf_sync_config['token']
sf_secret_key = sf_sync_config['sf_secret_key']
headers = Common.get_headers(self, token, sf_secret_key)
strurl = sf_sync_config['sf_url'] + create_url
val = {
'RfidCode': None,
}
kw = json.dumps(val, ensure_ascii=False)
r = requests.post(strurl, json={}, data={'kw': kw, 'token': token}, headers=headers)
ret = r.json()
if r == 200:
return "零件特采发送成功"
else:
raise ValidationError("零件特采发送失败")
# @api.onchange('quality_state')
# def _onchange_quality_state(self):
# if self.quality_state in ['pass', 'fail']:
# self._register_tool_groups()

View File

@@ -8,6 +8,7 @@ __author__ = 'jinling.yang'
_logger = logging.getLogger(__name__)
class AutoQuatotion(models.Model):
_name = 'sf.auto_quatotion.common'
_description = u'自动报价公用类'

View File

@@ -7,6 +7,7 @@ from odoo.exceptions import UserError
class ReSaleOrder(models.Model):
_inherit = 'sale.order'
logistics_way = fields.Selection([('自提', '自提'), ('到付', '到付'), ('在线支付', '在线支付')], string='物流方式')
state = fields.Selection(
selection=[
('draft', "报价"),
@@ -19,7 +20,6 @@ class ReSaleOrder(models.Model):
readonly=True, copy=False, index=True,
tracking=3,
default='draft')
deadline_of_delivery = fields.Date('订单交期', tracking=True)
person_of_delivery = fields.Char('交货人')
telephone_of_delivery = fields.Char('交货人电话号码')
@@ -141,6 +141,8 @@ class RePurchaseOrder(models.Model):
if not self.user_id:
if self.partner_id:
self.user_id = self.partner_id.purchase_user_id.id
self.check_status = 'pending'
self.state = 'purchase'
else:
self.user_id = self.env.user.id

View File

@@ -71,10 +71,11 @@ access_purchase_order_wizard_group_purchase,purchase_order_wizard_group_purchase
access_purchase_order_wizard_group_purchase_director,purchase_order_wizard_group_purchase_director,model_purchase_order_wizard,sf_base.group_purchase_director,1,1,1,0
access_crm_tag_group_sale_salemanager,crm_tag_group_sale_salemanager,sales_team.model_crm_tag,sf_base.group_sale_salemanager,1,0,0,0
access_crm_tag_group_sale_director,crm_tag_group_sale_director,sales_team.model_crm_tag,sf_base.group_sale_director,1,1,1,0
access_sale_order,sale.order,sale.model_sale_order,sf_base.group_plan_dispatch,1,1,0,0
access_res_partner_group_sale_salemanager,res_partner_group_sale_salemanager,base.model_res_partner,sf_base.group_sale_salemanager,1,0,1,0
access_res_partner_group_sale_director,res_partner_group_sale_director,base.model_res_partner,sf_base.group_sale_director,1,0,1,0
access_sale_order_cancel_group_sale_salemanager,sale_order_cancel_group_sale_salemanager,sale.model_sale_order_cancel,sf_base.group_sale_salemanager,1,1,1,0
access_sale_order_cancel_group_sale_director,sale_order_cancel_group_sale_director,sale.model_sale_order_cancel,sf_base.group_sale_director,1,1,1,0
access_res_partner_group_purchase,res_partner_group_purchase,base.model_res_partner,sf_base.group_purchase,1,0,1,0
access_res_partner_group_purchase_director,res_partner_group_purchase_director,base.model_res_partner,sf_base.group_purchase_director,1,0,1,0
access_sale_advance_payment_inv_group_sale_salemanager,sale_advance_payment_inv_group_sale_salemanager,sale.model_sale_advance_payment_inv,sf_base.group_sale_salemanager,1,1,1,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
71 access_purchase_order_wizard_group_purchase_director purchase_order_wizard_group_purchase_director model_purchase_order_wizard sf_base.group_purchase_director 1 1 1 0
72 access_crm_tag_group_sale_salemanager crm_tag_group_sale_salemanager sales_team.model_crm_tag sf_base.group_sale_salemanager 1 0 0 0
73 access_crm_tag_group_sale_director crm_tag_group_sale_director sales_team.model_crm_tag sf_base.group_sale_director 1 1 1 0
access_sale_order sale.order sale.model_sale_order sf_base.group_plan_dispatch 1 1 0 0
74 access_res_partner_group_sale_salemanager access_sale_order res_partner_group_sale_salemanager sale.order base.model_res_partner sale.model_sale_order sf_base.group_sale_salemanager sf_base.group_plan_dispatch 1 0 1 1 0 0
75 access_res_partner_group_sale_director access_res_partner_group_sale_salemanager res_partner_group_sale_director res_partner_group_sale_salemanager base.model_res_partner sf_base.group_sale_director sf_base.group_sale_salemanager 1 0 1 0
76 access_res_partner_group_purchase access_res_partner_group_sale_director res_partner_group_purchase res_partner_group_sale_director base.model_res_partner sf_base.group_purchase sf_base.group_sale_director 1 0 1 0
77 access_sale_order_cancel_group_sale_salemanager sale_order_cancel_group_sale_salemanager sale.model_sale_order_cancel sf_base.group_sale_salemanager 1 1 1 0
78 access_sale_order_cancel_group_sale_director sale_order_cancel_group_sale_director sale.model_sale_order_cancel sf_base.group_sale_director 1 1 1 0
79 access_res_partner_group_purchase_director access_res_partner_group_purchase res_partner_group_purchase_director res_partner_group_purchase base.model_res_partner sf_base.group_purchase_director sf_base.group_purchase 1 0 1 0
80 access_sale_advance_payment_inv_group_sale_salemanager access_res_partner_group_purchase_director sale_advance_payment_inv_group_sale_salemanager res_partner_group_purchase_director sale.model_sale_advance_payment_inv base.model_res_partner sf_base.group_sale_salemanager sf_base.group_purchase_director 1 1 0 1 0
81 access_sale_advance_payment_inv_group_sale_director access_sale_advance_payment_inv_group_sale_salemanager sale_advance_payment_inv_group_sale_director sale_advance_payment_inv_group_sale_salemanager sale.model_sale_advance_payment_inv sf_base.group_sale_director sf_base.group_sale_salemanager 1 1 1 0

View File

@@ -8,24 +8,23 @@
<field name="arch" type="xml">
<field name="partner_id" position="replace">
<field name="partner_id" widget="res_partner_many2one" context="{'is_supplier': True }"/>
<field name="check_status" invisible="1"/>
</field>
<field name="currency_id" position="after">
<field name="check_status" invisible="1"/>
<!-- <field name="state"/>-->
<field name="remark" attrs="{'readonly': ['&amp;',('state', 'in', ['purchase']),('check_status','in',
['pending','approved'])]}"/>
</field>
<xpath expr="//form/header/button[@name='action_rfq_send'][1]" position="after">
<button name="sf_sale.action_purchase_order_check_wizard" string="审核" type="action"
context="{'default_order_id':active_id}" groups="sf_base.group_purchase_director"
attrs="{'invisible': ['&amp;',('check_status','in', ['approved',False,'fail']),('state', 'in', ['purchase'])]}"
attrs="{'invisible': ['&amp;',('check_status','in', ['approved','fail']),('state', 'in', ['purchase','draft'])]}"
class="oe_highlight"/>
</xpath>
<xpath expr="//form/header/button[@name='button_confirm'][2]" position="replace">
<button name="button_confirm" type="object" context="{'validate_analytic': True}"
string="确认订单" id="draft_confirm"
attrs="{'invisible': ['|','&amp;','&amp;', ('state', 'in', ['purchase']), ('check_status', 'in', ['approved']), ('date_approve', '!=', False),'&amp;', '&amp;',('state', 'in', ['purchase', 'draft']),('check_status', 'in', [False, 'pending', 'fail']),('date_approve', '=', False)]}"
attrs="{'invisible': ['|','&amp;','&amp;', ('state', 'in', ['purchase','draft']), ('check_status', 'in', ['approved']), ('date_approve', '!=', False),'&amp;', '&amp;',('state', 'in', ['purchase', 'draft']),('check_status', 'in', [False, 'pending', 'fail']),('date_approve', '=', False)]}"
/>
<button name="button_confirming" type="object"
string="确认订单"

View File

@@ -8,55 +8,93 @@
<field name="arch" type="xml">
<form position="attributes">
<attribute name="delete">false</attribute>
<attribute name="edit">false</attribute>
<!-- <attribute name="edit">false</attribute>-->
</form>
<field name="name" position="attributes">
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</field>
<field name="company_type" position="attributes">
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</field>
<field name="vat" position="after">
<field name="customer_rank" invisible="1"/>
<field name="supplier_rank" invisible="1"/>
</field>
<field name="vat" position="attributes">
<attribute name="required">1</attribute>
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</field>
<field name="email" position="replace">
<field name="email" attrs="{'required' : [('customer_rank','>', 0)]}"/>
<field name="email"
attrs="{'required' : [('customer_rank','>', 0)],'readonly': [('id','!=', False)]}"/>
</field>
<field name="mobile" position="attributes">
<attribute name="attrs">{'required': [('phone', '=', False)]}
<attribute name="attrs">{'required': [('phone', '=', False)],'readonly': [('id','!=', False)]}
</attribute>
</field>
<field name="phone" position="attributes">
<attribute name="attrs">{'required': [('mobile', '=', False)]}
<attribute name="attrs">{'required': [('mobile', '=', False)],'readonly': [('id','!=', False)]}
</attribute>
</field>
<field name="street" position="attributes">
<attribute name="attrs">{'required': [('supplier_rank','>', 0)]}
<attribute name="attrs">{'required': [('supplier_rank','>', 0)],'readonly': [('id','!=', False)]}
</attribute>
</field>
<field name="street2" position="attributes">
<attribute name="attrs">{'required': [('supplier_rank','>', 0)]}
<attribute name="attrs">{'required': [('supplier_rank','>', 0)],'readonly': [('id','!=', False)]}
</attribute>
</field>
<field name="city" position="attributes">
<attribute name="attrs">{'required': [('supplier_rank','>', 0)]}
<attribute name="attrs">{'required': [('supplier_rank','>', 0)],'readonly': [('id','!=', False)]}
</attribute>
</field>
<field name="country_id" position="attributes">
<attribute name="attrs">{'required': [('supplier_rank','>', 0)]}
<attribute name="attrs">{'required': [('supplier_rank','>', 0)],'readonly': [('id','!=', False)]}
</attribute>
</field>
<xpath expr="//group[@name='sale']/field[@name='user_id']" position="replace">
<field name="user_id" widget="many2one_avatar_user" context="{'is_sale': True }"
attrs="{'required' : [('customer_rank','>', 0)],'readonly': [('supplier_rank','>', 0)]}"/>
attrs="{'required' : [('customer_rank','>', 0)]}"/>
</xpath>
<field name="category_id" position="attributes">
<attribute name="required">1</attribute>
<!-- <attribute name="attrs">{'required': ['|',('customer_rank','>', 0),('supplier_rank','>', 0)]}</attribute>-->
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</field>
<field name="company_registry" position="attributes">
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</field>
<field name="ref" position="attributes">
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</field>
<field name="company_id" position="attributes">
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</field>
<field name="industry_id" position="attributes">
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</field>
<xpath expr="//field[@name='comment']" position="attributes">
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</xpath>
<xpath expr="//page[@name='internal_notes']/field[@name='comment']" position="attributes">
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</xpath>
<field name="zip" position="attributes">
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</field>
<field name="website" position="attributes">
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</field>
<field name="lang" position="attributes">
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</field>
<xpath expr="//field[@name='child_ids']" position="attributes">
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="view_partner_property_form_inherit_sf">
<field name="name">res.partner.property.form.inherit.sf</field>
<record model="ir.ui.view" id="view_partner_property_form_account_inherit_sf">
<field name="name">res.partner.account.form.inherit.sf</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="account.view_partner_property_form"/>
<field name="arch" type="xml">
@@ -65,6 +103,79 @@
widget="many2one_avatar_user"
attrs="{'required' : [('supplier_rank','>', 0)],'readonly': [('customer_rank','>', 0)]}"/>
</field>
<xpath expr="//field[@name='property_account_position_id']" position="attributes">
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</xpath>
<xpath expr="//field[@name='property_payment_term_id']" position="attributes">
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</xpath>
<xpath expr="//field[@name='property_supplier_payment_term_id']" position="attributes">
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</xpath>
<xpath expr="//field[@name='bank_ids']" position="attributes">
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="view_partner_delivery_form_inherit_sf">
<field name="name">res.partner.delivery.form.inherit.sf</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="delivery.view_partner_property_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='property_delivery_carrier_id']" position="attributes">
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="view_partner_stock_form_inherit_sf">
<field name="name">res.partner.stock.form.inherit.sf</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="stock.view_partner_stock_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='property_stock_customer']" position="attributes">
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</xpath>
<xpath expr="//field[@name='property_stock_supplier']" position="attributes">
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="view_partner_mrp_subcontracting_form_inherit_sf">
<field name="name">res.partner.mrp.subcontracting.form.inherit.sf</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="mrp_subcontracting.view_partner_mrp_subcontracting_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='property_stock_subcontractor']" position="attributes">
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="view_partner_purchase_form_inherit_sf">
<field name="name">res.partner.purchase.form.inherit.sf</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="purchase.view_partner_property_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='receipt_reminder_email']" position="attributes">
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</xpath>
<xpath expr="//field[@name='property_purchase_currency_id']" position="attributes">
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="view_partner_team_form_inherit_sf">
<field name="name">res.partner.team.form.inherit.sf</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="sales_team.res_partner_view_team"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='team_id'][2]" position="attributes">
<attribute name="attrs">{'readonly': [('id','!=', False)]}</attribute>
</xpath>
</field>
</record>

View File

@@ -87,8 +87,11 @@
attrs="{'invisible': ['|','&amp;',('check_status', '!=', 'approved'),('state', 'in', ['draft','cancel']),'&amp;','&amp;',('check_status', '=', 'approved'),('state', 'in', ['sale','cancel']),('schedule_status', 'not in', False)]}"/>
</xpath>
<xpath expr="//form/header/button[@name='action_cancel']" position="attributes">
<attribute name="attrs">{'invisible': ['|',('state', 'in', ['cancel']),('check_status', 'in',
[False,'approved'])]}
<attribute name="attrs">{'invisible': ['|','&amp;',('state', 'in',
['cancel','draft']),('check_status',
'in',
[False,'approved']),'&amp;','&amp;',('check_status', '=', 'approved'),('state', 'in',
['sale','cancel','draft']),('schedule_status', 'not in', False)]}
</attribute>
</xpath>
<xpath expr="//form/header/button[@name='action_draft']" position="attributes">

View File

@@ -1,6 +1,7 @@
# -*-coding:utf-8-*-
from . import models
from . import wizard
from . import controllers
from odoo import api, SUPERUSER_ID

View File

@@ -16,6 +16,7 @@
'security/ir.model.access.csv',
'wizard/wizard_view.xml',
'views/tool_base_views.xml',
'views/sf_maintenance_equipment.xml',
'views/menu_view.xml',
'views/tool_material_search.xml',
],

View File

@@ -0,0 +1 @@
from . import controllers

View File

@@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
import logging
import json
import base64
from odoo import http
from odoo.http import request
class Manufacturing_Connect(http.Controller):
@http.route('/AutoDeviceApi/FeedBackOut', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
cors="*")
def get_equipment_tool_Info(self, **kw):
"""
机床当前刀库实时信息
:param kw:
:return:
"""
logging.info('get_equipment_tool_Info:%s' % kw)
try:
datas = request.httprequest.data
ret = json.loads(datas)
ret = json.loads(ret['result'])
logging.info('DeviceId:%s' % ret)
equipment = request.env['maintenance.equipment'].sudo().search([('name', '=', ret['DeviceId'])])
res = {'Succeed': True, 'Datas': []}
if equipment:
for item in equipment:
data = []
for equipment_tool_id in item.product_template_ids:
functional_tool_id = self.env['sf.functional.cutting.tool.entity'].sudo().search(
[('code', '=', equipment_tool_id.tool_code)])
alarm_time = None
if functional_tool_id.functional_tool_status == '报警':
alarm_time = self.env['sf.functional.tool.warning'].sudo().search(
[('code', '=', equipment_tool_id.tool_code)]).alarm_time
equipment_tool = {
'RfidCode': None,
'ToolId': equipment_tool_id.code,
'ToolName': equipment_tool_id.functional_tool_name_id.name,
'MaxLife': equipment_tool_id.life_value_max,
'UseLife': equipment_tool_id.used_value,
'AddDatetime': equipment_tool_id.tool_install_time,
'State': functional_tool_id.functional_tool_status,
'WarnDate': alarm_time if alarm_time else False
}
data.append(equipment_tool)
res['Datas'].append({
'DeviceId': item.name,
'Data': data
})
except Exception as e:
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
logging.info('get_equipment_tool_Info error:%s' % e)
return json.JSONEncoder().encode(res)

View File

@@ -1,9 +1,12 @@
# -*- coding: utf-8 -*-
import re
import json
import requests
from datetime import timedelta
from odoo import fields, models, api
from odoo import SUPERUSER_ID
from odoo import fields, models, api
from odoo.exceptions import ValidationError
from odoo.addons.sf_base.commons.common import Common
class FunctionalCuttingToolEntity(models.Model):
@@ -12,6 +15,7 @@ class FunctionalCuttingToolEntity(models.Model):
tool_groups_id = fields.Many2one('sf.tool.groups', '刀具组', related='functional_tool_name_id.tool_groups_id')
code = fields.Char('编码', related='functional_tool_name_id.code')
rfid = fields.Char('rfid', readonly=True)
name = fields.Char(related='functional_tool_name_id.name')
functional_tool_name_id = fields.Many2one('sf.functional.tool.assembly', string='功能刀具名称', readonly=True)
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', readonly=True)
@@ -44,13 +48,13 @@ class FunctionalCuttingToolEntity(models.Model):
if record.barcode_id.quant_ids:
for quant_id in record.barcode_id.quant_ids:
if quant_id.inventory_quantity_auto_apply > 0:
record.current_location_id = quant_id.location_id
record.current_location = quant_id.location_id.name
record.sudo().current_location_id = quant_id.location_id
record.sudo().current_location = quant_id.location_id.name
if record.current_location_id:
record.get_location_num()
record.sudo().get_location_num()
else:
record.current_location_id = False
record.current_location = False
record.sudo().current_location_id = False
record.sudo().current_location = False
def get_location_num(self):
"""
@@ -128,24 +132,24 @@ class FunctionalCuttingToolEntity(models.Model):
print('111')
if record.cutting_tool_integral_model_id:
print(record.cutting_tool_integral_model_id)
record.suitable_machining_method_ids = record.cutting_tool_integral_model_id.suitable_machining_method_ids.ids
record.blade_tip_characteristics_id = record.cutting_tool_integral_model_id.blade_tip_characteristics_id.id
record.handle_type_id = record.cutting_tool_integral_model_id.handle_type_id.id
record.cutting_direction_ids = record.cutting_tool_integral_model_id.cutting_direction_ids.ids
record.suitable_coolant_ids = record.cutting_tool_integral_model_id.suitable_coolant_ids.ids
record.sudo().suitable_machining_method_ids = record.cutting_tool_integral_model_id.suitable_machining_method_ids.ids
record.sudo().blade_tip_characteristics_id = record.cutting_tool_integral_model_id.blade_tip_characteristics_id.id
record.sudo().handle_type_id = record.cutting_tool_integral_model_id.handle_type_id.id
record.sudo().cutting_direction_ids = record.cutting_tool_integral_model_id.cutting_direction_ids.ids
record.sudo().suitable_coolant_ids = record.cutting_tool_integral_model_id.suitable_coolant_ids.ids
print(record.cutting_tool_integral_model_id.blade_tip_characteristics_id.ids)
elif record.cutting_tool_blade_model_id:
record.suitable_machining_method_ids = record.cutting_tool_blade_model_id.suitable_machining_method_ids.ids
record.blade_tip_characteristics_id = record.cutting_tool_blade_model_id.blade_tip_characteristics_id.id
record.handle_type_id = record.cutting_tool_blade_model_id.handle_type_id.id
record.cutting_direction_ids = record.cutting_tool_blade_model_id.cutting_direction_ids.ids
record.suitable_coolant_ids = record.cutting_tool_blade_model_id.suitable_coolant_ids.ids
record.sudo().suitable_machining_method_ids = record.cutting_tool_blade_model_id.suitable_machining_method_ids.ids
record.sudo().blade_tip_characteristics_id = record.cutting_tool_blade_model_id.blade_tip_characteristics_id.id
record.sudo().handle_type_id = record.cutting_tool_blade_model_id.handle_type_id.id
record.sudo().cutting_direction_ids = record.cutting_tool_blade_model_id.cutting_direction_ids.ids
record.sudo().suitable_coolant_ids = record.cutting_tool_blade_model_id.suitable_coolant_ids.ids
else:
record.suitable_machining_method_ids = []
record.blade_tip_characteristics_id = None
record.handle_type_id = None
record.cutting_direction_ids = []
record.suitable_coolant_ids = []
record.sudo().suitable_machining_method_ids = []
record.sudo().blade_tip_characteristics_id = None
record.sudo().handle_type_id = None
record.sudo().cutting_direction_ids = []
record.sudo().suitable_coolant_ids = []
def _get_functional_tool_model_ids(self, functional_tool_model_code):
functional_tool_model_ids = []
@@ -174,12 +178,41 @@ class FunctionalCuttingToolEntity(models.Model):
('coarse_middle_thin', '=', self.coarse_middle_thin)]
return result
# ==========刀具组接口==========
def _register_functional_tool_groups(self, obj):
create_url = '/AutoDeviceApi/FeedBackOut'
sf_sync_config = self.env['res.config.settings'].get_values()
token = sf_sync_config['token']
sf_secret_key = sf_sync_config['sf_secret_key']
headers = Common.get_headers(obj, token, sf_secret_key)
strurl = sf_sync_config['sf_url'] + create_url
val = {
'ToolName': obj.name,
'GroupName': obj.tool_groups_id.name,
'ToolId': obj.code
}
kw = json.dumps(val, ensure_ascii=False)
r = requests.post(strurl, json={}, data={'kw': kw, 'token': token}, headers=headers)
ret = r.json()
if r == 200:
return "刀具组发送成功"
else:
raise ValidationError("刀具组发送失败")
# @api.model_create_multi
# def create(self, vals):
# obj = super(FunctionalCuttingToolEntity, self).create(vals)
# # 调用刀具组接口
# self._register_functional_tool_groups(obj)
# return obj
class FunctionalToolWarning(models.Model):
_name = 'sf.functional.tool.warning'
_description = '功能刀具预警'
code = fields.Char('编码', related='functional_tool_name_id.code')
rfid = fields.Char('rfid', related='functional_tool_name_id.rfid')
tool_groups_id = fields.Many2one('sf.tool.groups', '刀具组', related='functional_tool_name_id.tool_groups_id')
name = fields.Char('名称', invisible=True, readonly=True, related='functional_tool_name_id.name')
# 机床信息
@@ -240,7 +273,7 @@ class FunctionalToolWarning(models.Model):
class StockMoveLine(models.Model):
_inherit = 'stock.move.line'
_description = '功能刀具出入库记录'
# _order = 'install_tool_time desc'
_order = 'date desc'
functional_tool_name_id = fields.Many2one('sf.functional.tool.assembly', string='功能刀具名称')
functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', store=True,
@@ -250,6 +283,7 @@ class StockMoveLine(models.Model):
knife_tip_r_angle = fields.Float(string='刀尖R角(mm)', related='functional_tool_name_id.knife_tip_r_angle')
install_tool_time = fields.Datetime("刀具组装时间", related='functional_tool_name_id.tool_loading_time')
code = fields.Char('编码', related='functional_tool_name_id.code')
rfid = fields.Char('rfid', related='functional_tool_name_id.rfid')
tool_groups_id = fields.Many2one('sf.tool.groups', '刀具组', related='functional_tool_name_id.tool_groups_id')
@api.model
@@ -310,9 +344,9 @@ class RealTimeDistributionOfFunctionalTools(models.Model):
def _compute_name(self):
for obj in self:
if obj.tool_groups_id:
obj.name = '%s-D%sR%s' % (obj.tool_groups_id.name, obj.diameter, obj.knife_tip_r_angle)
obj.sudo().name = '%s-D%sR%s' % (obj.tool_groups_id.name, obj.diameter, obj.knife_tip_r_angle)
else:
obj.name = None
obj.sudo().name = None
@api.constrains('min_stock_num', 'max_stock_num')
def _check_stock_num(self):
@@ -330,26 +364,26 @@ class RealTimeDistributionOfFunctionalTools(models.Model):
for tool in self:
if tool:
# 判断功能刀具组装单是否已经完成
tool.estimate_functional_tool_assembly_ids(tool)
tool.get_stock_num(tool)
tool.sudo().estimate_functional_tool_assembly_ids(tool)
tool.sudo().get_stock_num(tool)
# 计算当前库存量
tool.tool_stock_total = tool.tool_stock_num + tool.side_shelf_num + tool.on_tool_stock_num
tool.sudo().tool_stock_total = tool.tool_stock_num + tool.side_shelf_num + tool.on_tool_stock_num
# 如果当前库存量小于最低库存量,计算批次补货量
tool.open_batch_replenishment_num(tool)
tool.sudo().open_batch_replenishment_num(tool)
def open_batch_replenishment_num(self, tool):
"""
计算批次补货量
"""
if tool.tool_stock_total < tool.min_stock_num:
tool.batch_replenishment_num = tool.max_stock_num - tool.tool_stock_total
tool.sudo().batch_replenishment_num = tool.max_stock_num - tool.tool_stock_total
# 根据判断创建功能刀具组装单
if not tool.sf_functional_tool_assembly_ids and re.match(r'^\d+$', str(tool.id)):
for i in range(tool.batch_replenishment_num):
tool.create_functional_tool_assembly(tool)
tool.sudo().create_functional_tool_assembly(tool)
print(i, ": ", tool.sf_functional_tool_assembly_ids)
else:
tool.batch_replenishment_num = 0
tool.sudo().batch_replenishment_num = 0
def create_functional_tool_assembly(self, tool):
"""
@@ -369,7 +403,7 @@ class RealTimeDistributionOfFunctionalTools(models.Model):
'whether_standard_knife': tool.whether_standard_knife,
'reason_for_applying': '安全库存',
})
tool.sf_functional_tool_assembly_ids = [(4, functional_tool_assembly.id)]
tool.sudo().sf_functional_tool_assembly_ids = [(4, functional_tool_assembly.id)]
def estimate_functional_tool_assembly_ids(self, tool):
"""
@@ -378,24 +412,24 @@ class RealTimeDistributionOfFunctionalTools(models.Model):
for sf_functional_tool_assembly_id in tool.sf_functional_tool_assembly_ids:
if sf_functional_tool_assembly_id.assemble_status == '0':
return False
tool.sf_functional_tool_assembly_ids = []
tool.sudo().sf_functional_tool_assembly_ids = []
def get_stock_num(self, tool):
"""
计算刀具房数量、线边刀库数量、机内刀库数量
"""
if tool:
tool.tool_stock_num = 0
tool.side_shelf_num = 0
tool.on_tool_stock_num = 0
tool.sudo().tool_stock_num = 0
tool.sudo().side_shelf_num = 0
tool.sudo().on_tool_stock_num = 0
if tool.sf_functional_cutting_tool_entity_ids:
for cutting_tool in tool.sf_functional_cutting_tool_entity_ids:
if cutting_tool.tool_room_num > 0:
tool.tool_stock_num += 1
tool.sudo().tool_stock_num += 1
elif cutting_tool.line_edge_knife_library_num > 0:
tool.side_shelf_num += 1
tool.sudo().side_shelf_num += 1
elif cutting_tool.machine_knife_library_num > 0:
tool.on_tool_stock_num += 1
tool.sudo().on_tool_stock_num += 1
def create_or_edit_safety_stock(self, vals, sf_functional_cutting_tool_entity_ids):
"""
@@ -445,6 +479,7 @@ class MachineTableToolChangingApply(models.Model):
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', store=True,
domain=[('product_id.name', '=', '功能刀具')],
related='functional_tool_name_id.barcode_id')
rfid = fields.Char('rfid', related='functional_tool_name_id.rfid')
functional_tool_name_id = fields.Many2one('sf.functional.tool.assembly', domain=[('assemble_status', '=', '1')],
string='功能刀具名称')
functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', store=True,
@@ -471,7 +506,7 @@ class MachineTableToolChangingApply(models.Model):
reason_for_applying = fields.Char(string='申请原因', readonly=True)
remark = fields.Char(string='备注说明', readonly=False)
status = fields.Selection([('0', '未操作'), ('1', '换刀申请'), ('2', '已转移'), ('3', '已组装')],
status = fields.Selection([('0', '未操作'), ('1', '已申请换刀'), ('2', '已转移'), ('3', '已组装')],
string='操作状态', default='0')
sf_functional_tool_assembly_id = fields.Many2one('sf.functional.tool.assembly', '功能刀具组装单', readonly=True)
@@ -480,21 +515,21 @@ class MachineTableToolChangingApply(models.Model):
def _compute_functional_tool_status(self):
for record in self:
if record.alarm_value < record.used_value:
record.functional_tool_status = '报警'
record.sudo().functional_tool_status = '报警'
else:
record.functional_tool_status = '正常'
record.sudo().functional_tool_status = '正常'
@api.depends('maintenance_equipment_id')
def _compute_machine_table_type_id(self):
for record in self:
if record:
record.production_line_id = record.maintenance_equipment_id.production_line_id.id
record.machine_table_type_id = record.maintenance_equipment_id.category_id.id
record.machine_tool_code = record.maintenance_equipment_id.code
record.sudo().production_line_id = record.maintenance_equipment_id.production_line_id.id
record.sudo().machine_table_type_id = record.maintenance_equipment_id.category_id.id
record.sudo().machine_tool_code = record.maintenance_equipment_id.code
else:
record.production_line_id = None
record.machine_table_type_id = None
record.machine_tool_code = None
record.sudo().production_line_id = None
record.sudo().machine_table_type_id = None
record.sudo().machine_tool_code = None
@api.constrains("cutter_spacing_code_id")
def _check_cutter_spacing_code_id(self):
@@ -594,16 +629,16 @@ class CAMWorkOrderProgramKnifePlan(models.Model):
_name = 'sf.cam.work.order.program.knife.plan'
_description = 'CAM工单程序用刀计划'
name = fields.Char(string='工单任务编号', readonly=False)
cam_procedure_code = fields.Char(string='CAM程序编号', readonly=False)
cam_cutter_spacing_code = fields.Char(string='CAM刀位号', readonly=False)
name = fields.Char('工单任务编号')
cam_procedure_code = fields.Char('程序名')
filename = fields.Char('文件')
cam_cutter_spacing_code = fields.Char('刀号')
tool_position_interface_type = fields.Selection(
[('BT刀柄式', 'BT刀柄式'), ('SK刀柄式', 'SK刀柄式'), ('HSK刀柄式', 'HSK刀柄式'),
('CAT刀柄式', 'CAT刀柄式'), ('ISO刀盘式', 'ISO刀盘式'), ('DIN刀盘式', 'DIN刀盘式'),
('直装固定式', '直装固定式')], string='刀位接口型号')
production_line_id = fields.Many2one('sf.production.line', string='生产线', readonly=False,
group_expand='_read_group_names')
machine_table_name_id = fields.Many2one('maintenance.equipment', string='机床名称', readonly=False,
production_line_id = fields.Many2one('sf.production.line', string='生产线', group_expand='_read_group_names')
machine_table_name_id = fields.Many2one('maintenance.equipment', string='机床名称',
domain="[('production_line_id', '=', production_line_id)]")
machine_table_name = fields.Char(string='机台号', readonly=True, related='machine_table_name_id.name')
cutter_spacing_code_id = fields.Many2one('maintenance.equipment.tool', string='刀位号', required=True,
@@ -616,8 +651,9 @@ class CAMWorkOrderProgramKnifePlan(models.Model):
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号',
domain=[('product_id.name', '=', '功能刀具')])
functional_tool_name = fields.Char(string='功能刀具名称', required=True)
functional_tool_name = fields.Char(string='功能刀具名称', compute='_compute_functional_tool_name')
functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', readonly=False)
tool_groups_id = fields.Many2one('sf.tool.groups', '刀具组')
diameter = fields.Integer(string='刀具直径(mm)', readonly=False)
tool_included_angle = fields.Float(string='刀尖R角(mm)', readonly=False)
tool_loading_length = fields.Float(string='总长度(mm)', readonly=False)
@@ -629,12 +665,28 @@ class CAMWorkOrderProgramKnifePlan(models.Model):
L_D = fields.Float(string='L/D值', readonly=False)
clearance_length = fields.Float(string='避空长(mm)', readonly=False)
required_cutting_time = fields.Integer(string='需切削时长', readonly=False)
process_type = fields.Char('加工类型')
margin_x_y = fields.Float('余量_X/Y')
margin_z = fields.Float('余量_Z')
finish_depth = fields.Float('加工深度')
shank_model = fields.Char('刀柄型号')
estimated_processing_time = fields.Char('预计加工时间')
plan_execute_status = fields.Selection([('0', '待下发'), ('1', '执行中'), ('2', '已完成')],
string='计划执行状态', default='0', readonly=False)
sf_functional_tool_assembly_id = fields.Many2one('sf.functional.tool.assembly', '功能刀具组装', readonly=True)
@api.depends('diameter', 'tool_included_angle', 'tool_groups_id')
def _compute_functional_tool_name(self):
for obj in self:
if obj.tool_groups_id:
obj.functional_tool_name = '%s-D%sR%s' % (
obj.tool_groups_id.name, obj.diameter,
obj.tool_included_angle)
else:
obj.functional_tool_name = None
@api.model
def _read_group_names(self, categories, domain, order):
names = categories._search([], order=order, access_rights_uid=SUPERUSER_ID)
@@ -646,27 +698,34 @@ class CAMWorkOrderProgramKnifePlan(models.Model):
:return:
"""
record = self.env['sf.functional.tool.assembly'].create({
'barcode_id': self.barcode_id.id,
'functional_tool_name_id': self.functional_tool_name_id.id,
'functional_tool_name': self.functional_tool_name,
'functional_tool_type_id': self.functional_tool_type_id.id,
'tool_groups_id': self.tool_groups_id.id,
'functional_tool_diameter': self.diameter,
'functional_tool_length': self.tool_loading_length,
'loading_task_source': '0',
'coarse_middle_thin': None,
'tool_loading_length': None,
'applicant': self.env.user.name,
'reason_for_applying': self.reason_for_applying,
'use_tool_time': self.need_knife_time,
'knife_tip_r_angle': self.tool_included_angle,
'tool_loading_length': self.tool_loading_length,
'functional_tool_length': self.extension_length,
'effective_length': self.effective_length,
'whether_standard_knife': self.whether_standard_knife,
'coarse_middle_thin': self.coarse_middle_thin,
'new_former': self.new_former,
'production_line_name_id': self.production_line_id.id,
'machine_tool_name_id': self.machine_table_name_id.id,
'machine_tool_code': self.cam_procedure_code,
'cutter_spacing_code': self.cam_cutter_spacing_code,
'cutter_spacing_code_id': self.env['maintenance.equipment.tool'].sudo().search(
[('code', '=', self.cam_cutter_spacing_code), ('equipment_id', '=', self.machine_table_name_id.id)]).id,
'loading_task_source': '0',
'applicant': self.env.user.name,
'use_tool_time': self.need_knife_time,
'reason_for_applying': '工单用刀',
'sf_cam_work_order_program_knife_plan_id': self.id
})
self.sf_functional_tool_assembly_id = record.id
# 将计划执行状态改为执行中
self.env['sf.cam.work.order.program.knife.plan'].search(
[('barcode_id', '=', self.barcode_id.id)]).write(
[('name', '=', self.name), ('functional_tool_name', '=', self.functional_tool_name)]).write(
{'plan_execute_status': '1',
'applicant': self.env.user.name})
@@ -676,16 +735,50 @@ class CAMWorkOrderProgramKnifePlan(models.Model):
:return:
"""
self.env['sf.functional.tool.assembly'].search(
[('barcode_id', '=', self.barcode_id.id),
[('assembly_order_code', '=', self.sf_functional_tool_assembly_id.assembly_order_code),
('loading_task_source', '=', '0')]).unlink()
# 将计划执行状态改为待执行,同时清除申请人、功能刀具组装字段数据
self.env['sf.cam.work.order.program.knife.plan'].search(
[('barcode_id', '=', self.barcode_id.id)]).write(
[('name', '=', self.name), ('functional_tool_name', '=', self.functional_tool_name)]).write(
{'plan_execute_status': '0',
'applicant': None,
'sf_functional_tool_assembly_id': None})
def create_cam_work_plan(self, cnc_processing):
"""
根据传入的工单信息查询是否有需要的功能刀具如果没有则生成CAM工单程序用刀计划
"""
status = False
if cnc_processing.functional_tool_type_id and cnc_processing.cutting_tool_name:
functional_tools = self.env['sf.real.time.distribution.of.functional.tools'].sudo().search(
[('sf_cutting_tool_type_id', '=', cnc_processing.functional_tool_type_id.id),
('name', '=', cnc_processing.cutting_tool_name)])
if functional_tools:
for functional_tool in functional_tools:
if functional_tool.on_tool_stock_num == 0:
# self.env['sf.cnc.processing'].register_cnc_processing(cnc_processing)
if functional_tool.tool_stock_num == 0 and functional_tool.side_shelf_num == 0:
status = True
else:
status = True
if status:
self.env['sf.cam.work.order.program.knife.plan'].sudo().create({
'name': cnc_processing.workorder_id.production_id.name,
'cam_procedure_code': cnc_processing.program_name,
'filename': cnc_processing.cnc_id.name,
'functional_tool_type_id': cnc_processing.functional_tool_type_id.id,
'functional_tool_name': cnc_processing.cutting_tool_name,
'cam_cutter_spacing_code': cnc_processing.cutting_tool_no,
'process_type': cnc_processing.processing_type,
'margin_x_y': float(cnc_processing.margin_x_y),
'margin_z': float(cnc_processing.margin_z),
'finish_depth': float(cnc_processing.depth_of_processing_z),
'extension_length': float(cnc_processing.cutting_tool_extension_length),
'shank_model': cnc_processing.cutting_tool_handle_type,
'estimated_processing_time': cnc_processing.estimated_processing_time,
})
class FunctionalToolAssembly(models.Model):
_name = 'sf.functional.tool.assembly'
@@ -698,6 +791,7 @@ class FunctionalToolAssembly(models.Model):
obj.name = obj.after_assembly_functional_tool_name
code = fields.Char('功能刀具编码', readonly=True)
rfid = fields.Char('rfid', readonly=True)
tool_groups_id = fields.Many2one('sf.tool.groups', '刀具组', readonly=True)
name = fields.Char(string='名称', readonly=True, compute='_compute_name')
assembly_order_code = fields.Char(string='组装单编码', readonly=True)

View File

@@ -1,9 +1,22 @@
from odoo import models, api
from odoo import models, api, fields
class SfMaintenanceEquipmentTool(models.Model):
_inherit = 'maintenance.equipment.tool'
functional_tool_name_id = fields.Many2one('sf.functional.cutting.tool.entity', '功能刀具名称')
image = fields.Binary('图片', related='functional_tool_name_id.image')
tool_code = fields.Char('功能刀具编码', related='functional_tool_name_id.code')
functional_tool_type = fields.Char('功能刀具类型', related='functional_tool_name_id.sf_cutting_tool_type_id.name')
tool_groups = fields.Char('刀具组', related='functional_tool_name_id.tool_groups_id.name')
diameter = fields.Integer('直径(mm)', related='functional_tool_name_id.functional_tool_diameter')
knife_tip_r_angle = fields.Float('刀尖R角(mm)', related='functional_tool_name_id.knife_tip_r_angle')
life_value_max = fields.Integer('最大寿命值(min)', related='functional_tool_name_id.max_lifetime_value')
alarm_value = fields.Integer('报警值(min)', related='functional_tool_name_id.alarm_value')
used_value = fields.Integer('已使用值(min)', related='functional_tool_name_id.used_value')
tool_install_time = fields.Datetime('机内装刀时间')
@api.model_create_multi
def create(self, vals_list):
tools = super().create(vals_list)

View File

@@ -0,0 +1,38 @@
import json
import requests
from odoo import fields, models, api
from odoo.exceptions import ValidationError
from odoo.addons.sf_base.commons.common import Common
class CNCprocessing(models.Model):
_inherit = 'sf.cnc.processing'
_description = 'CNC加工用刀检测'
# ==========MES装刀指令接口==========
def register_cnc_processing(self, cnc_processing):
create_url = '/AutoDeviceApi/FeedBackOut'
sf_sync_config = self.env['res.config.settings'].get_values()
token = sf_sync_config['token']
sf_secret_key = sf_sync_config['sf_secret_key']
headers = Common.get_headers(self, token, sf_secret_key)
strurl = sf_sync_config['sf_url'] + create_url
val = {
'DeviceId': cnc_processing.workorder_id.machine_tool_name,
'RfidCode': None,
'ToolId': cnc_processing.cutting_tool_no
}
kw = json.dumps(val, ensure_ascii=False)
r = requests.post(strurl, json={}, data={'kw': kw, 'token': token}, headers=headers)
ret = r.json()
if r == 200:
return "MES装刀指令发送成功"
else:
raise ValidationError("MES装刀指令发送失败")
@api.model_create_multi
def create(self, vals):
obj = super(CNCprocessing, self).create(vals)
# 调用CAM工单程序用刀计划创建方法
self.env['sf.cam.work.order.program.knife.plan'].create_cam_work_plan(obj)
return obj

View File

@@ -1,20 +1,34 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_sf_functional_cutting_tool_entity,sf.functional.cutting.tool.entity,model_sf_functional_cutting_tool_entity,base.group_user,1,1,1,1
access_sf_functional_tool_warning,sf.functional.tool.warning,model_sf_functional_tool_warning,base.group_user,1,1,1,1
access_sf_real_time_distribution_of_functional_tools,sf.real.time.distribution.of.functional.tools,model_sf_real_time_distribution_of_functional_tools,base.group_user,1,1,1,1
access_sf_functional_cutting_tool_entity,sf.functional.cutting.tool.entity,model_sf_functional_cutting_tool_entity,sf_base.group_sf_tool_user,1,1,1,1
access_sf_functional_tool_warning,sf.functional.tool.warning,model_sf_functional_tool_warning,sf_base.group_sf_tool_user,1,1,1,1
access_sf_real_time_distribution_of_functional_tools,sf.real.time.distribution.of.functional.tools,model_sf_real_time_distribution_of_functional_tools,sf_base.group_sf_tool_user,1,1,1,1
access_sf_cam_work_order_program_knife_plan,sf.cam.work.order.program.knife.plan,model_sf_cam_work_order_program_knife_plan,base.group_user,1,1,1,1
access_sf_machine_table_tool_changing_apply,sf.machine.table.tool.changing.apply,model_sf_machine_table_tool_changing_apply,base.group_user,1,1,1,1
access_sf_cam_work_order_program_knife_plan,sf.cam.work.order.program.knife.plan,model_sf_cam_work_order_program_knife_plan,sf_base.group_sf_tool_user,1,1,1,1
access_sf_machine_table_tool_changing_apply,sf.machine.table.tool.changing.apply,model_sf_machine_table_tool_changing_apply,sf_base.group_sf_tool_user,1,1,1,1
access_sf_tool_change_requirement_information,sf.tool.change.requirement.information,model_sf_tool_change_requirement_information,base.group_user,1,1,1,1
access_sf_tool_transfer_request_information,sf.tool.transfer.request.information,model_sf_tool_transfer_request_information,base.group_user,1,1,1,1
access_sf_functional_tool_assembly,sf.functional.tool.assembly,model_sf_functional_tool_assembly,base.group_user,1,1,1,1
access_sf_functional_tool_assembly_order,sf.functional.tool.assembly.order,model_sf_functional_tool_assembly_order,base.group_user,1,1,1,1
access_sf_tool_material_search,sf.tool.material.search,model_sf_tool_material_search,base.group_user,1,1,1,1
access_sf_tool_change_requirement_information,sf.tool.change.requirement.information,model_sf_tool_change_requirement_information,sf_base.group_sf_tool_user,1,1,1,1
access_sf_tool_transfer_request_information,sf.tool.transfer.request.information,model_sf_tool_transfer_request_information,sf_base.group_sf_tool_user,1,1,1,1
access_sf_functional_tool_assembly,sf.functional.tool.assembly,model_sf_functional_tool_assembly,sf_base.group_sf_tool_user,1,1,1,1
access_sf_functional_tool_assembly_order,sf.functional.tool.assembly.order,model_sf_functional_tool_assembly_order,sf_base.group_sf_tool_user,1,1,1,1
access_sf_tool_material_search,sf.tool.material.search,model_sf_tool_material_search,sf_base.group_sf_tool_user,1,1,1,1
access_sf_functional_cutting_tool_entity_group_plan_dispatch,sf.functional.cutting.tool.entity,model_sf_functional_cutting_tool_entity,sf_base.group_plan_dispatch,1,0,0,0
access_sf_functional_tool_warning_group_plan_dispatch,sf.functional.tool.warning,model_sf_functional_tool_warning,sf_base.group_plan_dispatch,1,0,0,0
access_sf_real_time_distribution_of_functional_tools_group_plan_dispatch,sf.real.time.distribution.of.functional.tools,model_sf_real_time_distribution_of_functional_tools,sf_base.group_plan_dispatch,1,0,0,0
access_sf_cam_work_order_program_knife_plan_group_plan_dispatch,sf.cam.work.order.program.knife.plan,model_sf_cam_work_order_program_knife_plan,sf_base.group_plan_dispatch,1,0,0,0
access_sf_machine_table_tool_changing_apply_group_plan_dispatch,sf.machine.table.tool.changing.apply,model_sf_machine_table_tool_changing_apply,sf_base.group_plan_dispatch,1,0,0,0
access_sf_tool_change_requirement_information_group_plan_dispatch,sf.tool.change.requirement.information,model_sf_tool_change_requirement_information,sf_base.group_plan_dispatch,1,0,0,0
access_sf_tool_transfer_request_information_group_plan_dispatch,sf.tool.transfer.request.information,model_sf_tool_transfer_request_information,sf_base.group_plan_dispatch,1,0,0,0
access_sf_functional_tool_assembly_group_plan_dispatch,sf.functional.tool.assembly,model_sf_functional_tool_assembly,sf_base.group_plan_dispatch,1,0,0,0
access_sf_functional_tool_assembly_order_group_plan_dispatch,sf.functional.tool.assembly.order,model_sf_functional_tool_assembly_order,sf_base.group_plan_dispatch,1,0,0,0
access_sf_tool_material_search_group_plan_dispatch,sf.tool.material.search,model_sf_tool_material_search,sf_base.group_plan_dispatch,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_sf_functional_cutting_tool_entity sf.functional.cutting.tool.entity model_sf_functional_cutting_tool_entity base.group_user sf_base.group_sf_tool_user 1 1 1 1
3 access_sf_functional_tool_warning sf.functional.tool.warning model_sf_functional_tool_warning base.group_user sf_base.group_sf_tool_user 1 1 1 1
4 access_sf_real_time_distribution_of_functional_tools sf.real.time.distribution.of.functional.tools model_sf_real_time_distribution_of_functional_tools base.group_user sf_base.group_sf_tool_user 1 1 1 1
5 access_sf_cam_work_order_program_knife_plan sf.cam.work.order.program.knife.plan model_sf_cam_work_order_program_knife_plan base.group_user sf_base.group_sf_tool_user 1 1 1 1
6 access_sf_machine_table_tool_changing_apply sf.machine.table.tool.changing.apply model_sf_machine_table_tool_changing_apply base.group_user sf_base.group_sf_tool_user 1 1 1 1
7 access_sf_tool_change_requirement_information sf.tool.change.requirement.information model_sf_tool_change_requirement_information base.group_user sf_base.group_sf_tool_user 1 1 1 1
8 access_sf_tool_transfer_request_information sf.tool.transfer.request.information model_sf_tool_transfer_request_information base.group_user sf_base.group_sf_tool_user 1 1 1 1
9 access_sf_functional_tool_assembly sf.functional.tool.assembly model_sf_functional_tool_assembly base.group_user sf_base.group_sf_tool_user 1 1 1 1
10 access_sf_functional_tool_assembly_order sf.functional.tool.assembly.order model_sf_functional_tool_assembly_order base.group_user sf_base.group_sf_tool_user 1 1 1 1
11 access_sf_tool_material_search sf.tool.material.search model_sf_tool_material_search base.group_user sf_base.group_sf_tool_user 1 1 1 1
12 access_sf_functional_cutting_tool_entity_group_plan_dispatch sf.functional.cutting.tool.entity model_sf_functional_cutting_tool_entity sf_base.group_plan_dispatch 1 0 0 0
13 access_sf_functional_tool_warning_group_plan_dispatch sf.functional.tool.warning model_sf_functional_tool_warning sf_base.group_plan_dispatch 1 0 0 0
14 access_sf_real_time_distribution_of_functional_tools_group_plan_dispatch sf.real.time.distribution.of.functional.tools model_sf_real_time_distribution_of_functional_tools sf_base.group_plan_dispatch 1 0 0 0
15 access_sf_cam_work_order_program_knife_plan_group_plan_dispatch sf.cam.work.order.program.knife.plan model_sf_cam_work_order_program_knife_plan sf_base.group_plan_dispatch 1 0 0 0
16 access_sf_machine_table_tool_changing_apply_group_plan_dispatch sf.machine.table.tool.changing.apply model_sf_machine_table_tool_changing_apply sf_base.group_plan_dispatch 1 0 0 0
17 access_sf_tool_change_requirement_information_group_plan_dispatch sf.tool.change.requirement.information model_sf_tool_change_requirement_information sf_base.group_plan_dispatch 1 0 0 0
18 access_sf_tool_transfer_request_information_group_plan_dispatch sf.tool.transfer.request.information model_sf_tool_transfer_request_information sf_base.group_plan_dispatch 1 0 0 0
19 access_sf_functional_tool_assembly_group_plan_dispatch sf.functional.tool.assembly model_sf_functional_tool_assembly sf_base.group_plan_dispatch 1 0 0 0
20 access_sf_functional_tool_assembly_order_group_plan_dispatch sf.functional.tool.assembly.order model_sf_functional_tool_assembly_order sf_base.group_plan_dispatch 1 0 0 0
21 access_sf_tool_material_search_group_plan_dispatch sf.tool.material.search model_sf_tool_material_search sf_base.group_plan_dispatch 1 0 0 0
22
23
24
25
26
27
28
29
30
31
32
33
34

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- 设备增加刀具库位table-->
<record id="sf_maintenance_equipment_tool_view_form" model="ir.ui.view">
<field name="name">sf_manufacturing_equipment.form</field>
<field name="model">maintenance.equipment</field>
<field name="inherit_id" ref="sf_manufacturing.sf_manufacturing_hr_equipment_view_form"/>
<field name="arch" type="xml">
<xpath expr="//page[@name='sf_equipment_product_template']" position="replace">
<page string="标准刀库" name="sf_equipment_product_template"
attrs="{'invisible': [('equipment_type', '!=', '机床')]}">
<field name='product_template_ids'>
<tree editable='bottom'>
<field name="code"/>
<field name="tool_code"/>
<field name="functional_tool_type"/>
<field name="functional_tool_name_id"/>
<field name="image" widget="image"/>
<field name="tool_groups"/>
<field name="diameter"/>
<field name="knife_tip_r_angle"/>
<field name="life_value_max"/>
<field name="alarm_value"/>
<field name="used_value"/>
<field name="tool_install_time"/>
</tree>
</field>
</page>
</xpath>
</field>
</record>
</odoo>

View File

@@ -7,7 +7,8 @@
<field name="model">sf.functional.cutting.tool.entity</field>
<field name="arch" type="xml">
<tree string="功能刀具列表" create="0" edit="0" delete="0">
<field name="barcode_id"/>
<field name="barcode_id" invisible="1"/>
<field name="rfid"/>
<field name="functional_tool_name_id"/>
<field name="image" widget='image'/>
<field name="tool_groups_id"/>
@@ -43,7 +44,7 @@
</header>
<sheet>
<div class="oe_button_box" name="button_box">
<button class="oe_stat_button"
<button class="oe_stat_button" groups="sf_base.group_sf_mrp_user"
name="open_functional_tool_warning"
icon="fa-list-ul"
type="object">
@@ -53,7 +54,7 @@
</span>
</div>
</button>
<button class="oe_stat_button"
<button class="oe_stat_button" groups="sf_base.group_sf_mrp_user"
name="open_stock_move_line"
icon="fa-list-ul"
type="object">
@@ -63,7 +64,7 @@
</span>
</div>
</button>
<button class="oe_stat_button"
<button class="oe_stat_button" groups="sf_base.group_sf_mrp_user"
name="open_safety_stock"
icon="fa-list-ul"
type="object">
@@ -76,12 +77,13 @@
</div>
<div class="oe_title">
<h1>
<field name="barcode_id" readonly="1" nolabel="True"/>
<field name="code" readonly="1" nolabel="True"/>
</h1>
</div>
<group>
<group>
<field name="code" readonly="1"/>
<field name="barcode_id" invisible="1"/>
<field name="rfid" readonly="1"/>
<field name="functional_tool_name_id" invisible="False"
placeholder="请输入20字以内的名称"/>
<field name="sf_cutting_tool_type_id"/>
@@ -178,6 +180,7 @@
<field name="arch" type="xml">
<search>
<field name="barcode_id"/>
<field name="rfid"/>
<field name="functional_tool_name_id"/>
<field name="image" widget='image'/>
<field name="functional_tool_diameter"/>
@@ -224,7 +227,8 @@
<field name="maintenance_equipment_id" optional="hide"/>
<field name="machine_tool_code"/>
<field name="cutter_spacing_code_id"/>
<field name="barcode_id"/>
<field name="barcode_id" invisible="1"/>
<field name="rfid"/>
<field name="functional_tool_name_id"/>
<field name="diameter"/>
<field name="knife_tip_r_angle"/>
@@ -250,6 +254,7 @@
<field name="machine_tool_code"/>
<field name="cutter_spacing_code_id"/>
<field name="barcode_id"/>
<field name="rfid"/>
<field name="functional_tool_name_id"/>
<field name="diameter"/>
<field name="knife_tip_r_angle"/>
@@ -287,7 +292,7 @@
<field name="name">功能刀具安全库存</field>
<field name="model">sf.real.time.distribution.of.functional.tools</field>
<field name="arch" type="xml">
<tree create="1" edit="1" delete="0">
<tree>
<field name="name"/>
<field name="sf_cutting_tool_type_id" invisible="True"/>
<field name="tool_groups_id"/>
@@ -310,7 +315,7 @@
<field name="name">功能刀具安全库存</field>
<field name="model">sf.real.time.distribution.of.functional.tools</field>
<field name="arch" type="xml">
<form create="0" edit="1" delete="0">
<form>
<sheet>
<div class="oe_title">
<h1>
@@ -376,7 +381,7 @@
<page string="刀具信息">
<field name="sf_functional_cutting_tool_entity_ids" widget="many2many">
<tree edit="0" create="0" delete="0">
<field name="barcode_id"/>
<field name="rfid"/>
<field name="functional_tool_name_id"/>
<field name="new_former"/>
<field name="tool_loading_length" string="总长度(mm)"/>
@@ -435,7 +440,8 @@
<field name="arch" type="xml">
<tree string="功能刀具出入库记录" create="0" edit="0" delete="0">
<field name="reference" string="单据号"/>
<field name="lot_id" string="功能刀具序列号"/>
<field name="lot_id" invisible="1"/>
<field name="rfid"/>
<field name="functional_tool_name_id" string="功能刀具名称"/>
<field name="diameter"/>
<field name="knife_tip_r_angle"/>
@@ -457,6 +463,7 @@
<search>
<field name="reference"/>
<field name="lot_id"/>
<field name="rfid"/>
<field name="functional_tool_name_id"/>
<field name="diameter"/>
<field name="knife_tip_r_angle"/>
@@ -510,6 +517,7 @@
<field name="machine_table_type_id" invisible="1"/>
<field name="barcode_id" invisible="1"/>
<field name="rfid" invisible="1"/>
<field name="functional_tool_type_id" invisible="1"/>
<field name="tool_position_interface_type" invisible="1"/>
<field name="extension_length" invisible="1"/>
@@ -529,6 +537,7 @@
'default_machine_tool_code': machine_tool_code,
'default_cutter_spacing_code_id': cutter_spacing_code_id,
'default_barcode_id': barcode_id,
'default_rfid': rfid,
'default_functional_tool_name': functional_tool_name,
'default_functional_tool_type_id': functional_tool_type_id,
'default_tool_position_interface_type': tool_position_interface_type,
@@ -551,8 +560,8 @@
'default_replacement_extension_length': extension_length,
'default_replacement_effective_length': effective_length,
}"
attrs="{'invisible': [('status', '!=', '0')]}"
class="btn-primary"
attrs="{'invisible': ['|',('status', '!=', '0'), ('functional_tool_name_id', '=', False)]}"
class="btn-primary" groups="sf_base.group_sf_mrp_user"
/>
<button string="转移"
name="%(sf_tool_management.sf_tool_transfer_request_information_act)d"
@@ -566,6 +575,7 @@
'default_machine_tool_code': machine_tool_code,
'default_cutter_spacing_code_id': cutter_spacing_code_id,
'default_barcode_id': barcode_id,
'default_rfid': rfid,
'default_functional_tool_name': functional_tool_name,
'default_functional_tool_type_id': functional_tool_type_id,
'default_tool_position_interface_type': tool_position_interface_type,
@@ -578,13 +588,15 @@
'default_extension_length': extension_length,
'default_effective_length': effective_length,
}"
class="btn-primary"
class="btn-primary" groups="sf_base.group_sf_mrp_user"
attrs="{'invisible': ['|',('status', '!=', '0'), ('functional_tool_name_id', '=', False)]}"
/>
<button string="撤回换刀申请" name="revocation_1" type="object" class="btn-primary"
attrs="{'invisible': [('status', '!=', '1')]}" confirm="是否确认撤回换刀申请"/>
attrs="{'invisible': [('status', '!=', '1')]}" groups="sf_base.group_sf_mrp_user"
confirm="是否确认撤回换刀申请"/>
<button string="撤回转移" name="revocation_2" type="object" class="btn-primary"
attrs="{'invisible': [('status', '!=', '2')]}" confirm="是否确认撤回转移"/>
attrs="{'invisible': [('status', '!=', '2')]}" groups="sf_base.group_sf_mrp_user"
confirm="是否确认撤回转移"/>
</tree>
</field>
</record>
@@ -607,6 +619,7 @@
'default_machine_tool_code': machine_tool_code,
'default_cutter_spacing_code_id': cutter_spacing_code_id,
'default_barcode_id': barcode_id,
'default_rfid': rfid,
'default_functional_tool_name': functional_tool_name,
'default_functional_tool_type_id': functional_tool_type_id,
'default_tool_position_interface_type': tool_position_interface_type,
@@ -629,8 +642,8 @@
'default_replacement_extension_length': extension_length,
'default_replacement_effective_length': effective_length,
}"
attrs="{'invisible': [('status', '!=', '0')]}"
class="btn-primary"
attrs="{'invisible': ['|',('status', '!=', '0'), ('functional_tool_name_id', '=', False)]}"
class="btn-primary" groups="sf_base.group_sf_mrp_user"
/>
<button string="转移"
name="%(sf_tool_management.sf_tool_transfer_request_information_act)d"
@@ -642,6 +655,7 @@
'default_machine_tool_code': machine_tool_code,
'default_cutter_spacing_code_id': cutter_spacing_code_id,
'default_barcode_id': barcode_id,
'default_rfid': rfid,
'default_functional_tool_name': functional_tool_name,
'default_functional_tool_type_id': functional_tool_type_id,
'default_tool_position_interface_type': tool_position_interface_type,
@@ -654,12 +668,15 @@
'default_extension_length': extension_length,
'default_effective_length': effective_length,
}"
class="btn-primary"
class="btn-primary" groups="sf_base.group_sf_mrp_user"
attrs="{'invisible': ['|',('status', '!=', '0'),('functional_tool_name_id', '=', False)]}"/>
<button string="撤回换刀申请" name="revocation_1" type="object" class="btn-primary"
attrs="{'invisible': [('status', '!=', '1')]}" confirm="是否确认撤回换刀申请"/>
<button string="撤回转移" name="revocation_2" type="object" class="btn-primary"
attrs="{'invisible': [('status', '!=', '1')]}" groups="sf_base.group_sf_mrp_user"
confirm="是否确认撤回换刀申请"/>
<button string="撤回转移" name="revocation_2" type="object" groups="sf_base.group_sf_mrp_user"
class="btn-primary"
attrs="{'invisible': [('status', '!=', '2')]}" confirm="是否确认撤回转移"/>
<field name="status" widget="statusbar" statusbar_visible="0,1,2,3"/>
</header>
<field name="functional_tool_status" string="状态" invisible="True"/>
<sheet>
@@ -686,7 +703,8 @@
<page string="功能刀具信息">
<group>
<group>
<field name="barcode_id"/>
<field name="barcode_id" invisible="1"/>
<field name="rfid"/>
<field name="code"/>
<field name="functional_tool_name_id"
options="{'no_create': True, 'no_quick_create': True}"/>
@@ -722,6 +740,7 @@
<field name="machine_table_type_id"/>
<field name="cutter_spacing_code_id" optional="hide"/>
<field name="barcode_id" invisible="1"/>
<field name="rfid" invisible="1"/>
<field name="functional_tool_name_id"/>
<field name="diameter"/>
<field name="knife_tip_r_angle"/>
@@ -756,21 +775,29 @@
<tree>
<field name="name" string="工单编码"/>
<field name="cam_procedure_code"/>
<field name="filename"/>
<field name="functional_tool_name" string="刀具名称"/>
<field name="cam_cutter_spacing_code"/>
<field name="diameter" optional="hide"/>
<field name="tool_included_angle" optional="hide"/>
<field name="process_type"/>
<field name="margin_x_y"/>
<field name="margin_z"/>
<field name="finish_depth"/>
<field name="extension_length" string="刀具伸出长度(mm)"/>
<field name="shank_model"/>
<field name="estimated_processing_time"/>
<field name="need_knife_time"/>
<field name="applicant_time"/>
<field name="plan_execute_status"/>
<field name="production_line_id" invisible="1"/>
<field name="machine_table_name_id" invisible="1"/>
<field name="machine_table_name"/>
<field name="functional_tool_name"/>
<field name="diameter"/>
<field name="tool_included_angle"/>
<field name="need_knife_time"/>
<field name="applicant"/>
<field name="applicant_time"/>
<field name="plan_execute_status" invisible="0"/>
<!-- <button string="申请装刀" name="apply_for_tooling" type="object" class="btn-primary"-->
<!-- attrs="{'invisible': [('plan_execute_status', '!=', '0')]}" confirm="是否确认申请装刀"/>-->
<!-- <button string="撤回" name="revocation" type="object" class="btn-primary"-->
<!-- attrs="{'invisible': [('plan_execute_status', '!=', '1')]}" confirm="是否确认撤回装刀"/>-->
<field name="machine_table_name" invisible="1"/>
<button string="申请装刀" name="apply_for_tooling" type="object" class="btn-primary"
attrs="{'invisible': [('plan_execute_status', '!=', '0')]}" confirm="是否确认申请装刀"/>
<button string="撤回" name="revocation" type="object" class="btn-primary"
attrs="{'invisible': [('plan_execute_status', '!=', '1')]}" confirm="是否确认撤回装刀"/>
</tree>
</field>
</record>
@@ -780,13 +807,13 @@
<field name="model">sf.cam.work.order.program.knife.plan</field>
<field name="arch" type="xml">
<form>
<!-- <header>-->
<!-- <button string="申请装刀" name="apply_for_tooling" type="object" class="btn-primary"-->
<!-- attrs="{'invisible': [('plan_execute_status', '!=', '0')]}" confirm="是否确认申请装刀"/>-->
<!-- <button string="撤回" name="revocation" type="object" class="btn-primary"-->
<!-- attrs="{'invisible': [('plan_execute_status', '!=', '1')]}" confirm="是否确认撤回装刀"/>-->
<!-- <field name="plan_execute_status" widget="statusbar" statusbar_visible="0,1,2"/>-->
<!-- </header>-->
<header>
<button string="申请装刀" name="apply_for_tooling" type="object" class="btn-primary"
attrs="{'invisible': [('plan_execute_status', '!=', '0')]}" confirm="是否确认申请装刀"/>
<button string="撤回" name="revocation" type="object" class="btn-primary"
attrs="{'invisible': [('plan_execute_status', '!=', '1')]}" confirm="是否确认撤回装刀"/>
<field name="plan_execute_status" widget="statusbar" statusbar_visible="0,1,2"/>
</header>
<sheet>
<div class="oe_title">
@@ -797,35 +824,48 @@
<group>
<group>
<field name="cam_procedure_code"/>
<field name="filename"/>
<field name="production_line_id"/>
<field name="machine_table_name_id" string="机台号"/>
<field name="cam_cutter_spacing_code"/>
<field name="tool_position_interface_type" placeholder="请选择"/>
<field name="production_line_id" placeholder="请选择"/>
<field name="machine_table_name_id" placeholder="请选择"/>
<field name="machine_table_name"/>
<field name="cutter_spacing_code_id" placeholder="请选择"/>
<field name="whether_standard_knife"/>
<field name="need_knife_time"/>
<field name="applicant"/>
<field name="applicant_time"/>
<field name="reason_for_applying"/>
<field name="tool_position_interface_type"/>
<field name="sf_functional_tool_assembly_id" string="组装单"/>
</group>
<group>
<field name="barcode_id" invisible="1"/>
<field name="process_type"/>
<field name="margin_x_y"/>
<field name="margin_z"/>
<field name="finish_depth"/>
<field name="estimated_processing_time"/>
<field name="need_knife_time"/>
<field name="applicant_time"/>
</group>
</group>
<notebook>
<page string="刀具信息">
<group>
<group>
<field name="functional_tool_name"/>
<field name="functional_tool_type_id" placeholder="请选择"/>
<field name="functional_tool_type_id"/>
<field name="tool_groups_id"/>
<field name="diameter"/>
<field name="tool_included_angle"/>
<field name="new_former"/>
<field name="coarse_middle_thin"/>
<field name="whether_standard_knife"/>
</group>
<group>
<field name="shank_model"/>
<field name="tool_loading_length"/>
<field name="extension_length"/>
<field name="effective_length"/>
<field name="new_former"/>
<field name="coarse_middle_thin"/>
<field name="required_cutting_time"/>
<field name="L_D"/>
<field name="clearance_length"/>
<field name="required_cutting_time"/>
</group>
</group>
</page>
</notebook>
</sheet>
</form>
</field>
@@ -837,20 +877,25 @@
<search>
<field name="name" string="工单编码"/>
<field name="cam_procedure_code"/>
<field name="filename"/>
<field name="functional_tool_name" string="刀具名称"/>
<field name="cam_cutter_spacing_code"/>
<field name="machine_table_name_id" invisible="1"/>
<field name="production_line_id" invisible="1"/>
<field name="machine_table_name"/>
<field name="functional_tool_name"/>
<field name="diameter"/>
<field name="tool_included_angle"/>
<field name="diameter" optional="hide"/>
<field name="tool_included_angle" optional="hide"/>
<field name="process_type"/>
<field name="margin_x_y"/>
<field name="margin_z"/>
<field name="finish_depth"/>
<field name="extension_length" string="刀具伸出长度(mm)"/>
<field name="shank_model"/>
<field name="estimated_processing_time"/>
<field name="need_knife_time"/>
<field name="applicant"/>
<field name="applicant_time"/>
<field name="plan_execute_status" invisible="0"/>
<field name="plan_execute_status"/>
<searchpanel>
<field name="production_line_id" string="生产线" enable_counters="1" icon="fa-filter"/>
<field name="machine_table_name_id" string="CNC机床" enable_counters="1" icon="fa-filter"/>
<field name="functional_tool_type_id" string="功能刀具类型" enable_counters="1"
icon="fa-filter"/>
</searchpanel>
</search>
</field>
@@ -920,9 +965,10 @@
'default_use_tool_time':use_tool_time,
'default_reason_for_applying':reason_for_applying,
}"
attrs="{'invisible': [('assemble_status', '!=', '0')]}"
attrs="{'invisible': [('assemble_status', '!=', '0')]}" groups="sf_base.group_sf_mrp_user"
class="btn-primary"/>
<button string="组装单打印" name="assemble_single_print" type="object"
groups="sf_base.group_sf_mrp_user"
attrs="{'invisible': [('assemble_status', '=', '0')]}" class="btn-primary"
confirm="是否确认打印组装单"/>
</tree>
@@ -937,7 +983,7 @@
<header>
<button string="组装"
name="%(sf_tool_management.sf_functional_tool_assembly_order_act)d"
type="action"
type="action" groups="sf_base.group_sf_mrp_user"
context="{'default_name':name,
'default_assembly_order_code':assembly_order_code,
'default_production_line_name_id':production_line_name_id,
@@ -961,9 +1007,11 @@
class="btn-primary"/>
<button string="打印二维码" name="automatic_printing_of_QR_code" type="object"
groups="sf_base.group_sf_mrp_user"
attrs="{'invisible': [('assemble_status', '=', '0')]}" class="btn-primary"
confirm="是否确认打印二维码"/>
<button string="组装单打印" name="assemble_single_print" type="object"
groups="sf_base.group_sf_mrp_user"
attrs="{'invisible': [('assemble_status', '=', '0')]}" class="btn-primary"
confirm="是否确认打印组装单"/>
<field name="assemble_status" widget="statusbar" statusbar_visible="0,1"/>
@@ -995,7 +1043,8 @@
<group col="1">
<group>
<group>
<field name="barcode_id"/>
<field name="barcode_id" invisible="True"/>
<field name="rfid" string="功能刀具rfid"/>
<field name="code"/>
<field name="after_assembly_functional_tool_name"
string="功能刀具名称"/>

View File

@@ -9,6 +9,7 @@ class ToolChangeRequirementInformation(models.TransientModel):
_description = '换刀需求信息'
code = fields.Char('编码', readonly=True)
rfid = fields.Char('rfid', readonly=True)
tool_groups_id = fields.Many2one('sf.tool.groups', '刀具组', readonly=True)
name = fields.Char('名称', related='maintenance_equipment_id.name', store=True, readonly=True)
maintenance_equipment_id = fields.Many2one('maintenance.equipment', string='CNC机床', readonly=True)
@@ -41,7 +42,7 @@ class ToolChangeRequirementInformation(models.TransientModel):
replacement_tool_setting_length = fields.Float(string='待换刀具总长度(mm)', required=True)
replacement_extension_length = fields.Float(string='待换刀具伸出长(mm)')
replacement_effective_length = fields.Float(string='待换刀具有效长(mm)')
replacement_tool_coarse_middle_thin = fields.Selection([("1", ""), ('2', ''), ('3', '')], requirded=True,
replacement_tool_coarse_middle_thin = fields.Selection([("1", ""), ('2', ''), ('3', '')], required=True,
string='待换刀具粗/中/精', default='3')
replacement_max_lifetime_value = fields.Integer(string='待换刀具最大寿命值(min)')
@@ -303,6 +304,10 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
if not records:
raise ValidationError('扫描的条形码数据不存在,请重新扫描!')
for record_stock_lot in records:
if record_stock_lot.quant_ids[-1].location_id.name == '刀具组装位置':
raise ValidationError('该刀具物料已使用,请重新选择!!!')
elif record_stock_lot.quant_ids[-1].location_id.name not in '刀具房':
raise ValidationError('该刀具物料未入库,请重新选择!!!')
tool_material_name = record_stock_lot.product_id.cutting_tool_material_id.name
if tool_material_name == '整体式刀具':
record.integral_code_id = record_stock_lot.id
@@ -321,6 +326,7 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
# 组装功能刀具参数信息
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号')
rfid = fields.Char('rfid', required=True)
tool_code = fields.Char(string='功能刀具编码', readonly=True, compute='_compute_tool_code')
after_assembly_functional_tool_name = fields.Char(string='组装后功能刀具名称', compute='_compute_name')
after_assembly_functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model',
@@ -522,6 +528,7 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
return {
'barcode_id': stock_lot.id,
'code': self.tool_code,
'rfid': self.rfid,
'tool_groups_id': self.tool_groups_id.id,
'integral_code_id': self.integral_code_id.id,
'blade_code_id': self.blade_code_id.id,
@@ -558,6 +565,7 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
return {
'barcode_id': stock_lot.id,
'code': self.tool_code,
'rfid': self.rfid,
'tool_groups_id': self.tool_groups_id.id,
'functional_tool_name_id': functional_tool_assembly_id.id,
'sf_cutting_tool_type_id': self.after_assembly_functional_tool_type_id.id,

View File

@@ -24,7 +24,8 @@
<field name="whether_standard_knife"/>
</group>
<group>
<field name="barcode_id"/>
<field name="barcode_id" invisible="1"/>
<field name="rfid"/>
<field name="code"/>
<field name="functional_tool_name"/>
<field name="functional_tool_type_id"/>
@@ -334,6 +335,7 @@
<group>
<field name="barcode_id" invisible="True"/>
<field name="tool_code" readonly="True"/>
<field name="rfid" placeholder="请输入rfid码"/>
<field name="after_assembly_functional_tool_name" string="功能刀具名称"/>
<field name="after_assembly_functional_tool_type_id" string="功能刀具类型"
options="{'no_create': True, 'no_quick_create': True}"/>

View File

@@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
import datetime
import logging
from odoo import api, fields, models
from odoo import api, fields, models, _
from odoo.osv import expression
from odoo.exceptions import UserError
class SfLocation(models.Model):
@@ -279,7 +280,7 @@ class ShelfLocation(models.Model):
('空闲', '空闲'),
('占用', '占用'),
('禁用', '禁用')
], string='货位状态', default='空闲')
], string='货位状态', default='空闲', readonly=True)
# product_id = fields.Many2one('product.template', string='产品')
product_id = fields.Many2one('product.product', string='产品', compute='_compute_product_id', readonly=True)
product_sn_id = fields.Many2one('stock.lot', string='产品序列号')
@@ -287,6 +288,14 @@ class ShelfLocation(models.Model):
hide_shelf = fields.Boolean(compute='_compute_hide_what', string='隐藏货架')
hide_location = fields.Boolean(compute='_compute_hide_what', string='隐藏货位')
# 修改货位状态为禁用
def action_location_status_disable(self):
self.location_status = '禁用'
# 修改货位状态为空闲
def action_location_status_enable(self):
self.location_status = '空闲'
@api.onchange('shelf_location_id')
def _onchange_shelf_location_id(self):
"""
@@ -305,8 +314,8 @@ class ShelfLocation(models.Model):
"""
for record in self:
if record.product_sn_id:
record.product_id = record.product_sn_id.product_id
record.location_status = '占用'
record.sudo().product_id = record.product_sn_id.product_id
record.sudo().location_status = '占用'
else:
record.product_id = False
# record.location_status = '空闲'
@@ -318,12 +327,12 @@ class ShelfLocation(models.Model):
:return:
"""
for record in self:
record.hide_shelf = False
record.hide_location = False
record.sudo().hide_shelf = False
record.sudo().hide_location = False
if record.location_type and record.location_type == '货架':
record.hide_shelf = True
record.sudo().hide_shelf = True
elif record.location_type and record.location_type == '货位':
record.hide_location = True
record.sudo().hide_location = True
else:
pass

View File

@@ -97,7 +97,7 @@ access_stock_lot_label_layout_user,lot.label.layout.user,stock.model_lot_label_l
access_stock_replenish_option,stock.replenishment.option,stock.model_stock_replenishment_option,sf_warehouse.group_sf_stock_user,1,1,1,0
access_mrp_production,mrp.production,mrp.model_mrp_production,sf_warehouse.group_sf_stock_user,1,1,1,0
access_sf_shelf_location_group_plan_dispatch,sf.shelf.location,model_sf_shelf_location,sf_base.group_plan_dispatch,1,1,0,0
access_sf_shelf_location_group_plan_dispatch,sf.shelf.location,model_sf_shelf_location,sf_base.group_plan_dispatch,1,0,0,0
access_stock_move,stock.move,stock.model_stock_move,sf_base.group_plan_dispatch,1,1,1,0
access_stock_picking,stock.picking,stock.model_stock_picking,sf_base.group_plan_dispatch,1,0,0,0
access_stock_lot_group_plan_dispatch,stock.lot,stock.model_stock_lot,sf_base.group_plan_dispatch,1,0,0,0
@@ -127,6 +127,15 @@ access_stock_lot_group_purchase_director,stock_lot_group_purchase_director,stock
access_mrp_workcenter_productivity_group_purchase,mrp_workcenter_productivity_group_purchase,mrp.model_mrp_workcenter_productivity,sf_base.group_purchase,1,0,0,0
access_mrp_workcenter_productivity_group_purchase_director,mrp_workcenter_productivity_group_purchase_director,mrp.model_mrp_workcenter_productivity,sf_base.group_purchase_director,1,0,0,0
access_sf_cutting_speed_group_sf_stock_manager,sf_cutting_speed_group_sf_stock_manager,sf_base.model_sf_cutting_speed,sf_warehouse.group_sf_stock_manager,1,0,1,0
access_sf_feed_per_tooth_group_sf_stock_manager,sf_feed_per_tooth_group_sf_stock_manager,sf_base.model_sf_feed_per_tooth,sf_warehouse.group_sf_stock_manager,1,0,1,0
access_sf_cutting_tool_material_group_sf_stock_manager,sf_cutting_tool_material_group_sf_stock_manager,sf_base.model_sf_cutting_tool_material,sf_warehouse.group_sf_stock_manager,1,0,1,0
access_sf_cutting_tool_standard_library_group_sf_stock_manager,sf_cutting_tool_standard_library_group_sf_stock_manager,sf_base.model_sf_cutting_tool_standard_library,sf_warehouse.group_sf_stock_manager,1,0,1,0
access_sf_tool_materials_basic_parameters_group_sf_stock_manager,sf_tool_materials_basic_parameters_group_sf_stock_manager,sf_base.model_sf_tool_materials_basic_parameters,sf_warehouse.group_sf_stock_manager,1,0,1,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
97 access_sf_shelf_location_group_plan_dispatch sf.shelf.location model_sf_shelf_location sf_base.group_plan_dispatch 1 1 0 0 0
98 access_stock_move stock.move stock.model_stock_move sf_base.group_plan_dispatch 1 1 1 0
99 access_stock_picking stock.picking stock.model_stock_picking sf_base.group_plan_dispatch 1 0 0 0
100 access_stock_lot_group_plan_dispatch stock.lot stock.model_stock_lot sf_base.group_plan_dispatch 1 0 0 0
101 access_stock_lot_group_plan_director stock.lot stock.model_stock_lot sf_base.group_plan_director 1 1 1 0
102 access_stock_warehouse_orderpoint stock.warehouse.orderpoint stock.model_stock_warehouse_orderpoint sf_base.group_plan_dispatch 1 1 0 0
103 access_product_product product.product product.model_product_product sf_base.group_plan_dispatch 1 0 0 0
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

View File

@@ -62,19 +62,30 @@
<field name="inherit_id" ref="stock.view_picking_form"/>
<field name="arch" type="xml">
<xpath expr="//form//header//button[@name='action_cancel']" position="replace">
<button name="action_cancel" attrs="{'invisible': [('state', 'not in', ('assigned', 'confirmed', 'draft', 'waiting'))]}" string="取消" groups="sf_warehouse.group_sf_stock_user" type="object" data-hotkey="z"/>
<button name="action_cancel"
attrs="{'invisible': [('state', 'not in', ('assigned', 'confirmed', 'draft', 'waiting'))]}"
string="取消" groups="sf_warehouse.group_sf_stock_user" type="object" data-hotkey="z"/>
</xpath>
<xpath expr="//form//header//button[@name='do_unreserve']" position="replace">
<button name="do_unreserve" string="取消保留" groups="sf_warehouse.group_sf_stock_user" type="object" attrs="{'invisible': ['|', '|', '|', ('picking_type_code', '=', 'incoming'), ('immediate_transfer', '=', True), '&amp;', ('state', '!=', 'assigned'), ('move_type', '!=', 'one'), '&amp;', ('state', 'not in', ('assigned', 'confirmed')), ('move_type', '=', 'one')]}" data-hotkey="w"/>
<button name="do_unreserve" string="取消保留" groups="sf_warehouse.group_sf_stock_user"
type="object"
attrs="{'invisible': ['|', '|', '|', ('picking_type_code', '=', 'incoming'), ('immediate_transfer', '=', True), '&amp;', ('state', '!=', 'assigned'), ('move_type', '!=', 'one'), '&amp;', ('state', 'not in', ('assigned', 'confirmed')), ('move_type', '=', 'one')]}"
data-hotkey="w"/>
</xpath>
<xpath expr="//form//header//button[@name='button_scrap']" position="replace">
<button name="button_scrap" groups="sf_warehouse.group_sf_stock_user" type="object" string="报废" attrs="{'invisible': ['|', '&amp;', ('picking_type_code', '=', 'incoming'), ('state', '!=', 'done'), '&amp;', ('picking_type_code', '=', 'outgoing'), ('state', '=', 'done')]}" data-hotkey="y"/>
<button name="button_scrap" groups="sf_warehouse.group_sf_stock_user" type="object" string="报废"
attrs="{'invisible': ['|', '&amp;', ('picking_type_code', '=', 'incoming'), ('state', '!=', 'done'), '&amp;', ('picking_type_code', '=', 'outgoing'), ('state', '=', 'done')]}"
data-hotkey="y"/>
</xpath>
<xpath expr="//form//header//button[@name='action_assign']" position="replace">
<button name="action_assign" attrs="{'invisible': [('show_check_availability', '=', False)]}" string="检查可用量" type="object" class="oe_highlight" groups="sf_warehouse.group_sf_stock_user" data-hotkey="q"/>
<button name="action_assign" attrs="{'invisible': [('show_check_availability', '=', False)]}"
string="检查可用量" type="object" class="oe_highlight"
groups="sf_warehouse.group_sf_stock_user" data-hotkey="q"/>
</xpath>
<xpath expr="//form//header//button[@name='%(stock.act_stock_return_picking)d']" position="replace">
<button name="%(stock.act_stock_return_picking)d" string="退回" attrs="{'invisible': [('state', '!=', 'done')]}" type="action" groups="sf_warehouse.group_sf_stock_user" data-hotkey="k"/>
<button name="%(stock.act_stock_return_picking)d" string="退回"
attrs="{'invisible': [('state', '!=', 'done')]}" type="action"
groups="sf_warehouse.group_sf_stock_user" data-hotkey="k"/>
</xpath>
</field>
@@ -86,7 +97,25 @@
<field name="inherit_id" ref="stock.stock_scrap_form_view"/>
<field name="arch" type="xml">
<xpath expr="//header//button[@name='action_validate']" position="replace">
<button name="action_validate" states="draft" string="Validate" type="object" class="oe_highlight" context="{'not_unlink_on_discard': True}" data-hotkey="v" groups="sf_warehouse.group_sf_stock_user"/>
<button name="action_validate" states="draft" string="Validate" type="object" class="oe_highlight"
context="{'not_unlink_on_discard': True}" data-hotkey="v"
groups="sf_warehouse.group_sf_stock_user"/>
</xpath>
</field>
</record>
<record id="sf_vpicktree" model="ir.ui.view">
<field name="name">sf.vpicktree</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.vpicktree"/>
<field name="arch" type="xml">
<xpath expr="//header//button[@name='do_unreserve']" position="replace">
<button name="do_unreserve" type="object" string="取消保留"
groups="sf_warehouse.group_sf_stock_user"/>
</xpath>
<xpath expr="//header//button[@name='action_assign']" position="replace">
<button name="action_assign" type="object" string="检查可用量"
groups="sf_warehouse.group_sf_stock_user"/>
</xpath>
</field>
</record>

View File

@@ -55,8 +55,13 @@
<form string="Shelf Location">
<header>
<field name="location_status" invisible="1"/>
<button string="生成货位" name="create_location" type="object" class="oe_highlight"
attrs="{'invisible': [('hide_shelf', '=', False)]}"/>
<button string="禁用货位" name="action_location_status_disable" type="object" class="oe_highlight"
attrs="{'invisible': ['|', ('hide_shelf', '=', True), ('location_status', '!=', '空闲')]}"/>
<button string="启用货位" name="action_location_status_enable" type="object" class="oe_highlight"
attrs="{'invisible': ['|', ('hide_shelf', '=', True), ('location_status', '!=', '禁用')]}"/>
<!-- <button name="%(shelf_location_kanban_action_id)d"-->
<!-- type="action"-->

View File

@@ -13,20 +13,23 @@ class StockMoveLine(models.Model):
picking_location_dest_id = fields.Many2one(related='picking_id.location_dest_id')
product_stock_quant_ids = fields.One2many('stock.quant', compute='_compute_product_stock_quant_ids')
product_packaging_id = fields.Many2one(related='move_id.product_packaging_id')
product_packaging_uom_qty = fields.Float('Packaging Quantity', compute='_compute_product_packaging_uom_qty', help="Quantity of the Packaging in the UoM of the Stock Move Line.")
product_packaging_uom_qty = fields.Float('Packaging Quantity', compute='_compute_product_packaging_uom_qty',
help="Quantity of the Packaging in the UoM of the Stock Move Line.")
is_completed = fields.Boolean(compute='_compute_is_completed', help="Check if the quantity done matches the demand")
@api.depends('product_id', 'product_id.stock_quant_ids')
def _compute_product_stock_quant_ids(self):
for line in self:
line.product_stock_quant_ids = line.product_id.stock_quant_ids.filtered(lambda q: q.company_id in self.env.companies and q.location_id.usage == 'internal')
line.product_stock_quant_ids = line.product_id.stock_quant_ids.filtered(
lambda q: q.company_id in self.env.companies and q.location_id.usage == 'internal')
def _compute_dummy_id(self):
self.dummy_id = ''
def _compute_product_packaging_uom_qty(self):
for sml in self:
sml.product_packaging_uom_qty = sml.product_packaging_id.product_uom_id._compute_quantity(sml.product_packaging_id.qty, sml.product_uom_id)
sml.product_packaging_uom_qty = sml.product_packaging_id.product_uom_id._compute_quantity(
sml.product_packaging_id.qty, sml.product_uom_id)
@api.depends('qty_done')
def _compute_is_completed(self):

View File

@@ -1,5 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_stock_move_line_detailed_operation_tree_inherit_quality" model="ir.ui.view">
<field name="name">stock.move.line.operations.tree.inherit</field>
<field name="model">stock.move.line</field>
<field name="inherit_id" ref="stock.view_stock_move_line_detailed_operation_tree"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='product_uom_id']" position="after">
<field name="check_state" invisible="1"/>
<button type="object" class="btn-info" name="action_open_quality_check_wizard" icon="fa-check"
attrs="{'invisible': [('check_state', '!=', 'in_progress')]}" title="Quality Check"/>
<button type="object" class="btn-danger" name="action_open_quality_check_wizard" icon="fa-check"
attrs="{'invisible': [('check_state', '!=', 'fail')]}" title="Quality Check"/>
<button type="object" class="btn-success" name="action_open_quality_check_wizard" icon="fa-check"
attrs="{'invisible': [('check_state', '!=', 'pass')]}" title="Quality Check"/>
</xpath>
</field>
</record>
<record id="stock_move_line_product_selector" model="ir.ui.view">
<field name="name">stock.product.selector</field>
@@ -31,9 +47,14 @@
<div class="col-12 my-2 d-flex align-items-baseline">
<i class="fa fa-fw fa-lg fa-cube me-3" title="Quantity"/>
<field name="is_completed" invisible="1"/>
<field name="qty_done" class="w-100 w-md-50 text-end o_qty_done_field_completed" attrs="{'invisible': [('is_completed', '=', False)]}" options="{'type': 'number'}" placeholder="Quantity"/>
<field name="qty_done" class="w-100 w-md-50 text-end o_qty_done_field_not_completed" attrs="{'invisible':[('is_completed', '!=', False)]}" options="{'type': 'number'}" placeholder="Quantity"/>
<field name="reserved_uom_qty" widget="set_reserved_qty_button" field_to_set="qty_done" attrs="{'invisible': [('reserved_uom_qty', '=', 0)]}"/>
<field name="qty_done" class="w-100 w-md-50 text-end o_qty_done_field_completed"
attrs="{'invisible': [('is_completed', '=', False)]}" options="{'type': 'number'}"
placeholder="Quantity"/>
<field name="qty_done" class="w-100 w-md-50 text-end o_qty_done_field_not_completed"
attrs="{'invisible':[('is_completed', '!=', False)]}" options="{'type': 'number'}"
placeholder="Quantity"/>
<field name="reserved_uom_qty" widget="set_reserved_qty_button" field_to_set="qty_done"
attrs="{'invisible': [('reserved_uom_qty', '=', 0)]}"/>
</div>
<div class="col-6 my-2 d-flex align-items-baseline" groups="uom.group_uom"
attrs="{'invisible': [('reserved_uom_qty', '!=', 0)]}">
@@ -57,7 +78,8 @@
domain="[('id', 'child_of', picking_location_id)]"
options="{'no_create': True}"/>
</div>
<div class="col-12 col-md-6 my-2 d-flex align-items-baseline" attrs="{'invisible': [('picking_code', '=', 'outgoing')]}">
<div class="col-12 col-md-6 my-2 d-flex align-items-baseline"
attrs="{'invisible': [('picking_code', '=', 'outgoing')]}">
<i class="fa fa-fw fa-lg fa-long-arrow-right me-3" title="Destination Location"/>
<field name="location_dest_id" placeholder="Source Location"
domain="[('id', 'child_of', picking_location_dest_id)]"
@@ -90,7 +112,8 @@
<field name="picking_location_dest_id" invisible="1"/>
<div class="row" groups="stock.group_production_lot">
<div class="col-12 col-md-6 my-2 d-flex align-items-baseline">
<i class="fa fa-fw fa-lg fa-barcode me-3" title="Serial/Lot Number" attrs="{'invisible': [('tracking', 'not in', ['serial', 'lot'])]}"/>
<i class="fa fa-fw fa-lg fa-barcode me-3" title="Serial/Lot Number"
attrs="{'invisible': [('tracking', 'not in', ['serial', 'lot'])]}"/>
<field name="lot_name" placeholder="Serial/Lot Number"
attrs="{'invisible': ['|', '|', ('tracking', '=', 'none'), ('picking_type_use_create_lots', '=', False), ('picking_type_use_existing_lots', '=', True)]}"
/>
@@ -104,7 +127,8 @@
<div class="row row-long">
<div class="col-12 my-2 d-flex">
<i class="fa fa-fw fa-lg fa-cubes me-3" title="Locations"/>
<field name="product_stock_quant_ids" context="{'kanban_view_ref': 'stock_barcode.stock_quant_barcode_kanban_2', 'tree_view_ref': 'stock_barcode.view_stock_quant_tree'}"/>
<field name="product_stock_quant_ids"
context="{'kanban_view_ref': 'stock_barcode.stock_quant_barcode_kanban_2', 'tree_view_ref': 'stock_barcode.view_stock_quant_tree'}"/>
</div>
</div>
<div class="fixed-bottom">
@@ -115,7 +139,8 @@
<div class="o_barcode_control d-flex" attrs="{'invisible': [('reserved_uom_qty', '!=', 0)]}">
<button string="Delete" class="btn btn-danger text-uppercase o_delete"
name="unlink" type="object">
<i class="fa fa-trash-o"/> Delete
<i class="fa fa-trash-o"/>
Delete
</button>
</div>
</div>
@@ -134,7 +159,9 @@
<templates>
<t t-name="kanban-box">
<div>
<strong><field name="product_id"/></strong>
<strong>
<field name="product_id"/>
</strong>
<div class="row">
<div class="col-6">
<field name="lot_id" groups="stock.group_production_lot"/>
@@ -159,19 +186,27 @@
<t t-name="kanban-box">
<div t-attf-class="oe_kanban_global_click">
<div class="mb4">
<strong><field name="location_id"/></strong>
<strong>
<field name="location_id"/>
</strong>
</div>
<div class="mb4">
<field name="quantity"/> <field name="product_uom_id" groups="uom.group_uom"/>
<span class="ms-4" attrs="{'invisible': [('lot_id', '=', False)]}" groups="stock.group_production_lot">
<field name="quantity"/>
<field name="product_uom_id" groups="uom.group_uom"/>
<span class="ms-4" attrs="{'invisible': [('lot_id', '=', False)]}"
groups="stock.group_production_lot">
<field name="lot_id"/>
</span>
</div>
<div class="mb4" attrs="{'invisible': [('package_id', '=', False)]}" groups="stock.group_tracking_lot">
<i class="fa fa-lg fa-archive" title="Package"/><field name="package_id"/>
<div class="mb4" attrs="{'invisible': [('package_id', '=', False)]}"
groups="stock.group_tracking_lot">
<i class="fa fa-lg fa-archive" title="Package"/>
<field name="package_id"/>
</div>
<div class="mb4" attrs="{'invisible': [('owner_id', '=', False)]}" groups="stock.group_tracking_owner">
<i class="fa fa-lg fa-user-o" title="Owner"/><field name="owner_id"/>
<div class="mb4" attrs="{'invisible': [('owner_id', '=', False)]}"
groups="stock.group_tracking_owner">
<i class="fa fa-lg fa-user-o" title="Owner"/>
<field name="owner_id"/>
</div>
</div>
</t>

View File

@@ -1,21 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo><data>
<record id="view_stock_move_line_detailed_operation_tree_inherit_stock_barcode" model="ir.ui.view">
<field name="name">stock.move.line.operations.tree.inherit</field>
<field name="model">stock.move.line</field>
<field name="inherit_id" ref="stock.view_stock_move_line_detailed_operation_tree"/>
<field name="arch" type="xml">
<xpath expr="//tree" position="inside">
<field name="product_barcode" invisible="1"/>
<field name="location_processed" invisible="1"/>
</xpath>
<xpath expr="//field[@name='qty_done']" position="attributes">
<attribute name="options">{'barcode_events': True}</attribute>
<attribute name="widget">field_float_scannable</attribute>
</xpath>
</field>
</record>
<odoo>
<data>
<record id="view_stock_move_line_kanban_inherited" model="ir.ui.view">
<field name="name">stock.move.line.kanban.inherited</field>
<field name="model">stock.move.line</field>
@@ -45,11 +30,13 @@
attrs="{'invisible': [('show_allocation', '=', False)]}"
groups="stock.group_reception_report"/>
<field name="partner_id"/>
<field name="scheduled_date" readonly="1" attrs="{'invisible': [('scheduled_date', '=', False)]}"/>
<field name="scheduled_date" readonly="1"
attrs="{'invisible': [('scheduled_date', '=', False)]}"/>
<field name="origin" readonly="1" attrs="{'invisible': [('origin', '=', False)]}"/>
<field name="state" readonly="1" attrs="{'invisible': [('state', '=', False)]}"/>
<field name="priority" readonly="1" attrs="{'invisible': [('priority', '=', False)]}"/>
<field name="owner_id" readonly="1" attrs="{'invisible': [('owner_id', '=', False)]}" groups="stock.group_tracking_owner"/>
<field name="owner_id" readonly="1" attrs="{'invisible': [('owner_id', '=', False)]}"
groups="stock.group_tracking_owner"/>
<field name="company_id" readonly="1" groups="base.group_multi_company"/>
<field name="move_ids" readonly="1" attrs="{'invisible': [('move_ids', '=', False)]}">
<kanban>
@@ -105,14 +92,18 @@
<!-- Use the form view -->
<xpath expr="//div[hasclass('o_kanban_record_headings')]" position="after">
<button style="padding: 0px 10px;" class="btn btn-link fa fa-desktop" title="Open picking" name="action_open_picking" type="object"/>
<button style="padding: 0px 10px;" class="btn btn-link fa fa-desktop" title="Open picking"
name="action_open_picking" type="object"/>
</xpath>
<!-- Use mobile view-->
<xpath expr="//strong[hasclass('o_kanban_record_title')]" position="replace">
<button style="padding: 0px 0px;" class="btn btn-link o_kanban_record_title" name="action_open_picking_client_action"
<button style="padding: 0px 0px;" class="btn btn-link o_kanban_record_title"
name="action_open_picking_client_action"
type="object">
<span><t t-esc="record.name.value"/></span>
<span>
<t t-esc="record.name.value"/>
</span>
</button>
</xpath>
</field>
@@ -153,7 +144,8 @@
attrs="{'invisible': [('code', '=', 'outgoing')]}"/>
</group>
<field name="show_barcode_validation" invisible="1"/>
<group name="barcode_validation" string="Final Validation" attrs="{'invisible': [('show_barcode_validation', '=', False)]}">
<group name="barcode_validation" string="Final Validation"
attrs="{'invisible': [('show_barcode_validation', '=', False)]}">
<!-- show_barcode_validation handles combined groups/invisible complexity -->
<field name="barcode_validation_full"
attrs="{'invisible': [('restrict_scan_product', '=', True)]}"/>
@@ -178,4 +170,5 @@
</xpath>
</field>
</record>
</data></odoo>
</data>
</odoo>