diff --git a/sf_manufacturing/models/__init__.py b/sf_manufacturing/models/__init__.py index c4d8ad94..e6845317 100644 --- a/sf_manufacturing/models/__init__.py +++ b/sf_manufacturing/models/__init__.py @@ -15,4 +15,5 @@ from . import sf_technology_design from . import sf_production_common from . import sale_order from . import quick_easy_order -from . import purchase_order \ No newline at end of file +from . import purchase_order +from . import quality_check \ No newline at end of file diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 76bf6a41..8e6b889a 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -433,6 +433,7 @@ class MrpProduction(models.Model): def technology_confirm(self): process_parameters = [] account_moves = [] + purchase_orders = [] parameters_not = [] # 获取原有的工单对应的工序 origin_designs = self.workorder_ids.technology_design_id @@ -444,8 +445,10 @@ class MrpProduction(models.Model): purchase = workorder._get_surface_technics_purchase_ids() account = self.env['account.move'].search([('id', 'in', purchase.invoice_ids.ids)]) if account.state not in ['cancel', False]: - if purchase.name not in account_moves: - account_moves.append(purchase.name) + if account.name not in account_moves: + account_moves.append(account.name) + if purchase.state not in ['cancel','draft', False]: + purchase_orders.append(purchase.name) special_design = self.technology_design_ids.filtered( lambda a: a.routing_tag == 'special' and a.is_auto is False) for special in special_design: @@ -459,7 +462,9 @@ class MrpProduction(models.Model): process_parameters.append(special.process_parameters_id.display_name) if account_moves: - raise UserError(_("请联系工厂生产经理对会计凭证为%s生成的账单进行取消", ", ".join([move.name for move in account_moves]))) + raise UserError(_("请联系工厂生产经理对该(%s)账单进行取消", ", ".join(account_moves))) + if purchase_orders: + raise UserError(_("请联系工厂生产经理对该(%s)采购订单进行取消", ", ".join(purchase_orders))) if parameters_not: raise UserError(_("【工艺设计】-【工序】为%s未选择参数,请选择", ", ".join(parameters_not))) if process_parameters: @@ -692,7 +697,13 @@ class MrpProduction(models.Model): 'user': cnc.env.user.name, 'programme_way': programme_way, 'model_file': '' if not cnc.product_id.model_file else base64.b64encode( - cnc.product_id.model_file).decode('utf-8') + cnc.product_id.model_file).decode('utf-8'), + 'part_name': cnc.product_id.part_name, + 'part_number': cnc.product_id.part_number, + 'machining_drawings': base64.b64encode(cnc.product_id.machining_drawings).decode( + 'utf-8') if cnc.product_id.machining_drawings else '', + 'machining_drawings_name': cnc.product_id.machining_drawings_name, + 'machining_drawings_mimetype': cnc.product_id.machining_drawings_mimetype, } # 打印出除了 model_file 之外的所有键值对 for key, value in res.items(): @@ -839,7 +850,7 @@ class MrpProduction(models.Model): if process_parameter_workorder: # 将这些特殊表面工艺工单的采购单与调拨单置为失效 for workorder in process_parameter_workorder: - workorder._get_surface_technics_purchase_ids().write({'state': 'cancel'}) + # workorder._get_surface_technics_purchase_ids().write({'state': 'cancel'}) workorder.move_subcontract_workorder_ids.write({'state': 'cancel'}) workorder.move_subcontract_workorder_ids.picking_id.write({'state': 'cancel'}) sorted_workorders = sorted(process_parameter_workorder, key=lambda w: w.sequence) @@ -1520,7 +1531,10 @@ class MrpProduction(models.Model): """ 重载创建制造订单的方法,单个制造订单,同一成品只创建一个采购组,用于后续单据的创建 """ - group_id = self.env["procurement.group"].create({'name':vals_list[0].get('origin')}).id + group_id = False + first_origin = next((obj['origin'] for obj in vals_list if 'origin' in obj), None) + if first_origin: + group_id = self.env["procurement.group"].create({'name':first_origin}).id for vals in vals_list: if not vals.get('name', False) or vals['name'] == _('New'): picking_type_id = vals.get('picking_type_id') @@ -1528,7 +1542,7 @@ class MrpProduction(models.Model): picking_type_id = self._get_default_picking_type_id(vals.get('company_id', self.env.company.id)) vals['picking_type_id'] = picking_type_id vals['name'] = self.env['stock.picking.type'].browse(picking_type_id).sequence_id.next_by_id() - if not vals.get('procurement_group_id'): + if not vals.get('procurement_group_id') and group_id: vals['procurement_group_id'] = group_id return super(MrpProduction, self).create(vals_list) @@ -1692,6 +1706,7 @@ class sf_programming_record(models.Model): class sf_detection_result(models.Model): _name = 'sf.detection.result' _description = "检测结果" + _order = 'handle_result_date desc, id asc' production_id = fields.Many2one('mrp.production') processing_panel = fields.Char('加工面') @@ -1709,6 +1724,8 @@ class sf_detection_result(models.Model): test_report = fields.Binary('检测报告', readonly=True) handle_result = fields.Selection([("待处理", "待处理"), ("已处理", "已处理")], default='', string="处理结果", tracking=True) + handle_result_date = fields.Datetime('处理时间') + handle_result_user = fields.Many2one('res.users', '处理人') # 查看检测报告 def button_look_test_report(self): @@ -1719,6 +1736,12 @@ class sf_detection_result(models.Model): 'views': [(self.env.ref('sf_manufacturing.sf_test_report_form').id, 'form')], 'target': 'new' } + + def write(self, vals): + if vals.get('handle_result') and vals.get('handle_result') == '已处理': + vals['handle_result_date'] = fields.Datetime.now() + vals['handle_result_user'] = self.env.user.id + return super(sf_detection_result, self).write(vals) class sf_processing_panel(models.Model): diff --git a/sf_manufacturing/models/mrp_routing_workcenter.py b/sf_manufacturing/models/mrp_routing_workcenter.py index a2a884c9..666be375 100644 --- a/sf_manufacturing/models/mrp_routing_workcenter.py +++ b/sf_manufacturing/models/mrp_routing_workcenter.py @@ -26,7 +26,7 @@ class ResMrpRoutingWorkcenter(models.Model): surface_technics_id = fields.Many2one('sf.production.process', string="表面工艺") reserved_duration = fields.Float('预留时长', default=30, tracking=True) is_outsource = fields.Boolean('外协', default=False) - individuation_page = fields.Many2many('sf.work.individuation.page', string='个性化记录') + individuation_page_ids = fields.Many2many('sf.work.individuation.page', string='个性化记录') def get_no(self): international_standards = self.search( diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index e2beea1e..63e049cd 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -1344,6 +1344,21 @@ class ResMrpWorkOrder(models.Model): record.production_id.button_mark_done1() # record.production_id.state = 'done' + # ============工单完成,修改对应[质检单]的值===================== + if record.check_ids: + if record.test_results == '合格': + record.check_ids.write({'test_results': None}) + for check_id in record.check_ids: + check_id.do_pass() + elif record.test_results in ('返工', '报废'): + record.check_ids.write({ + 'test_results': record.test_results, + 'reason': record.reason, + 'detailed_reason': record.detailed_reason}) + for check_id in record.check_ids: + check_id.do_fail() + # ====================================================== + # 解绑托盘 def unbind_tray(self): for item in self: @@ -1466,6 +1481,53 @@ class ResMrpWorkOrder(models.Model): move_subcontract_workorder_ids = fields.One2many('stock.move', 'subcontract_workorder_id', string='组件') + # ==============================配置化页签--个性化记录=================================== + routing_workcenter_id = fields.Many2one('mrp.routing.workcenter', compute='_compute_routing_workcenter_id', + store=True) + individuation_page_ids = fields.Many2many('sf.work.individuation.page', string='个性化记录', store=True, + compute='_compute_individuation_page_ids') + individuation_page_PTD = fields.Boolean('个性化记录(后置三元检测PTD)', default=False) + + @api.depends('name') + def _compute_routing_workcenter_id(self): + for mw in self: + routing_workcenter_id = self.env['mrp.routing.workcenter'].sudo().search( + [('name', '=', mw.name), ('routing_type', '=', mw.routing_type)]) + if routing_workcenter_id: + mw.routing_workcenter_id = routing_workcenter_id.id + + @api.depends('routing_workcenter_id.individuation_page_ids') + def _compute_individuation_page_ids(self): + for mw in self: + if mw.routing_workcenter_id: + mw.individuation_page_ids = mw.routing_workcenter_id.individuation_page_ids.ids + # 初始化页签配置 + mw.individuation_page_PTD = False + # 根据工单对应的【作业_个性化记录】配置页签 + if any(item.code == 'PTD' for item in mw.routing_workcenter_id.individuation_page_ids): + mw.individuation_page_PTD = True + # ============================================================================================= + + is_inspect = fields.Boolean('需送检', compute='_compute_is_inspect', store=True, default=False) + + @api.depends('check_ids.is_inspect') + def _compute_is_inspect(self): + for item in self: + if item.check_ids: + is_inspect = False + for check_id in item.check_ids: + if check_id.is_inspect: + is_inspect = True + break + item.is_inspect = is_inspect + + def do_inspect(self): + """送检""" + # 修改工单状态 + self.write({'state': 'to be detected'}) + # 若关联的【质量检查_需送检】=true,则质量检查单的状态从“等待”更新为“待处理” + self.check_ids.filtered(lambda ch: ch.is_inspect is True).write({'quality_state': 'none'}) + class CNCprocessing(models.Model): _name = 'sf.cnc.processing' diff --git a/sf_manufacturing/models/product_template.py b/sf_manufacturing/models/product_template.py index 4b927596..307fbbc2 100644 --- a/sf_manufacturing/models/product_template.py +++ b/sf_manufacturing/models/product_template.py @@ -778,6 +778,8 @@ class ResProductMo(models.Model): quality_standard = fields.Binary('质检标准', readonly=True) part_name = fields.Char(string='零件名称', readonly=True) part_number = fields.Char(string='零件图号', readonly=True) + machining_drawings_name = fields.Char(string='零件图号名称', readonly=True) + machining_drawings_mimetype = fields.Char(string='零件图号类型', readonly=True) @api.constrains('tool_length') def _check_tool_length_size(self): if self.tool_length > 1000000: @@ -892,6 +894,8 @@ class ResProductMo(models.Model): item['machining_drawings']), 'quality_standard': '' if not item['quality_standard'] else base64.b64decode(item['quality_standard']), 'part_name': item.get('part_name') or '', + 'machining_drawings_name': item.get('machining_drawings_name') or '', + 'machining_drawings_mimetype': item.get('machining_drawings_mimetype') or '', } tax_id = self.env['account.tax'].sudo().search( [('type_tax_use', '=', 'sale'), ('amount', '=', item.get('tax')), ('price_include', '=', 'True')]) diff --git a/sf_manufacturing/models/quality_check.py b/sf_manufacturing/models/quality_check.py new file mode 100644 index 00000000..291e598e --- /dev/null +++ b/sf_manufacturing/models/quality_check.py @@ -0,0 +1,7 @@ +from odoo import fields, models, api + + +class QualityCheck(models.Model): + _inherit = "quality.check" + + is_inspect = fields.Boolean('需送检') diff --git a/sf_manufacturing/views/mrp_production_addional_change.xml b/sf_manufacturing/views/mrp_production_addional_change.xml index 60d88a21..d844cf66 100644 --- a/sf_manufacturing/views/mrp_production_addional_change.xml +++ b/sf_manufacturing/views/mrp_production_addional_change.xml @@ -343,6 +343,10 @@ + + + +