diff --git a/jikimo_frontend/static/src/js/custom_form_status_indicator.js b/jikimo_frontend/static/src/js/custom_form_status_indicator.js index 7db13b4b..100542b8 100644 --- a/jikimo_frontend/static/src/js/custom_form_status_indicator.js +++ b/jikimo_frontend/static/src/js/custom_form_status_indicator.js @@ -4,6 +4,7 @@ import {patch} from '@web/core/utils/patch'; // import { Dialog } from "@web/core/dialog/dialog"; import {_t} from "@web/core/l10n/translation"; import {FormStatusIndicator} from "@web/views/form/form_status_indicator/form_status_indicator"; +import {ListRenderer} from "@web/views/list/list_renderer"; import {Field} from "@web/views/fields/field"; @@ -45,6 +46,11 @@ const filedRequiredList = { 'date_planned_start': { multiple: false, noLabel: false }, 'date_planned_finished': { multiple: false, noLabel: false }, } +const tableRequiredList = [ + 'product_template_id', 'product_uom_qty', 'price_unit','product_id','product_qty', + 'name', 'fault_type', 'maintenance_standards', 'Period' +] + patch(FormStatusIndicator.prototype, 'jikimo_frontend.FormStatusIndicator', { // 你可以重写或者添加一些方法和属性 async _onDiscardChanges() { @@ -110,7 +116,24 @@ patch(Field.prototype, 'jikimo_frontend.Field', { } } }) - +patch(ListRenderer.prototype, 'jikimo_frontend.ListRenderer', { + setup(){ + owl.onMounted(() => { + this.activeElement = this.uiService.activeElement; + this.setRequired() + }) + return this._super(...arguments); + }, + setRequired() { + this.allColumns.forEach(_ => { + if( tableRequiredList.indexOf(_.name) >= 0 ) { + const dom = $(`th[data-name=${_.name}]`) + let t = dom.html() + dom.html('*' + t) + } + }) + } +}) $(function () { document.addEventListener('click', function () { @@ -160,45 +183,13 @@ $(function () { }, 500) } - function setRequired(dom = {label: [], table: []}) { - let domTimer = null - let timer_count = 0 - clearInterval(domTimer) - domTimer = setInterval(() => { - timer_count++ - const lint = $('.o_form_view_container') - if (lint.length) { - clearInterval(domTimer) - const { table} = dom - - if (table.length) { - table.forEach(_ => { - const th = $(`th[data-name=${_}]`) - const t = th.find('span').eq(0).text().replace('*','') - th.find('span').eq(0).html('*' + t) - - }) - - } - } - if (timer_count == 20) { - clearInterval(domTimer) - } - }, 500) - } - var currentUrl = location.href - const customRequiredDom = { - table: ['product_template_id', 'product_uom_qty', 'price_unit','product_id','product_qty', 'name', 'fault_type', 'maintenance_standards', 'Period'] - } const listenerUrl = setInterval(() => { const isChange = currentUrl != location.href if (isChange) { currentUrl = location.href customRequired() - setRequired(customRequiredDom) } }, 500) customRequired() - setRequired(customRequiredDom) }) diff --git a/jikimo_frontend/static/src/scss/custom_style.scss b/jikimo_frontend/static/src/scss/custom_style.scss index bc1be730..f7195534 100644 --- a/jikimo_frontend/static/src/scss/custom_style.scss +++ b/jikimo_frontend/static/src/scss/custom_style.scss @@ -467,3 +467,15 @@ div:has(.o_required_modifier) > label::before { background: #71639e; color: #fff } + +// 修改时间输入框宽度 +.o_datepicker_input.o_input.datetimepicker-input { + width: 200px; +} + + +.o_form_view .o_form_editable .o_row > .o_field_widget, .o_form_view .o_form_editable .o_row > .o_field_widget.o_field_float_time { + width: auto !important; + flex: unset; +} + diff --git a/sf_base/models/tool_base_new.py b/sf_base/models/tool_base_new.py index a3a9e172..f2010b4a 100644 --- a/sf_base/models/tool_base_new.py +++ b/sf_base/models/tool_base_new.py @@ -308,3 +308,28 @@ class ToolGroups(models.Model): # records = super(ToolGroups, self).create(vals_list) # self._register_tool_groups(records) # return records + + +class ToolInventory(models.Model): + _name = 'sf.tool.inventory' + _description = '功能刀具清单' + + name = fields.Char('功能刀具名称', required=True) + type = fields.Char('类型') + functional_cutting_tool_model_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型') + prefix = fields.Char('前缀') + postfix = fields.Char('后缀') + diameter = fields.Float('直径(mm)') + angle = fields.Float('R角(mm)') + tool_length = fields.Float('刀具总长(mm)') + blade_length = fields.Float('避空长/刃长(mm)') + knife_head_name = fields.Char('刀头名称') + cutter_number = fields.Char('刀号') + blade_number = fields.Integer('刃数(个)') + extension = fields.Float('伸出长度(mm)') + work_material = fields.Selection([('钢', '钢'), ('铝', '铝')], string='加工材料') + life_span = fields.Float('寿命(h)') + + tool_groups_id = fields.Many2one('sf.tool.groups', string='刀具组') + + active = fields.Boolean('已归档', default=True) diff --git a/sf_base/security/ir.model.access.csv b/sf_base/security/ir.model.access.csv index 2a3cd471..9d027bdb 100644 --- a/sf_base/security/ir.model.access.csv +++ b/sf_base/security/ir.model.access.csv @@ -192,4 +192,11 @@ access_sf_machine_brand_tags_group_purchase_director,sf_machine_brand_tags_group access_printer,printer,model_printer,base.group_user,1,1,1,1 -access_printer_configuration,printer.configuration,model_printer_configuration,base.group_user,1,1,1,1 \ No newline at end of file +access_printer_configuration,printer.configuration,model_printer_configuration,base.group_user,1,1,1,1 + +access_group_sf_mrp_user,sf_tool_inventory,model_sf_tool_inventory,base.group_user,1,1,1,0 +access_group_sf_mrp_user_admin,sf_tool_inventory_admin,model_sf_tool_inventory,base.group_system,1,1,1,0 +access_group_sf_mrp_user_group_purchase_director,sf_tool_inventory_group_purchase_director,model_sf_tool_inventory,sf_base.group_purchase_director,1,0,1,0 +access_group_sf_mrp_user_group_sale_director,sf_tool_inventory_group_sale_director,model_sf_tool_inventory,sf_base.group_sale_director,1,0,1,0 +access_sf_cutting_tool_material_group_plan_director,sf_tool_inventory_group_plan_director,model_sf_tool_inventory,sf_base.group_plan_director,1,0,1,0 +access_group_sf_mrp_user_group_sf_mrp_user,sf_tool_inventory_group_sf_mrp_user,model_sf_tool_inventory,sf_base.group_sf_mrp_user,1,1,0,0 \ No newline at end of file diff --git a/sf_base/static/src/scss/test.scss b/sf_base/static/src/scss/test.scss index fdc5821e..c91a8a77 100644 --- a/sf_base/static/src/scss/test.scss +++ b/sf_base/static/src/scss/test.scss @@ -189,3 +189,6 @@ td.o_required_modifier { flex-direction: row !important; } +.supplier_ids_set_css thead th[data-name=partner_id]{ + width: 500px!important; +} \ No newline at end of file diff --git a/sf_base/views/common_view.xml b/sf_base/views/common_view.xml index 0826b51c..e829274a 100644 --- a/sf_base/views/common_view.xml +++ b/sf_base/views/common_view.xml @@ -269,7 +269,7 @@ - + diff --git a/sf_base/views/tool_menu.xml b/sf_base/views/tool_menu.xml index 506a73df..bad606d6 100644 --- a/sf_base/views/tool_menu.xml +++ b/sf_base/views/tool_menu.xml @@ -59,14 +59,14 @@ id="menu_sf_cutting_tool_type" parent="menu_sf_cutting_tool" name="刀具类型" - sequence="2" + sequence="10" action="action_sf_cutting_tool_type" /> @@ -82,7 +82,7 @@ id="menu_sf_functional_cutting_tool_model_type" parent="menu_sf_cutting_tool" name="功能刀具类型" - sequence="4" + sequence="30" action="action_sf_functional_cutting_tool_model_type" /> @@ -91,14 +91,14 @@ name="能力特征库" parent="menu_sf_cutting_tool" action="action_maintenance_equipment_image" - sequence="5"/> + sequence="40"/> + sequence="50"/> diff --git a/sf_base/views/tool_views.xml b/sf_base/views/tool_views.xml index 34b87a41..e52a6222 100644 --- a/sf_base/views/tool_views.xml +++ b/sf_base/views/tool_views.xml @@ -123,7 +123,7 @@
+ required="1"/>

@@ -547,7 +547,75 @@ - + ' + + + + sf.tool.inventory.tree + sf.tool.inventory + + + + + + + + + + + + + + + + + + + + + + + + + + sf.tool.inventory.search + sf.tool.inventory + + + + + + + + + + + + + + + + + + + + + + + + 功能刀具清单 + ir.actions.act_window + sf.tool.inventory + tree + + + diff --git a/sf_manufacturing/controllers/controllers.py b/sf_manufacturing/controllers/controllers.py index c548222a..63fd4f57 100644 --- a/sf_manufacturing/controllers/controllers.py +++ b/sf_manufacturing/controllers/controllers.py @@ -238,7 +238,7 @@ class Manufacturing_Connect(http.Controller): workorder = request.env['mrp.workorder'].sudo().search( [('production_id', '=', production_id), ('routing_type', '=', routing_type)], limit=1) if workorder: - workorder.test_result = ret['Quality'] + # workorder.test_results = ret['Quality'] logging.info('制造订单:%s' % workorder.production_id.name) if 'ReportPaht' in ret: download_state = request.env['mrp.workorder'].with_user( @@ -261,8 +261,7 @@ class Manufacturing_Connect(http.Controller): ('picking_id', '=', stock_picking.id)]) if quality_check: logging.info('质检单:%s' % quality_check.name) - quality_check.write({'report_pdf': workorder.detection_report, - 'report_result': workorder.test_result}) + quality_check.write({'report_pdf': workorder.detection_report}) elif download_state == 2: res = {'Succeed': False, 'ErrorCode': 205, 'Error': 'ReportPaht中的工件号与制造订单%s不匹配,请检查ReportPaht是否正确' % workorder.production_id.name} diff --git a/sf_manufacturing/data/stock_data.xml b/sf_manufacturing/data/stock_data.xml index 6bd0fe53..72559691 100644 --- a/sf_manufacturing/data/stock_data.xml +++ b/sf_manufacturing/data/stock_data.xml @@ -67,5 +67,21 @@ search="[('barcode','=','WH-PREPRODUCTION')]"/> + + + 表面工艺外协 + + True + 11 + + + + + + + + + + diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index 7b3467b7..89510ae0 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -1,3 +1,5 @@ +import re + import logging import base64 import urllib.parse @@ -96,7 +98,8 @@ class ResMrpWorkOrder(models.Model): Y10_axis = fields.Float(default=0) Z10_axis = fields.Float(default=0) X_deviation_angle = fields.Integer(string="X轴偏差度", default=0) - test_result = fields.Char("检测结果") + test_results = fields.Selection([("合格", "合格"), ("返工", "返工"), ("报废", "报废")], default='合格', + string="检测结果") cnc_ids = fields.One2many("sf.cnc.processing", 'workorder_id', string="CNC加工程序") cmm_ids = fields.One2many("sf.cmm.program", 'workorder_id', string="CMM程序") tray_code = fields.Char(string="托盘编码") @@ -141,6 +144,7 @@ class ResMrpWorkOrder(models.Model): production_line_state = fields.Selection(related='production_id.production_line_state', string='上/下产线', store=True) detection_report = fields.Binary('检测报告', readonly=True) + is_remanufacture = fields.Boolean(string='是否重新生成制造订单', default=True) def get_plan_workorder(self, production_line): tomorrow = (date.today() + timedelta(days=+1)).strftime("%Y-%m-%d") @@ -444,7 +448,7 @@ class ResMrpWorkOrder(models.Model): """ 重新生成制造订单或者重新生成工单 """ - if self.test_result == '报废': + if self.test_results == '报废': values = self.env['mrp.production'].create_production1_values(self.production_id) productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company( self.production_id.company_id).create( @@ -476,7 +480,7 @@ class ResMrpWorkOrder(models.Model): 'mail.message_origin_link', values={'self': production, 'origin': origin_production}, subtype_id=self.env.ref('mail.mt_note').id) - if self.test_result == '返工': + if self.test_results == '返工': productions = self.production_id # self.env['stock.move'].sudo().create(productions._get_moves_raw_values()) # self.env['stock.move'].sudo().create(productions._get_moves_finished_values()) @@ -606,6 +610,8 @@ class ResMrpWorkOrder(models.Model): if self.routing_type == '装夹预调': if not self.material_center_point and self.X_deviation_angle > 0: raise UserError("请对前置三元检测定位参数进行计算定位") + if not self.rfid_code: + raise UserError("请扫RFID码进行绑定") if self.picking_out_id: picking_out = self.env['stock.picking'].search([('id', '=', self.picking_out_id.id)]) if picking_out.workorder_out_id: @@ -819,25 +825,33 @@ class SfWorkOrderBarcodes(models.Model): workorder = self.env['mrp.workorder'].browse(self.ids) # workorder = self.env['mrp.workorder'].search( # [('routing_type', '=', '装夹预调'), ('production_id', '=', self.production_id.id)]) + # workorder_old = self.env['mrp.workorder'].search([('rfid_code', '=', barcode)]) + # if workorder_old: + # raise UserError('该托盘已绑定工件,请先解除绑定!!!') 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' - # } + if workorder.state in ['progress', 'done']: + work_state = {'progress': '进行中', 'done': '已完工'} + raise UserError('该工单%s,不能重新绑定托盘' % work_state.get(workorder.state)) + lots = self.env['stock.lot'].sudo().search([('rfid', '=', barcode)]) + if lots: + for lot in lots: + if lot.product_id.categ_type == '夹具': + val = { + 'tray_serial_number': lot.name, + 'tray_product_id': lot.product_id.id, + 'tray_brand_id': lot.product_id.brand_id.id, + 'tray_type_id': lot.product_id.fixture_material_id.id, + 'tray_model_id': lot.product_id.fixture_model_id.id, + 'rfid_code': barcode + } + workorder.write(val) + self.write(val) + workorder_rfid = self.env['mrp.workorder'].search( + [('production_id', '=', workorder.production_id.id)]) + if workorder_rfid: + for item in workorder_rfid: + item.write({'rfid_code': barcode}) else: embryo_stock_lot = self.env['stock.lot'].search([('name', '=', barcode)]) if embryo_stock_lot: @@ -869,7 +883,58 @@ class SfWorkOrderBarcodes(models.Model): [('production_id', '=', workorder.production_id.id)]) if workorder_rfid: for item in workorder_rfid: - item.write({'rfid_code': barcode}) + if item.state == "progress": + item.write({'rfid_code': barcode}) + raise UserError('该托盘信息不存在!!!') + # stock_move_line = self.env['stock.move.line'].search([('lot_name', '=', barcode)]) + # if stock_move_line.product_id.categ_type == '夹具': + # 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('工件生产线不一致,请重新确认') + # else: + # workorder_rfid = self.env['mrp.workorder'].search( + # [('production_id', '=', workorder.production_id.id)]) + # if workorder_rfid: + # for item in workorder_rfid: + # item.write({'rfid_code': barcode}) class WorkPieceDelivery(models.Model): @@ -909,16 +974,24 @@ class WorkPieceDelivery(models.Model): # 配送至avg小车 def _delivery_avg(self): - res = {'reqCode': urllib.parse.quote(self.production_id.name), 'reqTime': '', 'clientCode': '', 'tokenCode': '', - 'taskTyp': 'F01', 'ctnrTyp': '', 'ctnrCode': '', 'wbCode': '006848AB006774', 'positionCodePath': [], + config = self.env['res.config.settings'].get_values() + agv_site = self.env['res.agv.site'].search([]) + positionCode_Arr = [] + if agv_site: + for item in agv_site: + positionCode_Arr.append({ + 'positionCode': item.content, + 'code': item.type + }) + res = {'reqCode': self.production_id.name, 'reqTime': '', 'clientCode': '', 'tokenCode': '', + 'taskTyp': config['task_type_no'], 'ctnrTyp': '', 'ctnrCode': '', 'wbCode': config['wbcode'], + 'positionCodePath': positionCode_Arr, 'podCode': '', 'podDir': '', 'materialLot': '', 'priority': '', 'taskCode': '', 'agvCode': '', 'materialLot': '', 'data': ''} - config = self.env['res.config.settings'].get_values() try: logging.info('AGV请求路径:%s' % config['agv_rcs_url']) logging.info('AGV-json:%s' % res) - headers = {'Content-Type': 'application/json'} ret = requests.post((config['agv_rcs_url']), json=res, headers=headers) ret = ret.json() diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index be0c09ae..f3cba150 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -6,12 +6,11 @@ import os from odoo import models, fields, api, _ from odoo.exceptions import ValidationError from odoo.modules import get_resource_path - - from OCC.Extend.DataExchange import read_step_file from OCC.Extend.DataExchange import write_stl_file + class ResProductMo(models.Model): _inherit = 'product.template' @@ -107,7 +106,10 @@ class ResProductMo(models.Model): @api.onchange('cutting_tool_model_id') def _onchange_cutting_tool_model_id(self): - self.specification_id = False + for item in self: + if item: + item.specification_id = False + item.cutting_tool_chuck_id = item.cutting_tool_model_id.chuck_id @api.onchange('cutting_tool_material_id') def _onchange_cutting_tool_material_id(self): @@ -310,7 +312,6 @@ class ResProductMo(models.Model): self.cutting_tool_is_safety_lock = self.specification_id.is_safe_lock self.cutting_tool_fit_nut_model = self.specification_id.nut self.cutting_tool_wrench = self.specification_id.spanner - self.cutting_tool_chuck_id = self.specification_id.chuck_id.id self.cutting_tool_jump_accuracy = self.specification_id.diameter_slip_accuracy self.cutting_tool_taper_shank_model = self.specification_id.taper_shank_model self.cutting_tool_cooling_type = self.specification_id.cooling_model diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index b85f7ac4..80a334ce 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -17,6 +17,50 @@ from io import BytesIO from odoo.exceptions import ValidationError +class stockWarehouse(models.Model): + _inherit = 'stock.warehouse' + + subcontracting_surface_technology_pull_out_id = fields.Many2one( + 'stock.rule', '表面工艺规则1') + subcontracting_surface_technology_pull_in_id = fields.Many2one( + 'stock.rule', '表面工艺规则2' + ) + + def _get_global_route_rules_values(self): + rules = super(stockWarehouse, self)._get_global_route_rules_values() + location_virtual_id = self.env.ref( + 'sf_manufacturing.stock_location_locations_virtual_outcontract').id, + location_pre_id = self.env['stock.location'].search( + [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id, + rules.update({ + 'subcontracting_surface_technology_pull_in_id': { + 'create_values': { + 'action': 'pull', + 'picking_type_id': self.env.ref('sf_manufacturing.outcontract_picking_in').id, + 'group_propagation_option': 'none', + 'company_id': self.company_id.id, + 'location_src_id': location_virtual_id, + 'location_dest_id': location_pre_id, + 'route_id': self._find_global_route('sf_manufacturing.route_surface_technology_outsourcing', + _('表面工艺外协')).id, + } + }, + 'subcontracting_surface_technology_pull_out_id': { + 'create_values': { + 'action': 'pull', + 'picking_type_id': self.env.ref('sf_manufacturing.outcontract_picking_out').id, + 'group_propagation_option': 'none', + 'company_id': self.company_id.id, + 'location_src_id': location_pre_id, + 'location_dest_id': location_virtual_id, + 'route_id': self._find_global_route('sf_manufacturing.route_surface_technology_outsourcing', + _('表面工艺外协')).id, + } + } + }) + return rules + + class StockRule(models.Model): _inherit = 'stock.rule' @@ -222,6 +266,21 @@ class ProductionLot(models.Model): _name = 'stock.lot' _inherit = ['stock.lot', 'printing.utils'] + rfid = fields.Char('Rfid', readonly=True) + product_specification = fields.Char('规格', compute='_compute_product_specification', store=True) + + @api.depends('product_id') + def _compute_product_specification(self): + for stock in self: + if stock: + if stock.product_id: + if stock.product_id.categ_id.name in '刀具': + stock.product_specification = stock.product_id.specification_id.name + elif stock.product_id.categ_id.name in '夹具': + stock.product_specification = stock.product_id.specification_fixture_id.name + else: + stock.product_specification = stock.product_id.default_code + @api.model def generate_lot_names1(self, display_name, first_lot, count): """Generate `lot_names` from a string.""" @@ -264,7 +323,7 @@ class ProductionLot(models.Model): if not last_serial: return "%s-%s%03d" % (product.cutting_tool_model_id.code[:-12], now, 1) else: - return "%s-%s%03d" % (product.cutting_tool_model_id.code[:-12], now, int(last_serial.name[-3:]) + 2) + return "%s-%s%03d" % (product.cutting_tool_model_id.code[:-12], now, int(last_serial.name[-3:]) + 1) else: raise ValidationError('该刀具物料产品的型号字段为空,请补充完整!!!') diff --git a/sf_manufacturing/views/mrp_production_addional_change.xml b/sf_manufacturing/views/mrp_production_addional_change.xml index 0ae0d95f..6ba78573 100644 --- a/sf_manufacturing/views/mrp_production_addional_change.xml +++ b/sf_manufacturing/views/mrp_production_addional_change.xml @@ -422,7 +422,8 @@
规格: - + +
[] diff --git a/sf_manufacturing/views/mrp_workorder_view.xml b/sf_manufacturing/views/mrp_workorder_view.xml index 4a766526..9a747791 100644 --- a/sf_manufacturing/views/mrp_workorder_view.xml +++ b/sf_manufacturing/views/mrp_workorder_view.xml @@ -104,18 +104,14 @@ - +

+ + + + + diff --git a/sf_manufacturing/views/stock_lot_views.xml b/sf_manufacturing/views/stock_lot_views.xml index bd04005c..aef50e55 100644 --- a/sf_manufacturing/views/stock_lot_views.xml +++ b/sf_manufacturing/views/stock_lot_views.xml @@ -13,6 +13,12 @@