Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/制造代码优化

This commit is contained in:
mgw
2023-11-28 16:42:54 +08:00
31 changed files with 344 additions and 401 deletions

View File

@@ -1,4 +1,3 @@
# -*-coding:utf-8-*- # -*-coding:utf-8-*-
from . import controllers from . import controllers
from . import models from . import models

View File

@@ -1,5 +1 @@
from . import product_supplierinfo from . import product_supplierinfo

View File

@@ -2,9 +2,7 @@
import os import os
import json import json
import base64 import base64
import shutil
import logging import logging
import hashlib
from io import BytesIO from io import BytesIO
from zipfile import ZipFile from zipfile import ZipFile
from datetime import datetime, timedelta from datetime import datetime, timedelta
@@ -12,8 +10,6 @@ import requests
from odoo.http import request from odoo.http import request
from odoo import fields, models, api from odoo import fields, models, api
from odoo.exceptions import UserError from odoo.exceptions import UserError
from odoo.exceptions import MissingError
from odoo.exceptions import ValidationError
from odoo.addons.sf_machine_connect.models import py2opcua, ftp_operate from odoo.addons.sf_machine_connect.models import py2opcua, ftp_operate
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)

View File

@@ -1,5 +1,4 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os
import logging import logging
from ftplib import FTP from ftplib import FTP
@@ -20,7 +19,6 @@ class FTP_P(FTP):
cmd = 'LIST' cmd = 'LIST'
templist = [] templist = []
tempdic = {} tempdic = {}
func = None
if args[-1:] and type(args[-1]) != type(''): if args[-1:] and type(args[-1]) != type(''):
args, func = args[:-1], args[-1] args, func = args[:-1], args[-1]
for arg in args: for arg in args:

View File

@@ -19,4 +19,4 @@
'application': False, 'application': False,
'auto_install': False, 'auto_install': False,
'license': 'LGPL-3', 'license': 'LGPL-3',
} }

View File

@@ -1,6 +1,6 @@
# -*-coding:utf-8-*- # -*-coding:utf-8-*-
from odoo import api, fields, models, SUPERUSER_ID, _ from odoo import api, fields, models
from odoo.exceptions import UserError
class SfEquipmentSaintenanceStandards(models.Model): class SfEquipmentSaintenanceStandards(models.Model):

View File

@@ -1,10 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import json import json
import base64 import base64
from datetime import date, datetime, timedelta from datetime import timedelta
import requests import requests
from odoo.addons.sf_base.commons.common import Common from odoo.addons.sf_base.commons.common import Common
from odoo import api, fields, models, SUPERUSER_ID, _ from odoo import api, fields, models, _
from odoo.exceptions import UserError from odoo.exceptions import UserError
@@ -65,8 +65,8 @@ class SfMaintenanceEquipment(models.Model):
MTcode = fields.Char("机台编码", default=get_no) MTcode = fields.Char("机台编码", default=get_no)
created_user = fields.Many2one('res.users', string='创建人', default=lambda self: self.env.user) created_user = fields.Many2one('res.users', string='创建人', default=lambda self: self.env.user)
equipment_type = fields.Selection([('机床', '机床'), ('机器人', '机器人'), ('AGV小车', 'AGV小车'), ('检测设备', '检测设备')] equipment_type = fields.Selection([('机床', '机床'), ('机器人', '机器人'), ('AGV小车', 'AGV小车'),
, compute='_compute_category_id') ('检测设备', '检测设备')], compute='_compute_category_id')
@api.depends('category_id') @api.depends('category_id')
def _compute_category_id(self): def _compute_category_id(self):

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import base64 import base64
from odoo import api, fields, models, SUPERUSER_ID, _ from odoo import api, fields, models, _
from odoo.exceptions import UserError from odoo.exceptions import UserError

View File

@@ -1,6 +1,7 @@
# -*-coding:utf-8-*- # -*-coding:utf-8-*-
from odoo.tests.common import TransactionCase from odoo.tests.common import TransactionCase
class TestEquipmentMaintenanceStandards(TransactionCase): class TestEquipmentMaintenanceStandards(TransactionCase):
def setUp(self, *args, **kwargs): def setUp(self, *args, **kwargs):
result = super().setUp(*args, **kwargs) result = super().setUp(*args, **kwargs)

View File

@@ -41,14 +41,6 @@
], ],
'qweb': [ 'qweb': [
], ],
'assets': {
'web.assets_backend': [
'sf_manufacturing/static/src/js/kanban_change.js',
'sf_manufacturing/static/src/scss/kanban_change.scss',
'sf_manufacturing/static/src/xml/kanban_change.xml',
],
},
'license': 'LGPL-3', 'license': 'LGPL-3',
'installable': True, 'installable': True,
'application': False, 'application': False,

View File

@@ -1,4 +1,4 @@
from odoo import fields, models, api from odoo import fields, models
class ModelType(models.Model): class ModelType(models.Model):

View File

@@ -4,7 +4,6 @@ from dateutil.relativedelta import relativedelta
from odoo import api, fields, models, _ from odoo import api, fields, models, _
class MaintenanceEquipment(models.Model): class MaintenanceEquipment(models.Model):
_inherit = "maintenance.equipment" _inherit = "maintenance.equipment"
@@ -64,6 +63,7 @@ class MaintenanceRequest(models.Model):
production_company_id = fields.Many2one(string='Production Company', related='production_id.company_id') production_company_id = fields.Many2one(string='Production Company', related='production_id.company_id')
company_id = fields.Many2one(domain="[('id', '=?', production_company_id)]") company_id = fields.Many2one(domain="[('id', '=?', production_company_id)]")
class SfMaintenanceLogs(models.Model): class SfMaintenanceLogs(models.Model):
_inherit = 'sf.maintenance.logs' _inherit = 'sf.maintenance.logs'

View File

@@ -1,10 +1,10 @@
import logging import logging
from datetime import datetime
from dateutil.relativedelta import relativedelta
import os
import base64 import base64
import math from datetime import datetime
import requests import requests
import os
import math
from dateutil.relativedelta import relativedelta
# import subprocess # import subprocess
from odoo import api, fields, models, SUPERUSER_ID, _ from odoo import api, fields, models, SUPERUSER_ID, _
from odoo.addons.sf_base.commons.common import Common from odoo.addons.sf_base.commons.common import Common
@@ -616,7 +616,7 @@ class CNCprocessing(models.Model):
logging.info('folder_name:%s' % folder_name) logging.info('folder_name:%s' % folder_name)
serverdir = os.path.join('/tmp', folder_name, 'return', processing_panel) serverdir = os.path.join('/tmp', folder_name, 'return', processing_panel)
logging.info('serverdir:%s' % serverdir) logging.info('serverdir:%s' % serverdir)
for root, dirs, files in os.walk(serverdir): for root, files in os.walk(serverdir):
for f in files: for f in files:
logging.info('f:%s' % f) logging.info('f:%s' % f)
if os.path.splitext(f)[1] == ".pdf": if os.path.splitext(f)[1] == ".pdf":

View File

@@ -1,6 +1,3 @@
from . import ftp_operate from . import ftp_operate
from . import res_config_setting from . import res_config_setting
from . import sync_common from . import sync_common

View File

@@ -1,5 +1,3 @@
from . import sale_order from . import sale_order
from . import quick_easy_order from . import quick_easy_order
from . import auto_quatotion_common from . import auto_quatotion_common

View File

@@ -2,7 +2,7 @@
import logging import logging
from odoo.modules import get_resource_path from odoo.modules import get_resource_path
from odoo import fields, models, api from odoo import fields, models, api
# from quatotion import readSql, feature_recognize, auto_quatotion from quatotion import readSql, feature_recognize, auto_quatotion
__author__ = 'jinling.yang' __author__ = 'jinling.yang'
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@@ -24,14 +24,14 @@ class AutoQuatotion(models.Model):
def get_process_time_db_path(self): def get_process_time_db_path(self):
return get_resource_path('sf_sale', 'models', 'process_time.db') return get_resource_path('sf_sale', 'models', 'process_time.db')
# def get_auto_quatotion(self, stp_url, feature_full_path, process_time_db_path, model_code): def get_auto_quatotion(self, stp_url, feature_full_path, process_time_db_path, model_code):
# ''' '''
# 通过打包好的.so库 通过打包好的.so库
# 以调用autoQuatotion库中Quatotion类 以调用autoQuatotion库中Quatotion类
# 初始化后调用类的analyseShape方法对模型文件进行价格预测 初始化后调用类的analyseShape方法对模型文件进行价格预测
# ''' '''
# # 初始化自动报价类(输入特征数据库和加工时间数据库) # 初始化自动报价类(输入特征数据库和加工时间数据库)
# reader = auto_quatotion.Quatotion(feature_full_path, process_time_db_path) reader = auto_quatotion.Quatotion(feature_full_path, process_time_db_path)
# # 获取价格、加工时间、尺寸、XYZ、翻面次数 # 获取价格、加工时间、尺寸、XYZ、翻面次数
# feature_info = reader.analyseShape(stp_url, InfoJson={}) feature_info = reader.analyseShape(stp_url, InfoJson={})
# return feature_info return feature_info

View File

@@ -14,7 +14,6 @@ class ReSaleOrder(models.Model):
pay_way = fields.Selection([('转账', '转账'), ('微信', '微信'), ('支付宝', '支付宝')], '支付方式') pay_way = fields.Selection([('转账', '转账'), ('微信', '微信'), ('支付宝', '支付宝')], '支付方式')
check_status = fields.Selection([('unchecked', '未审核'), ('checked', '已审核')], '审核状态', default='unchecked') check_status = fields.Selection([('unchecked', '未审核'), ('checked', '已审核')], '审核状态', default='unchecked')
payment_term_id = fields.Many2one( payment_term_id = fields.Many2one(
comodel_name='account.payment.term', comodel_name='account.payment.term',
string="交付条件", string="交付条件",
@@ -32,6 +31,7 @@ class ReSaleOrder(models.Model):
'date_order': now_time, 'date_order': now_time,
'name': self.env['ir.sequence'].next_by_code('sale.order', sequence_date=now_time), 'name': self.env['ir.sequence'].next_by_code('sale.order', sequence_date=now_time),
'partner_id': partner.id, 'partner_id': partner.id,
'check_status': 'checked',
'state': 'draft', 'state': 'draft',
'person_of_delivery': delivery_name, 'person_of_delivery': delivery_name,
'telephone_of_delivery': delivery_telephone, 'telephone_of_delivery': delivery_telephone,
@@ -74,9 +74,3 @@ class ResaleOrderLine(models.Model):
_inherit = 'sale.order.line' _inherit = 'sale.order.line'
model_glb_file = fields.Binary('模型的glb文件') model_glb_file = fields.Binary('模型的glb文件')
class ResCrmTeam(models.Model):
_inherit = 'crm.team'

View File

@@ -10,12 +10,10 @@
""", """,
'category': 'sf', 'category': 'sf',
'website': 'https://www.sf.jikimo.com', 'website': 'https://www.sf.jikimo.com',
'depends': ['sf_base', 'sf_manufacturing'], 'depends': ['sf_manufacturing'],
'data': [ 'data': [
# 'security/group_security.xml', 'security/group_security.xml',
'security/ir.model.access.csv', 'security/ir.model.access.csv',
# 'views/tool_base_views.xml',
# # 'views/menu_view.xml',
'wizard/wizard_view.xml', 'wizard/wizard_view.xml',
'views/tool_base_views.xml', 'views/tool_base_views.xml',
'views/menu_view.xml', 'views/menu_view.xml',

View File

@@ -6,11 +6,6 @@ from odoo import SUPERUSER_ID
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
# class FunctionalCuttingToolEntity(models.Model):
# _name = 'sf.functional.cutting.tool.entity'
# _inherit = 'sf.functional.cutting.tool'
# _inherits = {'sf.functional.cutting.tool': 'sf_functional_cutting_tool_entity_id'}
# _description = '功能刀具管理'
class FunctionalCuttingToolEntity(models.Model): class FunctionalCuttingToolEntity(models.Model):
_name = 'sf.functional.cutting.tool.entity' _name = 'sf.functional.cutting.tool.entity'
_description = '功能刀具列表' _description = '功能刀具列表'
@@ -30,7 +25,7 @@ class FunctionalCuttingToolEntity(models.Model):
tool_loading_length = fields.Float(string='装刀长(mm)', readonly=True) tool_loading_length = fields.Float(string='装刀长(mm)', readonly=True)
functional_tool_length = fields.Float(string='伸出长(mm)', readonly=True) functional_tool_length = fields.Float(string='伸出长(mm)', readonly=True)
effective_length = fields.Float(string='有效长(mm)', readonly=True) effective_length = fields.Float(string='有效长(mm)', readonly=True)
tool_room_num = fields.Integer(string='刀具房数量', readonly=True, ) tool_room_num = fields.Integer(string='刀具房数量', readonly=True)
line_edge_knife_library_num = fields.Integer(string='线边刀库数量', readonly=True) line_edge_knife_library_num = fields.Integer(string='线边刀库数量', readonly=True)
machine_knife_library_num = fields.Integer(string='机内刀库数量', readonly=True) machine_knife_library_num = fields.Integer(string='机内刀库数量', readonly=True)
max_lifetime_value = fields.Integer(string='最大寿命值(min)', readonly=True) max_lifetime_value = fields.Integer(string='最大寿命值(min)', readonly=True)
@@ -41,16 +36,16 @@ class FunctionalCuttingToolEntity(models.Model):
current_location_id = fields.Many2one('stock.location', string='当前位置', readonly=True) current_location_id = fields.Many2one('stock.location', string='当前位置', readonly=True)
image = fields.Binary('图片', readonly=True) image = fields.Binary('图片', readonly=True)
@api.depends('current_location_id') # @api.depends('current_location_id')
def _compute_location_num(self): # def _compute_location_num(self):
""" # """
计算库存位置数量 # 计算库存位置数量
""" # """
for obj in self: # for obj in self:
if obj.current_location_id.name in ('组装后', '刀具房'): # if obj.current_location_id.name in ('组装后', '刀具房'):
obj.tool_room_num = 1 # obj.tool_room_num = 1
obj.line_edge_knife_library_num = 0 # obj.line_edge_knife_library_num = 0
obj.machine_knife_library_num = 0 # obj.machine_knife_library_num = 0
@api.model @api.model
def _read_group_mrs_cutting_tool_type_id(self, categories, domain, order): def _read_group_mrs_cutting_tool_type_id(self, categories, domain, order):
@@ -118,6 +113,14 @@ class FunctionalCuttingToolEntity(models.Model):
result['domain'] = [('lot_id', '=', self.barcode_id.id), ('qty_done', '>', 0)] result['domain'] = [('lot_id', '=', self.barcode_id.id), ('qty_done', '>', 0)]
return result return result
def open_safety_stock(self):
action = self.env.ref('sf_tool_management.sf_real_time_distribution_of_functional_tools_view_act')
result = action.read()[0]
result['domain'] = [('name', '=', self.name), ('diameter', '=', self.functional_tool_diameter),
('knife_tip_r_angle', '=', self.knife_tip_r_angle),
('coarse_middle_thin', '=', self.coarse_middle_thin)]
return result
class FunctionalToolWarning(models.Model): class FunctionalToolWarning(models.Model):
_name = 'sf.functional.tool.warning' _name = 'sf.functional.tool.warning'
@@ -178,113 +181,74 @@ class RealTimeDistributionOfFunctionalTools(models.Model):
_name = 'sf.real.time.distribution.of.functional.tools' _name = 'sf.real.time.distribution.of.functional.tools'
_description = '功能刀具安全库存' _description = '功能刀具安全库存'
functional_cutting_tool_id = fields.Many2one('sf.functional.cutting.tool.entity', '功能刀具', readonly=True) name = fields.Char('功能刀具名称')
mrs_cutting_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型', readonly=True, sf_cutting_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型',
group_expand='_read_mrs_cutting_tool_type_ids', group_expand='_read_mrs_cutting_tool_type_ids', store=True)
store=True, diameter = fields.Integer(string='刀具直径(mm)')
compute='_compute_functional_cutting_tool_ids') knife_tip_r_angle = fields.Float(string='刀尖R角(mm)')
tool_stock_num = fields.Integer(string='刀具房数量')
side_shelf_num = fields.Integer(string='线边刀库数量')
on_tool_stock_num = fields.Integer(string='机内刀库数量')
tool_stock_total = fields.Integer(string='当前库存量', readonly=True, compute='_compute_tool_stock_total')
min_stock_num = fields.Integer('最低库存量')
max_stock_num = fields.Integer('最高库存量')
batch_replenishment_num = fields.Integer('批次补货量')
unit = fields.Char('单位')
image = fields.Binary('图片')
coarse_middle_thin = fields.Selection([("1", ""), ('2', ''), ('3', '')], string='粗/中/精')
whether_standard_knife = fields.Boolean(string='是否标准刀', default=True)
# 能力特征信息
suitable_machining_method_ids = fields.Many2many(
'maintenance.equipment.image', 'rel_machining_product_template_distribution', '适合加工方式',
domain=[('type', '=', '加工能力')],
related='sf_functional_cutting_tool_entity_ids.suitable_machining_method_ids')
blade_tip_characteristics_id = fields.Many2many(
'maintenance.equipment.image', 'rel_blade_tip_product_template_distribution', '刀尖特征',
domain=[('type', '=', '刀尖特征')],
related='sf_functional_cutting_tool_entity_ids.blade_tip_characteristics_id')
handle_type_ids = fields.Many2many(
'maintenance.equipment.image', 'rel_handle_product_template_distribution', '柄部类型',
domain=[('type', '=', '柄部类型')], related='sf_functional_cutting_tool_entity_ids.handle_type_ids')
cutting_direction_ids = fields.Many2many(
'maintenance.equipment.image', 'rel_cutting_product_template_distribution', '走刀方向',
domain=[('type', '=', '走刀方向')], related='sf_functional_cutting_tool_entity_ids.cutting_direction_ids')
suitable_coolant_ids = fields.Many2many(
'maintenance.equipment.image', 'rel_coolant_product_template_distribution', '适合冷却液',
domain=[('type', '=', '冷却液')], related='sf_functional_cutting_tool_entity_ids.suitable_coolant_ids')
sf_functional_cutting_tool_entity_ids = fields.Many2many('sf.functional.cutting.tool.entity',
'sf_functional_cutting_tool_entity_ref',
string='功能刀具列表信息', readonly=True)
@api.model @api.model
def _read_mrs_cutting_tool_type_ids(self, categories, domain, order): def _read_mrs_cutting_tool_type_ids(self, categories, domain, order):
mrs_cutting_tool_type_ids = categories._search([], order=order, access_rights_uid=SUPERUSER_ID) mrs_cutting_tool_type_ids = categories._search([], order=order, access_rights_uid=SUPERUSER_ID)
return categories.browse(mrs_cutting_tool_type_ids) return categories.browse(mrs_cutting_tool_type_ids)
@api.depends('functional_cutting_tool_id')
def _compute_functional_cutting_tool_ids(self):
for record in self:
if record:
record.mrs_cutting_tool_type_id = record.functional_cutting_tool_id.mrs_cutting_tool_type_id.id
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', readonly=True)
name = fields.Char('名称', invisible=True, readonly=True)
functional_tool_name_id = fields.Many2one('product.product', string='功能刀具名称', readonly=True)
# 整体式刀具型号
cutting_tool_integral_model_id = fields.Many2one(
'product.product', string='整体式刀具型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '整体式刀具')],
related='functional_cutting_tool_id.cutting_tool_integral_model_id')
# 刀片型号
cutting_tool_blade_model_id = fields.Many2one(
'product.product', string='刀片型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '刀片')],
related='functional_cutting_tool_id.cutting_tool_blade_model_id')
# 刀杆型号
cutting_tool_cutterbar_model_id = fields.Many2one(
'product.product', string='刀杆型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '刀杆')],
related='functional_cutting_tool_id.cutting_tool_cutterbar_model_id')
# 刀盘型号
cutting_tool_cutterpad_model_id = fields.Many2one(
'product.product', string='刀盘型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '刀盘')],
related='functional_cutting_tool_id.cutting_tool_cutterpad_model_id')
# 刀柄型号
cutting_tool_cutterhandle_model_id = fields.Many2one(
'product.product', string='刀柄型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '刀柄')],
related='functional_cutting_tool_id.cutting_tool_cutterhandle_model_id')
# 夹头型号
cutting_tool_cutterhead_model_id = fields.Many2one(
'product.product', string='夹头型号', readonly=True,
domain=[('cutting_tool_material_id', '=', '夹头')],
related='functional_cutting_tool_id.cutting_tool_cutterhead_model_id')
diameter = fields.Float('直径(mm)', readonly=True)
tool_grade = fields.Selection([('1', 'P1'), ('2', 'P2'), ('3', 'P3'), ('4', 'P4'), ('5', 'P5'), ('6', 'P6')],
string='刀具等级', readonly=True)
machining_accuracy = fields.Float('加工精度(mm)', readonly=True)
tool_length = fields.Float('装刀长(mm)', readonly=True)
blade_number = fields.Integer('刃数', readonly=True)
integral_blade_length = fields.Float('整体刃长(mm)', readonly=True)
effective_blade_length = fields.Float('有效刃长(mm)', readonly=True)
max_life = fields.Float('最大寿命值', readonly=True)
is_standard = fields.Selection([('1', ''), ('0', '')], '是否标准刀', readonly=True,
compute='_compute_functional_cutting_tool_id')
applicable_range = fields.Char('适用范围', readonly=True)
image = fields.Binary('图片', readonly=True)
@api.depends('functional_cutting_tool_id')
def _compute_functional_cutting_tool_id(self):
if self.functional_cutting_tool_id:
self.tool_grade = self.functional_cutting_tool_id.tool_grade
self.is_standard = self.functional_cutting_tool_id.is_standard
# 功能刀具实时分布
tool_stock_num = fields.Integer(string='刀具房库存数量', readonly=False)
side_shelf_num = fields.Integer(string='线边货架货架数量', readonly=False)
on_tool_stock_num = fields.Integer(string='机内刀库库存数量', readonly=False)
tool_stock_total = fields.Integer(string='合计(库存)', readonly=True, compute='_compute_tool_stock_total')
return_reuse_num_re = fields.Integer(string='归还再用数量(精)', readonly=False)
return_reuse_num_co = fields.Integer(string='归还再用数量(粗)', readonly=False)
return_processing_num = fields.Integer(string='归还需磨削数量', readonly=False)
return_total = fields.Integer(string='合计(归还)', readonly=True, compute='_compute_return_total')
total = fields.Integer(string='总计', readonly=True, compute='_compute_total')
remark = fields.Char(string='备注/说明', readonly=False)
@api.depends('tool_stock_num', 'side_shelf_num', 'on_tool_stock_num') @api.depends('tool_stock_num', 'side_shelf_num', 'on_tool_stock_num')
def _compute_tool_stock_total(self): def _compute_tool_stock_total(self):
for record in self: for record in self:
if record: if record:
self.tool_stock_total = record.tool_stock_num + record.side_shelf_num + record.on_tool_stock_num self.tool_stock_total = record.tool_stock_num + record.side_shelf_num + record.on_tool_stock_num
@api.depends('return_reuse_num_re', 'return_reuse_num_co', 'return_processing_num') def create_or_edit_safety_stock(self, vals, sf_functional_cutting_tool_entity_ids):
def _compute_return_total(self): """
for record in self: 根据传入的信息新增或者更新功能刀具安全库存的信息
if record: """
self.return_total = (record.return_reuse_num_re + record.return_reuse_num_co + print(vals)
record.return_processing_num) # 根据功能刀具名称、直径或尖刀R角、粗/中/精查询该功能刀具是否已经存在
record = self.env['sf.real.time.distribution.of.functional.tools'].search(
@api.depends('tool_stock_total', 'return_total') [('name', '=', vals['name']), ('sf_cutting_tool_type_id', '=', vals['sf_cutting_tool_type_id']),
def _compute_total(self): ('diameter', '=', vals['diameter']), ('knife_tip_r_angle', '=', vals['knife_tip_r_angle']),
for record in self: ('coarse_middle_thin', '=', vals['coarse_middle_thin'])])
if record: print(record)
self.total = record.tool_stock_total + record.return_total if len(record) > 0:
for obj in record:
obj.write({'sf_functional_cutting_tool_entity_ids': [(4, sf_functional_cutting_tool_entity_ids.id)]})
else:
vals['sf_functional_cutting_tool_entity_ids'] = sf_functional_cutting_tool_entity_ids.ids
self.env['sf.real.time.distribution.of.functional.tools'].create(vals)
class MachineTableToolChangingApply(models.Model): class MachineTableToolChangingApply(models.Model):
@@ -293,6 +257,7 @@ class MachineTableToolChangingApply(models.Model):
_order = 'cutter_spacing_code_id' _order = 'cutter_spacing_code_id'
name = fields.Char('名称', related='maintenance_equipment_id.name', store=True) name = fields.Char('名称', related='maintenance_equipment_id.name', store=True)
# 设备信息
maintenance_equipment_id = fields.Many2one('maintenance.equipment', string='CNC机床', required=True, readonly=False, maintenance_equipment_id = fields.Many2one('maintenance.equipment', string='CNC机床', required=True, readonly=False,
domain=[('category_id.equipment_type', '=', '机床')]) domain=[('category_id.equipment_type', '=', '机床')])
production_line_id = fields.Many2one('sf.production.line', string='生产线', readonly=True, production_line_id = fields.Many2one('sf.production.line', string='生产线', readonly=True,
@@ -302,6 +267,7 @@ class MachineTableToolChangingApply(models.Model):
machine_tool_code = fields.Char(string='机台号', store=True, invisible=True, readonly=True) machine_tool_code = fields.Char(string='机台号', store=True, invisible=True, readonly=True)
cutter_spacing_code_id = fields.Many2one('maintenance.equipment.tool', string='刀位号', readonly=False, cutter_spacing_code_id = fields.Many2one('maintenance.equipment.tool', string='刀位号', readonly=False,
required=True, domain="[('equipment_id', '=', maintenance_equipment_id)]") required=True, domain="[('equipment_id', '=', maintenance_equipment_id)]")
# 功能刀具信息
functional_tool_name = fields.Char(string='刀具名称', related='functional_tool_name_id.name', store=True) functional_tool_name = fields.Char(string='刀具名称', related='functional_tool_name_id.name', store=True)
barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', store=True, barcode_id = fields.Many2one('stock.lot', string='功能刀具序列号', store=True,
domain=[('product_id.name', '=', '功能刀具')], domain=[('product_id.name', '=', '功能刀具')],
@@ -407,20 +373,7 @@ class MachineTableToolChangingApply(models.Model):
machine_table_tool_changing_apply.write( machine_table_tool_changing_apply.write(
{'status': '1', {'status': '1',
'sf_functional_tool_assembly_id': sf_functional_tool_assembly}) 'sf_functional_tool_assembly_id': sf_functional_tool_assembly.id})
# def new_assembly_task(self, vals):
# """
# 新建组装任务
# :param vals:
# :return:
# """
# # 增加设置直径的值
# tool_changing_apply = self.env['sf.machine.table.tool.changing.apply'].search(
# [('name', '=', vals['name'])])
# vals['functional_tool_diameter'] = tool_changing_apply.diameter
#
# self.env['sf.functional.tool.assembly'].create(vals)
def revocation_1(self): def revocation_1(self):
""" """
@@ -538,7 +491,7 @@ class CAMWorkOrderProgramKnifePlan(models.Model):
class FunctionalToolAssembly(models.Model): class FunctionalToolAssembly(models.Model):
_name = 'sf.functional.tool.assembly' _name = 'sf.functional.tool.assembly'
_description = '功能刀具组装' _description = '功能刀具组装'
_order = 'use_tool_time asc' _order = 'use_tool_time asc'
@api.depends('functional_tool_name') @api.depends('functional_tool_name')

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from odoo import fields, models, api, SUPERUSER_ID from odoo import fields, models, api, SUPERUSER_ID
from odoo.exceptions import ValidationError # from odoo.exceptions import ValidationError
# 刀具物料搜索 # 刀具物料搜索

View File

@@ -61,6 +61,16 @@
</span> </span>
</div> </div>
</button> </button>
<button class="oe_stat_button"
name="open_safety_stock"
icon="fa-list-ul"
type="object">
<div class="o_field_widget o_stat_info">
<span>
安全库存
</span>
</div>
</button>
</div> </div>
<div class="oe_title"> <div class="oe_title">
<h1> <h1>
@@ -264,126 +274,96 @@
</record> </record>
<!-- =====================================功能刀具实时分布============================================================= --> <!-- =====================================功能刀具安全库存=================================================== -->
<record id="sf_real_time_distribution_of_functional_tools_view_tree" model="ir.ui.view"> <record id="sf_real_time_distribution_of_functional_tools_view_tree" model="ir.ui.view">
<field name="name">功能刀具实时分布</field> <field name="name">功能刀具安全库存</field>
<field name="model">sf.real.time.distribution.of.functional.tools</field> <field name="model">sf.real.time.distribution.of.functional.tools</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree create="0" edit="0" delete="0"> <tree create="0" edit="0" delete="0">
<field name="barcode_id"/> <field name="name"/>
<field name="functional_tool_name_id"/> <field name="sf_cutting_tool_type_id" invisible="True"/>
<field name="mrs_cutting_tool_type_id"/> <field name="diameter"/>
<field name="cutting_tool_integral_model_id" optional="hide"/> <field name="knife_tip_r_angle"/>
<field name="cutting_tool_blade_model_id" optional="hide"/> <field name="coarse_middle_thin"/>
<field name="cutting_tool_cutterbar_model_id" optional="hide"/>
<field name="cutting_tool_cutterpad_model_id" optional="hide"/>
<field name="cutting_tool_cutterhandle_model_id" optional="hide"/>
<field name="cutting_tool_cutterhead_model_id" optional="hide"/>
<field name="tool_stock_num"/> <field name="tool_stock_num"/>
<field name="side_shelf_num"/> <field name="side_shelf_num"/>
<field name="on_tool_stock_num"/> <field name="on_tool_stock_num"/>
<field name="tool_stock_total"/> <field name="tool_stock_total"/>
<field name="return_reuse_num_re" optional="hide"/> <field name="min_stock_num"/>
<field name="return_reuse_num_co" optional="hide"/> <field name="max_stock_num"/>
<field name="return_processing_num" optional="hide"/> <field name="batch_replenishment_num"/>
<field name="return_total" optional="hide"/> <field name="unit"/>
<field name="total" optional="hide"/>
<field name="remark"/>
</tree> </tree>
</field> </field>
</record> </record>
<record id="sf_real_time_distribution_of_functional_tools_view_form" model="ir.ui.view"> <record id="sf_real_time_distribution_of_functional_tools_view_form" model="ir.ui.view">
<field name="name">功能刀具实时分布</field> <field name="name">功能刀具安全库存</field>
<field name="model">sf.real.time.distribution.of.functional.tools</field> <field name="model">sf.real.time.distribution.of.functional.tools</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form create="0" edit="0" delete="0"> <form create="0" edit="0" delete="0">
<sheet> <sheet>
<div class="oe_title"> <div class="oe_title">
<h1> <h1>
<field name="barcode_id" readonly="1"/> <field name="name"/>
</h1> </h1>
</div> </div>
<group> <group>
<group> <group>
<field name="functional_tool_name_id" invisible="False"/> <field name="sf_cutting_tool_type_id"/>
<field name="mrs_cutting_tool_type_id"/> <field name="diameter"/>
<field name="knife_tip_r_angle"/>
<field name="cutting_tool_integral_model_id" <field name="coarse_middle_thin"/>
options="{'no_create': True, 'no_quick_create': True}" <field name="whether_standard_knife"/>
attrs="{'invisible': [('cutting_tool_blade_model_id', '!=', False)]}"
/>
<field name="cutting_tool_blade_model_id"
options="{'no_create': True, 'no_quick_create': True}"
attrs="{'invisible': [('cutting_tool_integral_model_id', '!=', False)]}"
/>
<field name="cutting_tool_cutterbar_model_id"
options="{'no_create': True, 'no_quick_create': True}"
attrs="{'invisible': ['|',('cutting_tool_cutterpad_model_id','!=',False),('cutting_tool_blade_model_id', '=', False)]}"
/>
<field name="cutting_tool_cutterpad_model_id"
options="{'no_create': True, 'no_quick_create': True}"
attrs="{'invisible': ['|',('cutting_tool_cutterbar_model_id','!=',False),('cutting_tool_blade_model_id', '=', False)]}"
/>
<field name="cutting_tool_cutterhandle_model_id"
options="{'no_create': True, 'no_quick_create': True}"/>
<field name="cutting_tool_cutterhead_model_id"
options="{'no_create': True, 'no_quick_create': True}"/>
</group> </group>
<group> <group>
<field name="image" nolabel="1" widget="image"/> <field name="image" widget='image'/>
</group>
</group>
<group col="1">
<group string="适合加工方式">
<field name="suitable_machining_method_ids" string=""
widget="custom_many2many_checkboxes"
domain="[('id','in',suitable_machining_method_ids)]"/>
</group>
<group>
<group string="刀尖特征">
<field name="blade_tip_characteristics_id" string=""
widget="custom_many2many_checkboxes"
domain="[('id','in',blade_tip_characteristics_id)]"/>
</group>
<group string="柄部类型">
<field name="handle_type_ids" string="" widget="custom_many2many_checkboxes"
domain="[('id','in',handle_type_ids)]"/>
</group>
</group>
<group>
<group string="走刀方向">
<field name="cutting_direction_ids" string="" widget="custom_many2many_checkboxes"
domain="[('id','in',cutting_direction_ids)]"/>
</group>
<group string="适合冷却液">
<field name="suitable_coolant_ids" string="" widget="custom_many2many_checkboxes"
domain="[('id','in',suitable_coolant_ids)]"/>
</group>
</group> </group>
</group> </group>
<notebook> <notebook>
<page string="实时分布信息"> <page string="刀具信息">
<group> <field name="sf_functional_cutting_tool_entity_ids" widget="many2many">
<group> <tree>
<group> <field name="barcode_id"/>
<field name="tool_stock_num"/> <field name="functional_tool_name_id"/>
<field name="return_reuse_num_re"/> <field name="new_former"/>
</group> <field name="tool_loading_length"/>
<group> <field name="functional_tool_length"/>
<field name="side_shelf_num"/> <field name="effective_length"/>
<field name="return_reuse_num_co"/> <field name="max_lifetime_value"/>
</group> <field name="alarm_value"/>
</group> <field name="used_value"/>
<group> <field name="functional_tool_status"/>
<group> </tree>
<field name="on_tool_stock_num"/> </field>
<field name="return_processing_num"/>
</group>
<group>
<field name="tool_stock_total"/>
<field name="return_total"/>
<field name="total"/>
</group>
</group>
</group>
</page>
<page string="参数信息">
<group>
<group>
<field name="diameter"/>
<field name="tool_grade"/>
<field name="machining_accuracy"/>
<field name="tool_length"/>
<field name="blade_number"/>
</group>
<group>
<field name="integral_blade_length"/>
<field name="effective_blade_length"/>
<field name="max_life"/>
<field name="is_standard" default="false"/>
<field name="applicable_range"/>
</group>
</group>
</page>
<page string="其他信息">
<group>
<field name="remark"/>
</group>
</page> </page>
</notebook> </notebook>
</sheet> </sheet>
@@ -392,28 +372,31 @@
</record> </record>
<record id="sf_real_time_distribution_of_functional_tools_view_search" model="ir.ui.view"> <record id="sf_real_time_distribution_of_functional_tools_view_search" model="ir.ui.view">
<field name="name">功能刀具实时分布</field> <field name="name">功能刀具安全库存</field>
<field name="model">sf.real.time.distribution.of.functional.tools</field> <field name="model">sf.real.time.distribution.of.functional.tools</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search> <search>
<field name="barcode_id"/> <field name="name"/>
<field name="functional_tool_name_id"/> <field name="sf_cutting_tool_type_id" invisible="True"/>
<field name="mrs_cutting_tool_type_id"/> <field name="diameter"/>
<field name="cutting_tool_integral_model_id" optional="hide"/> <field name="knife_tip_r_angle"/>
<field name="cutting_tool_blade_model_id" optional="hide"/> <field name="tool_stock_num"/>
<field name="cutting_tool_cutterbar_model_id" optional="hide"/> <field name="side_shelf_num"/>
<field name="cutting_tool_cutterpad_model_id" optional="hide"/> <field name="on_tool_stock_num"/>
<field name="cutting_tool_cutterhandle_model_id" optional="hide"/> <field name="tool_stock_total"/>
<field name="cutting_tool_cutterhead_model_id" optional="hide"/> <field name="min_stock_num"/>
<field name="max_stock_num"/>
<field name="batch_replenishment_num"/>
<field name="unit"/>
<searchpanel> <searchpanel>
<field name="mrs_cutting_tool_type_id" enable_counters="1" icon="fa-building"/> <field name="sf_cutting_tool_type_id" enable_counters="1" icon="fa-building"/>
</searchpanel> </searchpanel>
</search> </search>
</field> </field>
</record> </record>
<record id="sf_real_time_distribution_of_functional_tools_view_act" model="ir.actions.act_window"> <record id="sf_real_time_distribution_of_functional_tools_view_act" model="ir.actions.act_window">
<field name="name">功能刀具实时分布</field> <field name="name">功能刀具安全库存</field>
<field name="type">ir.actions.act_window</field> <field name="type">ir.actions.act_window</field>
<field name="res_model">sf.real.time.distribution.of.functional.tools</field> <field name="res_model">sf.real.time.distribution.of.functional.tools</field>
<field name="view_mode">tree,form,search</field> <field name="view_mode">tree,form,search</field>

View File

@@ -57,12 +57,10 @@ class ToolChangeRequirementInformation(models.TransientModel):
确认换刀申请(按键) 确认换刀申请(按键)
:return: :return:
""" """
print('已运行')
record = self.env['sf.machine.table.tool.changing.apply'].search( record = self.env['sf.machine.table.tool.changing.apply'].search(
[('maintenance_equipment_id', '=', self.maintenance_equipment_id.id), [('maintenance_equipment_id', '=', self.maintenance_equipment_id.id),
('cutter_spacing_code_id', '=', self.cutter_spacing_code_id.id) ('cutter_spacing_code_id', '=', self.cutter_spacing_code_id.id)
]) ])
print('运行record_1')
# 功能刀具组装创建新任务(new_assembly_task) # 功能刀具组装创建新任务(new_assembly_task)
sf_functional_tool_assembly = self.env['sf.functional.tool.assembly'].sudo().create({ sf_functional_tool_assembly = self.env['sf.functional.tool.assembly'].sudo().create({
@@ -86,13 +84,11 @@ class ToolChangeRequirementInformation(models.TransientModel):
'reason_for_applying': self.reason_for_applying, 'reason_for_applying': self.reason_for_applying,
'sf_machine_table_tool_changing_apply_id': record.id 'sf_machine_table_tool_changing_apply_id': record.id
}) })
print('sf_functional_tool_assembly:', sf_functional_tool_assembly)
# 修改机床换刀申请状态 # 修改机床换刀申请状态
record.write({ record.write({
'status': '1', 'status': '1',
'sf_functional_tool_assembly_id': sf_functional_tool_assembly 'sf_functional_tool_assembly_id': sf_functional_tool_assembly.id
}) })
print('运行成功')
# 关闭弹出窗口 # 关闭弹出窗口
return {'type': 'ir.actions.act_window_close'} return {'type': 'ir.actions.act_window_close'}
@@ -186,7 +182,9 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
# 功能刀具组装信息 # 功能刀具组装信息
# 整体式刀具型号 # 整体式刀具型号
integral_code_id = fields.Many2one('stock.lot', string='整体式刀具序列号', integral_code_id = fields.Many2one('stock.lot', string='整体式刀具序列号',
domain=[('product_id.cutting_tool_material_id.name', '=', '整体式刀具')]) domain=[('product_id.cutting_tool_material_id.name', '=', '整体式刀具'),
('quant_ids.location_id.name', 'in', ['刀具房']),
('quant_ids.quantity', '>', 0)])
cutting_tool_integral_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='整体式刀具型号', cutting_tool_integral_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='整体式刀具型号',
readonly=True) readonly=True)
integral_name = fields.Char('整体式刀具名称', readonly=True) integral_name = fields.Char('整体式刀具名称', readonly=True)
@@ -194,14 +192,18 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
# 刀片型号 # 刀片型号
blade_code_id = fields.Many2one('stock.lot', '刀片序列号', blade_code_id = fields.Many2one('stock.lot', '刀片序列号',
domain=[('product_id.cutting_tool_material_id.name', '=', '刀片')]) domain=[('product_id.cutting_tool_material_id.name', '=', '刀片'),
('quant_ids.location_id.name', 'in', ['刀具房']),
('quant_ids.quantity', '>', 0)])
cutting_tool_blade_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀片型号', readonly=True) cutting_tool_blade_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀片型号', readonly=True)
blade_name = fields.Char('刀片名称', readonly=True) blade_name = fields.Char('刀片名称', readonly=True)
sf_tool_brand_id_2 = fields.Many2one('sf.machine.brand', '刀片品牌', readonly=True) sf_tool_brand_id_2 = fields.Many2one('sf.machine.brand', '刀片品牌', readonly=True)
# 刀杆型号 # 刀杆型号
bar_code_id = fields.Many2one('stock.lot', '刀杆序列号', bar_code_id = fields.Many2one('stock.lot', '刀杆序列号',
domain=[('product_id.cutting_tool_material_id.name', '=', '刀杆')]) domain=[('product_id.cutting_tool_material_id.name', '=', '刀杆'),
('quant_ids.location_id.name', 'in', ['刀具房']),
('quant_ids.quantity', '>', 0)])
cutting_tool_cutterbar_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀杆型号', cutting_tool_cutterbar_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀杆型号',
readonly=True) readonly=True)
bar_name = fields.Char('刀杆名称', readonly=True) bar_name = fields.Char('刀杆名称', readonly=True)
@@ -209,7 +211,9 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
# 刀盘型号 # 刀盘型号
pad_code_id = fields.Many2one('stock.lot', '刀盘序列号', pad_code_id = fields.Many2one('stock.lot', '刀盘序列号',
domain=[('product_id.cutting_tool_material_id.name', '=', '刀盘')]) domain=[('product_id.cutting_tool_material_id.name', '=', '刀盘'),
('quant_ids.location_id.name', 'in', ['刀具房']),
('quant_ids.quantity', '>', 0)])
cutting_tool_cutterpad_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀盘型号', cutting_tool_cutterpad_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀盘型号',
readonly=True) readonly=True)
pad_name = fields.Char('刀盘名称', readonly=True) pad_name = fields.Char('刀盘名称', readonly=True)
@@ -217,7 +221,9 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
# 刀柄型号 # 刀柄型号
handle_code_id = fields.Many2one('stock.lot', '刀柄序列号', required=True, handle_code_id = fields.Many2one('stock.lot', '刀柄序列号', required=True,
domain=[('product_id.cutting_tool_material_id.name', '=', '刀柄')]) domain=[('product_id.cutting_tool_material_id.name', '=', '刀柄'),
('quant_ids.location_id.name', 'in', ['刀具房']),
('quant_ids.quantity', '>', 0)])
cutting_tool_cutterhandle_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀柄型号', cutting_tool_cutterhandle_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀柄型号',
readonly=True) readonly=True)
handle_name = fields.Char('刀柄名称', readonly=True) handle_name = fields.Char('刀柄名称', readonly=True)
@@ -225,7 +231,9 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
# 夹头型号 # 夹头型号
chuck_code_id = fields.Many2one('stock.lot', '夹头序列号', required=True, chuck_code_id = fields.Many2one('stock.lot', '夹头序列号', required=True,
domain=[('product_id.cutting_tool_material_id.name', '=', '夹头')]) domain=[('product_id.cutting_tool_material_id.name', '=', '夹头'),
('quant_ids.location_id.name', 'in', ['刀具房']),
('quant_ids.quantity', '>', 0)])
cutting_tool_cutterhead_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='夹头型号', cutting_tool_cutterhead_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='夹头型号',
readonly=True) readonly=True)
chuck_name = fields.Char('夹头名称', readonly=True, compute='_compute_auto_fill') chuck_name = fields.Char('夹头名称', readonly=True, compute='_compute_auto_fill')
@@ -339,6 +347,7 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
功能刀具组装 功能刀具组装
:return: :return:
""" """
# 获取组装单对象
functional_tool_assembly = self.env['sf.functional.tool.assembly'].search([ functional_tool_assembly = self.env['sf.functional.tool.assembly'].search([
('assembly_order_code', '=', self.assembly_order_code), ('assembly_order_code', '=', self.assembly_order_code),
('machine_tool_name_id', '=', self.machine_tool_name_id.id), ('machine_tool_name_id', '=', self.machine_tool_name_id.id),
@@ -348,29 +357,45 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
# 对物料做必填判断 # 对物料做必填判断
self.materials_must_be_judged() self.materials_must_be_judged()
product_id = self.env['product.product'].search([('name', '=', '功能刀具')])
# 创建组装入库单 # 创建组装入库单
# 创建功能刀具批次/序列号记录 # 创建功能刀具批次/序列号记录
stock_lot = self.create_assemble_warehouse_receipt(functional_tool_assembly) stock_lot = product_id.create_assemble_warehouse_receipt(self.id, functional_tool_assembly)
# 创建刀具组装入库单 # 创建刀具组装入库单
self.create_stocking_picking(stock_lot) self.create_stocking_picking(stock_lot)
# 封装功能刀具数据 # 刀具物料出库
desc_1 = self.get_desc_1(stock_lot) if self.integral_code_id:
product_id.tool_material_stock_moves(self.integral_code_id)
if self.blade_code_id:
product_id.tool_material_stock_moves(self.blade_code_id)
if self.bar_code_id:
product_id.tool_material_stock_moves(self.bar_code_id)
if self.pad_code_id:
product_id.tool_material_stock_moves(self.pad_code_id)
if self.handle_code_id:
product_id.tool_material_stock_moves(self.handle_code_id)
if self.chuck_code_id:
product_id.tool_material_stock_moves(self.chuck_code_id)
# 创建功能刀具列表记录 # ============================创建功能刀具列表、安全库存记录===============================
# 封装功能刀具数据 # 封装功能刀具数据
desc_2 = self.get_desc_2(stock_lot, functional_tool_assembly) desc_2 = self.get_desc_2(stock_lot, functional_tool_assembly)
# 创建功能刀具列表、功能刀具预警、功能刀具实时分布、功能刀具出入库记录 # 创建功能刀具列表记录
record_1 = self.env['sf.functional.cutting.tool.entity'].create(desc_2) record_1 = self.env['sf.functional.cutting.tool.entity'].create(desc_2)
# self.env['sf.real.time.distribution.of.functional.tools'].create({ # 创建安全库存信息
# 'functional_cutting_tool_id': record_1.id self.env['sf.real.time.distribution.of.functional.tools'].create_or_edit_safety_stock({
# }) 'name': self.after_assembly_functional_tool_name,
# self.env['sf.inbound.and.outbound.records.of.functional.tools'].create({ 'sf_cutting_tool_type_id': self.after_assembly_functional_tool_type_id.id,
# 'functional_cutting_tool_id': record_1.id 'diameter': self.after_assembly_functional_tool_diameter,
# }) 'knife_tip_r_angle': self.after_assembly_knife_tip_r_angle,
'coarse_middle_thin': self.after_assembly_coarse_middle_thin,
}, record_1)
# =====================修改功能刀具组装单、机床换刀申请、CAM工单程序用刀计划的状态==============
# 封装功能刀具数据
desc_1 = self.get_desc_1(stock_lot)
# 修改功能刀具组装单信息 # 修改功能刀具组装单信息
functional_tool_assembly.write(desc_1) functional_tool_assembly.write(desc_1)
if functional_tool_assembly.sf_machine_table_tool_changing_apply_id: if functional_tool_assembly.sf_machine_table_tool_changing_apply_id:
# 修改机床换刀申请的状态 # 修改机床换刀申请的状态
self.env['sf.machine.table.tool.changing.apply'].sudo().search([ self.env['sf.machine.table.tool.changing.apply'].sudo().search([
@@ -414,71 +439,6 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
# 将刀具组装入库单的状态更改为就绪 # 将刀具组装入库单的状态更改为就绪
picking_id.action_confirm() picking_id.action_confirm()
def create_assemble_warehouse_receipt(self, functional_tool_assembly):
"""
创建功能刀具批次/序列号记录
"""
product_id = self.env['product.product'].search([('name', '=', '功能刀具')])
stock_lot = self.env['stock.lot'].create({
'name': self.get_stock_lot_name(),
'product_id': product_id.id,
'company_id': self.env.company.id
})
# 创建功能刀具该批次/序列号 库存移动和移动历史
self.create_stock_quant(product_id, stock_lot, functional_tool_assembly)
return stock_lot
def create_stock_quant(self, product_id, stock_lot, functional_tool_assembly):
"""
创建功能刀具该批次/序列号 库存移动和移动历史
"""
# 获取位置对象
stock_location_id = self.env['stock.location'].search([('name', '=', '组装后')])
location_inventory_id = self.env['stock.location'].search([('name', '=', 'Inventory adjustment')])
# 创建库存移动
stock_move_id = self.env['stock.move'].create({
'name': '功能刀具组装出库',
'product_id': product_id.id,
'location_id': location_inventory_id.id,
'location_dest_id': stock_location_id.id,
'product_uom_qty': 1.00,
'state': 'done'
})
# 创建移动历史
stock_move_line_id = self.env['stock.move.line'].create({
'product_id': product_id.id,
'functional_tool_name_id': functional_tool_assembly.id,
'lot_id': stock_lot.id,
'move_id': stock_move_id.id,
'install_tool_time': fields.Datetime.now(),
'qty_done': 1.0,
'state': 'done'
})
return stock_move_id, stock_move_line_id
def get_stock_lot_name(self):
"""
生成功能刀具序列号
"""
code = 'JKM-T-' + str(self.functional_tool_type_id.code) + '-' + str(self.functional_tool_diameter) + '-'
new_time = fields.Date.today()
code += str(new_time) + '-'
stock_lot_id = self.env['stock.lot'].sudo().search(
[('name', 'like', new_time), ('product_id.name', '=', '功能刀具')],
limit=1,
order="id desc"
)
if not stock_lot_id:
num = "%03d" % 1
else:
m = int(stock_lot_id.name[-3:]) + 1
num = "%03d" % m
return code + str(num)
def get_desc_1(self, stock_lot): def get_desc_1(self, stock_lot):
return { return {
'barcode_id': stock_lot.id, 'barcode_id': stock_lot.id,
@@ -543,3 +503,90 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
'cut_number': self.cut_number, 'cut_number': self.cut_number,
'current_location_id': stock_lot.quant_ids.location_id.ids[-1], 'current_location_id': stock_lot.quant_ids.location_id.ids[-1],
} }
class ProductProduct(models.Model):
_inherit = 'product.product'
def create_assemble_warehouse_receipt(self, tool_assembly_order_id, functional_tool_assembly):
"""
创建功能刀具批次/序列号记录
"""
product_id = self.env['product.product'].search([('name', '=', '功能刀具')])
stock_lot = self.env['stock.lot'].create({
'name': self.get_stock_lot_name(tool_assembly_order_id),
'product_id': product_id.id,
'company_id': self.env.company.id
})
# 获取位置对象
location_inventory_id = self.env['stock.location'].search([('name', '=', 'Production')])
stock_location_id = self.env['stock.location'].search([('name', '=', '组装后')])
# 创建功能刀具该批次/序列号 库存移动和移动历史
stock_lot.create_stock_quant(location_inventory_id, stock_location_id, functional_tool_assembly.id)
return stock_lot
def get_stock_lot_name(self, tool_assembly_order_id):
"""
生成功能刀具序列号
"""
tool_assembly_order = self.env['sf.functional.tool.assembly.order'].search(
[('id', '=', tool_assembly_order_id)])
code = 'JKM-T-' + str(tool_assembly_order.after_assembly_functional_tool_type_id.code) + '-' + str(
tool_assembly_order.after_assembly_functional_tool_diameter) + '-'
new_time = fields.Date.today()
code += str(new_time) + '-'
stock_lot_id = self.env['stock.lot'].sudo().search(
[('name', 'like', new_time), ('product_id.name', '=', '功能刀具')],
limit=1,
order="id desc"
)
if not stock_lot_id:
num = "%03d" % 1
else:
m = int(stock_lot_id.name[-3:]) + 1
num = "%03d" % m
return code + str(num)
def tool_material_stock_moves(self, tool_material):
"""
对刀具物料进行库存移动到 刀具组装位置
"""
# 获取位置对象
location_inventory_id = tool_material.quant_ids.location_id[-1]
print(location_inventory_id)
stock_location_id = self.env['stock.location'].search([('name', '=', '刀具组装位置')])
# 创建功能刀具该批次/序列号 库存移动和移动历史
tool_material.create_stock_quant(location_inventory_id, stock_location_id, None)
class StockLot(models.Model):
_inherit = 'stock.lot'
def create_stock_quant(self, location_inventory_id, stock_location_id, functional_tool_assembly_id):
"""
对功能刀具组装过程的功能刀具和刀具物料进行库存移动,以及创建移动历史
"""
# 创建库存移动记录
stock_move_id = self.env['stock.move'].create({
'name': '功能刀具组装',
'product_id': self.product_id.id,
'location_id': location_inventory_id.id,
'location_dest_id': stock_location_id.id,
'product_uom_qty': 1.00,
'state': 'done'
})
# 创建移动历史记录
stock_move_line_id = self.env['stock.move.line'].create({
'product_id': self.product_id.id,
'functional_tool_name_id': functional_tool_assembly_id,
'lot_id': self.id,
'move_id': stock_move_id.id,
'install_tool_time': fields.Datetime.now(),
'qty_done': 1.0,
'state': 'done'
})
return stock_move_id, stock_move_line_id

View File

@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import logging from odoo import api, fields, models
from odoo import SUPERUSER_ID, _, api, fields, models
from odoo.osv import expression from odoo.osv import expression

View File

@@ -1 +0,0 @@

View File

@@ -10,7 +10,7 @@
"depends": ['web'], "depends": ['web'],
"demo": [], "demo": [],
"data": [ "data": [
#'views/views.xml', #这是为了测试的效果,可以删除 # 'views/views.xml', #这是为了测试的效果,可以删除
], ],
'assets': { 'assets': {
'web.assets_qweb': [ 'web.assets_qweb': [
@@ -21,4 +21,4 @@
], ],
}, },
'license': 'LGPL-3', 'license': 'LGPL-3',
} }

View File

@@ -23,7 +23,6 @@ try:
import httpagentparser import httpagentparser
except ImportError: except ImportError:
pass pass
from time import gmtime, strftime
from odoo.addons.web.controllers import home from odoo.addons.web.controllers import home
from odoo.http import request from odoo.http import request
from odoo.exceptions import Warning from odoo.exceptions import Warning

View File

@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from odoo import models, fields, api, _ from odoo import models, fields
class LoginImage(models.Model): class LoginImage(models.Model):

View File

@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from odoo import api, fields, models, modules from odoo import api, fields, models
class ResConfigSettings(models.TransientModel): class ResConfigSettings(models.TransientModel):

View File

@@ -1,3 +1,3 @@
# -*-coding:utf-8-*- # -*-coding:utf-8-*-
from .import models from .import models
from .import controllers from .import controllers

View File

@@ -8,26 +8,20 @@ import werkzeug.exceptions
import werkzeug.utils import werkzeug.utils
import werkzeug.wrappers import werkzeug.wrappers
import werkzeug.wsgi import werkzeug.wsgi
from werkzeug.urls import url_parse
from odoo import http from odoo import http
from odoo.http import content_disposition, request from odoo.http import request
from odoo.tools.safe_eval import safe_eval, time
from odoo.addons.web.controllers.report import ReportController from odoo.addons.web.controllers.report import ReportController
from ..models.common import Common from ..models.common import Common
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
class ZplReportController(ReportController): class ZplReportController(ReportController):
# ------------------------------------------------------
#------------------------------------------------------
# Report controllers # Report controllers
#------------------------------------------------------ # ------------------------------------------------------
@http.route([ @http.route([
'/report/<converter>/<reportname>', '/report/<converter>/<reportname>',
'/report/<converter>/<reportname>/<docids>', '/report/<converter>/<reportname>/<docids>',
@@ -57,4 +51,4 @@ class ZplReportController(ReportController):
texthttpheaders = [('Content-Type', 'text/plain'), ('Content-Length', len(text))] texthttpheaders = [('Content-Type', 'text/plain'), ('Content-Length', len(text))]
return request.make_response(text, headers=texthttpheaders) return request.make_response(text, headers=texthttpheaders)
else: else:
raise werkzeug.exceptions.HTTPException(description='Converter %s not implemented.' % converter) raise werkzeug.exceptions.HTTPException(description='Converter %s not implemented.' % converter)

View File

@@ -18,4 +18,4 @@ class Common(models.Model):
tsclibrary.printlabelW("0", "1"); tsclibrary.printlabelW("0", "1");
tsclibrary.closeport(); tsclibrary.closeport();
except Exception as e: except Exception as e:
raise UserWarning("错误警告") raise UserWarning("错误警告:%s" % e)