diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py index 0572401f..118af095 100644 --- a/sf_manufacturing/models/mrp_production.py +++ b/sf_manufacturing/models/mrp_production.py @@ -56,6 +56,7 @@ class MrpProduction(models.Model): production.deadline_of_delivery = False else: production.deadline_of_delivery = False + def _compute_default_delivery_status(self): try: if self.state == 'cancel': @@ -250,6 +251,7 @@ class MrpProduction(models.Model): remanufacture_count = fields.Integer("重新制造订单数量", compute='_compute_remanufacture_production_ids') remanufacture_production_id = fields.Many2one('mrp.production', string='') technology_design_ids = fields.One2many('sf.technology.design', 'production_id', string='工艺设计') + is_adjust = fields.Boolean('是否退回调整', default=False) @api.depends('remanufacture_production_id') def _compute_remanufacture_production_ids(self): @@ -276,7 +278,7 @@ class MrpProduction(models.Model): @api.depends( 'move_raw_ids.state', 'move_raw_ids.quantity_done', 'move_finished_ids.state', 'tool_state', - 'workorder_ids.state', 'product_qty', 'qty_producing', 'schedule_state') + 'workorder_ids.state', 'product_qty', 'qty_producing', 'schedule_state', 'programming_state') def _compute_state(self): for production in self: if not production.state or not production.product_uom_id: @@ -309,7 +311,7 @@ class MrpProduction(models.Model): # 新添加的状态逻辑 if ( production.state == 'to_close' or production.state == 'progress') and production.schedule_state == '未排': - if not production.workorder_ids: + if not production.workorder_ids or production.is_adjust is True: production.state = 'technology_to_confirmed' else: production.state = 'confirmed' @@ -675,27 +677,22 @@ class MrpProduction(models.Model): 'operation_id': operation.id, 'state': 'pending', }] - if production.product_id.categ_id.type == '成品': + if production.product_id.categ_id.type in ['成品', '坯料']: # # 根据工序设计生成工单 for route in production.technology_design_ids: - if route.route_id.routing_type not in ['表面工艺']: - workorders_values.append( - self.env['mrp.workorder'].json_workorder_str(production, route)) - else: - product_production_process = self.env['product.template'].search( - [('server_product_process_parameters_id', '=', route.process_parameters_id.id)]) - workorders_values.append( - self.env[ - 'mrp.workorder']._json_workorder_surface_process_str( - production, route, product_production_process.seller_ids[0].partner_id.id)) - elif production.product_id.categ_id.type == '坯料': - embryo_routing_workcenter = self.env['sf.embryo.model.type.routing.sort'].search( - [('embryo_model_type_id', '=', production.product_id.embryo_model_type_id.id)], - order='sequence asc' - ) - for route_embryo in embryo_routing_workcenter: - workorders_values.append( - self.env['mrp.workorder'].json_workorder_str('', production, route_embryo)) + workorder_has = self.env['mrp.workorder'].search( + [('name', '=', route.route_id.name), ('production_id', '=', production.id)]) + if not workorder_has: + if route.route_id.routing_type not in ['表面工艺']: + workorders_values.append( + self.env['mrp.workorder'].json_workorder_str(production, route)) + else: + product_production_process = self.env['product.template'].search( + [('server_product_process_parameters_id', '=', route.process_parameters_id.id)]) + workorders_values.append( + self.env[ + 'mrp.workorder']._json_workorder_surface_process_str( + production, route, product_production_process.seller_ids[0].partner_id.id)) production.workorder_ids = workorders_values for workorder in production.workorder_ids: workorder.duration_expected = workorder._get_duration_expected() @@ -717,7 +714,7 @@ class MrpProduction(models.Model): sorted_workorders = sorted(process_parameter_workorder, key=lambda w: w.sequence) for i, workorder in enumerate(sorted_workorders): # 检查当前工作订单和下一个工作订单是否连续,并且供应商相同 - if workorder.sequence == 1: + if i == 0: consecutive_workorders.append(workorder) elif workorder.sequence == sorted_workorders[ i - 1].sequence + 1 and workorder.supplier_id.id == sorted_workorders[i - 1].supplier_id.id: @@ -725,7 +722,7 @@ class MrpProduction(models.Model): else: # 处理连续组,如果它不为空 if consecutive_workorders: - # 创建出库拣货单和采购订单 + # 创建外协出入库单和采购订单 self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production) self.env['purchase.order'].get_purchase_order(consecutive_workorders, production, product_id_to_production_names) @@ -739,7 +736,7 @@ class MrpProduction(models.Model): i - 1].supplier_id.id: consecutive_workorders = [workorder] else: - # 立即创建出库拣货单和采购订单 + # 立即创建外协出入库单和采购订单 self.env['stock.picking'].create_outcontract_picking(workorder, production) self.env['purchase.order'].get_purchase_order(workorder, production, product_id_to_production_names) @@ -817,6 +814,36 @@ class MrpProduction(models.Model): self._reset_work_order_sequence1(k) return True + # 需对不连续工单对应的采购单和外协出入库单做处理 + def _reset_subcontract_pick_purchase(self): + production_all = self.sorted(lambda x: x.id) + product_id_to_production_names = {} + grouped_product_ids = {k: list(g) for k, g in + groupby(production_all, key=lambda x: x.product_id.id)} + for product_id, pd in grouped_product_ids.items(): + product_id_to_production_names[product_id] = [p.name for p in pd] + for item in production_all: + production_process = product_id_to_production_names.get(item.product_id.id) + workorder_sf = item.workorder_ids.filtered(lambda sf: sf.routing_type == '表面工艺') + for i, workorder in enumerate(workorder_sf): + if i == 0: + continue + elif workorder.sequence != workorder_sf[i - 1].sequence + 1: + # workorder.picking_ids.move_ids = False + workorder.picking_ids = False + purchase_order = self.env['purchase.order'].search( + [('state', '=', 'draft'), ('origin', '=', ','.join(production_process)), + ('purchase_type', '=', 'consignment')]) + for line in purchase_order.order_line: + server_template = self.env['product.template'].search( + [('server_product_process_parameters_id', '=', workorder.surface_technics_parameters_id.id), + ('detailed_type', '=', 'service')]) + purchase_order_line = self.env['purchase.order.line'].search( + [('product_id', '=', server_template.product_variant_id.id), ('id', '=', line.id), + ('product_qty', '=', len(production_process))], limit=1, order='id desc') + if purchase_order_line: + line.unlink() + def _reset_work_order_sequence(self): """ 工单工序排序方法(新) @@ -834,7 +861,8 @@ class MrpProduction(models.Model): work_id.sequence = order_id.sequence + 1 break # 对该工单之后的工单工序进行加一 - work_order_ids = rec.workorder_ids.filtered(lambda item: item.sequence >= work_id.sequence) + work_order_ids = rec.workorder_ids.filtered( + lambda item: item.sequence >= work_id.sequence and item.id != work_id.id) for work in work_order_ids: work.sequence = work.sequence + 1 @@ -954,15 +982,17 @@ class MrpProduction(models.Model): last_time = pro_plan.date_planned_start # 预置时间 works = self.workorder_ids - for index,work in enumerate(works): + for index, work in enumerate(works): count = type_map.get(work.routing_type) date_planned_end = None date_planned_start = None - if self.production_type=='自动化产线加工': - date_planned_start,date_planned_end,last_time = work.auto_production_process(last_time,count,type_map) - elif self.production_type=='': - date_planned_start,date_planned_end,last_time = work.manual_offline_process(last_time,index) - work.update_work_start_end(date_planned_start,date_planned_end) + if self.production_type == '自动化产线加工': + date_planned_start, date_planned_end, last_time = work.auto_production_process(last_time, count, + type_map) + elif self.production_type == '': + date_planned_start, date_planned_end, last_time = work.manual_offline_process(last_time, index) + work.update_work_start_end(date_planned_start, date_planned_end) + # def def process_range_time(self): for production in self: @@ -1104,6 +1134,7 @@ class MrpProduction(models.Model): 'target': 'new', 'context': { 'default_production_id': self.id, + 'default_workorder_ids': self.workorder_ids.filtered(lambda wk: wk.state == 'done').ids, 'default_reprogramming_num': cloud_programming['reprogramming_num'], 'default_programming_state': cloud_programming['programming_state'], 'default_is_reprogramming': True if cloud_programming['programming_state'] in ['已下发'] else False @@ -1229,6 +1260,7 @@ class MrpProduction(models.Model): 重新生成制造订单 """ if self.is_scrap is True: + technology_design_values = [] procurement_requests = [] sale_order = self.env['sale.order'].sudo().search([('name', '=', self.origin)]) values = self.env['mrp.production'].create_production1_values(self) @@ -1259,11 +1291,13 @@ class MrpProduction(models.Model): [('origin', '=', self.origin)], order='id desc', limit=1) move = self.env['stock.move'].search([('origin', '=', productions.name)], order='id desc') for mo in move: + domain = [] if mo.procure_method == 'make_to_order' and mo.name != productions.name: if mo.name == '/': domain = [('barcode', '=', 'WH-PC'), ('sequence_code', '=', 'PC')] elif mo.name == '拉': domain = [('barcode', '=', 'WH-INTERNAL'), ('sequence_code', '=', 'INT')] + if domain: picking_type = self.env['stock.picking.type'].search(domain) mo.write({'picking_type_id': picking_type.id}) mo._assign_picking() @@ -1315,10 +1349,72 @@ class MrpProduction(models.Model): if purchase_orders.origin.find(productions.name) == -1: purchase_orders.origin += ',' + productions.name if item['is_reprogramming'] is False: - productions._create_workorder(item) productions.programming_state = '已编程' else: productions.programming_state = '编程中' + if not technology_design_values: + i = 0 + if self.product_id.categ_id.type == '成品': + # 根据加工面板的面数及成品工序模板生成工序设计 + for k in (self.product_id.model_processing_panel.split(',')): + if self.production_type == '自动化产线加工': + product_routing_workcenter = self.env['sf.product.model.type.routing.sort'].search( + [('product_model_type_id', '=', + self.product_id.product_model_type_id.id)], + order='sequence asc' + ) + else: + product_routing_workcenter = self.env[ + 'sf.manual.product.model.type.routing.sort'].search( + [('manual_product_model_type_id', '=', + self.product_id.product_model_type_id.id)], + order='sequence asc' + ) + for route in product_routing_workcenter: + i += 1 + technology_design_values.append( + self.env['sf.technology.design'].json_technology_design_str(k, route, i, False)) + elif self.product_id.categ_id.type == '坯料': + i = 0 + embryo_routing_workcenter = self.env['sf.embryo.model.type.routing.sort'].search( + [('embryo_model_type_id', '=', self.product_id.embryo_model_type_id.id)], + order='sequence asc' + ) + for route_embryo in embryo_routing_workcenter: + i += 1 + technology_design_values.append( + self.env['sf.technology.design'].json_technology_design_str(False, route_embryo, i, + False)) + surface_technics_arr = [] + route_workcenter_arr = [] + for item in self.product_id.product_model_type_id.surface_technics_routing_tmpl_ids: + if item.route_workcenter_id.surface_technics_id.id: + for process_param in self.product_id.model_process_parameters_ids: + if item.route_workcenter_id.surface_technics_id == process_param.process_id: + surface_technics_arr.append( + item.route_workcenter_id.surface_technics_id.id) + route_workcenter_arr.append(item.route_workcenter_id.id) + if surface_technics_arr: + production_process = self.env['sf.production.process'].search( + [('id', 'in', surface_technics_arr)], + order='sequence asc' + ) + for p in production_process: + # logging.info('production_process:%s' % p.name) + process_parameter = self.product_id.model_process_parameters_ids.filtered( + lambda pm: pm.process_id.id == p.id) + if process_parameter: + i += 1 + route_production_process = self.env[ + 'mrp.routing.workcenter'].search( + [('surface_technics_id', '=', p.id), + ('id', 'in', route_workcenter_arr)]) + technology_design_values.append( + self.env['sf.technology.design'].json_technology_design_str(False, + route_production_process, + i, + process_parameter)) + productions.technology_design_ids = technology_design_values return productions # 在之前的销售单上重新生成制造订单 diff --git a/sf_manufacturing/models/mrp_workorder.py b/sf_manufacturing/models/mrp_workorder.py index db33abac..48099f88 100644 --- a/sf_manufacturing/models/mrp_workorder.py +++ b/sf_manufacturing/models/mrp_workorder.py @@ -145,7 +145,7 @@ class ResMrpWorkOrder(models.Model): tag_type = fields.Selection([("重新加工", "重新加工")], string="标签", tracking=True) def _compute_default_construction_period_status(self): - need_list=['pending', 'waiting', 'ready', 'progress', 'to be detected','done'] + need_list = ['pending', 'waiting', 'ready', 'progress', 'to be detected', 'done'] try: if self.state not in need_list: return False @@ -154,9 +154,9 @@ class ResMrpWorkOrder(models.Model): hours = self.get_hours_diff() if hours >= 12: return '正常' - elif hours > 0 and hours < 12 and self.state!='done': + elif hours > 0 and hours < 12 and self.state != 'done': return '预警' - elif hours > 0 and hours < 12 and self.state=='done': + elif hours > 0 and hours < 12 and self.state == 'done': return '正常' else: return '已逾期' @@ -168,7 +168,7 @@ class ResMrpWorkOrder(models.Model): def _compute_construction_period_status(self): for worker in self: construction_period_status = worker._compute_default_construction_period_status() - if construction_period_status and worker.construction_period_status!=construction_period_status: + if construction_period_status and worker.construction_period_status != construction_period_status: worker.construction_period_status = construction_period_status construction_period_status = fields.Selection([('正常', '正常'), ('预警', '预警'), ('已逾期', '已逾期')], @@ -199,14 +199,17 @@ class ResMrpWorkOrder(models.Model): func(records) # 增加页码 page_number += 1 - def run_compute_construction_period_status(self,records): + + def run_compute_construction_period_status(self, records): records._compute_construction_period_status() + def _corn_update_construction_period_status(self): - need_list=['pending', 'waiting', 'ready', 'progress', 'to be detected'] + need_list = ['pending', 'waiting', 'ready', 'progress', 'to be detected'] # need_list = [ # 'progress', # 'to be detected'] - self.get_page_all_records('mrp.workorder',self.run_compute_construction_period_status,[('state', 'in', need_list)],100) + self.get_page_all_records('mrp.workorder', self.run_compute_construction_period_status, + [('state', 'in', need_list)], 100) def get_hours_diff(self): # 获取当前日期和时间 @@ -230,16 +233,16 @@ class ResMrpWorkOrder(models.Model): def _compute_surface_technics_picking_ids(self): for workorder in self: if workorder.routing_type == '表面工艺': - domain = [('origin', '=', workorder.production_id.name), ('state', 'not in', ['cancel'])] + domain = [('origin', '=', workorder.production_id.name), ('state', 'not in', ['cancel']), + ('partner_id', '!=', False)] previous_workorder = self.env['mrp.workorder'].search( [('sequence', '=', workorder.sequence - 1), ('routing_type', '=', '表面工艺'), ('production_id', '=', workorder.production_id.id)]) if previous_workorder: - process_product = self.env['product.template']._get_process_parameters_product( - previous_workorder.surface_technics_parameters_id) - domain += [('partner_id', '=', process_product.partner_id.id)] - else: - domain += [('surface_technics_parameters_id', '=', workorder.surface_technics_parameters_id.id)] + if previous_workorder.supplier_id != workorder.supplier_id: + process_product = self.env['product.template']._get_process_parameters_product( + previous_workorder.surface_technics_parameters_id) + domain += [('partner_id', '=', process_product.partner_id.id)] picking_ids = self.env['stock.picking'].search(domain, order='id asc') workorder.surface_technics_picking_count = len(picking_ids) workorder.picking_ids = picking_ids.ids @@ -782,7 +785,7 @@ class ResMrpWorkOrder(models.Model): routing_types = ['切割', '装夹预调', 'CNC加工', '解除装夹'] if route.route_id.routing_type in routing_types: routing_workcenter = self.env['mrp.routing.workcenter'].sudo().search( - [('name', '=', route.route_id.routing_type)]) + [('name', '=', oute.routing_type if hasattr(route, 'routing_type') else route.route_id.routing_type)]) duration_expected = routing_workcenter.time_cycle reserved_duration = routing_workcenter.reserved_duration else: @@ -792,14 +795,15 @@ class ResMrpWorkOrder(models.Model): 'product_uom_id': production.product_uom_id.id, 'qty_producing': 0, 'operation_id': False, - 'name': route.route_id.name, - 'processing_panel': route.panel, + 'name': route.name if hasattr(route, 'routing_type') else route.route_id.name, + 'processing_panel': False if hasattr(route, 'routing_type') else route.panel, 'sequence': route.sequence, - 'quality_point_ids': route.route_id.quality_point_ids, - 'routing_type': route.route_id.routing_type, - 'workcenter_id': self.env['mrp.routing.workcenter'].get_workcenter(route.route_id.workcenter_ids.ids, - route.route_id.routing_type, - production.product_id), + 'quality_point_ids': False if hasattr(route, 'routing_type') else route.route_id.quality_point_ids, + 'routing_type': route.routing_type if hasattr(route, 'routing_type') else route.route_id.routing_type, + 'workcenter_id': False if hasattr(route, 'routing_type') else self.env[ + 'mrp.routing.workcenter'].get_workcenter(route.route_id.workcenter_ids.ids, + route.route_id.routing_type, + production.product_id), # 设定初始化值,避免出现变成bool问题 'date_planned_start': datetime.now(), 'date_planned_finished': datetime.now() + timedelta(days=1), @@ -1004,7 +1008,7 @@ class ResMrpWorkOrder(models.Model): return workorders_values_str @api.depends('production_availability', 'blocked_by_workorder_ids', 'blocked_by_workorder_ids.state', - 'production_id.tool_state', 'production_id.schedule_state') + 'production_id.tool_state', 'production_id.schedule_state', 'sequence') def _compute_state(self): # super()._compute_state() for workorder in self: @@ -1015,10 +1019,13 @@ class ResMrpWorkOrder(models.Model): if workorder.state == 'pending': if all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]): if workorder.production_id.reservation_state == 'assigned' and workorder.production_id.schedule_state == '已排': - if (workorder.sequence == 1 and not workorder.blocked_by_workorder_ids) or ( - workorder.blocked_by_workorder_ids.state in ('done', 'cancel')) or ( - previous_workorder.state in ( - 'done', 'cancel') and not workorder.blocked_by_workorder_ids): + if ((workorder.sequence == 1 and not workorder.blocked_by_workorder_ids) + or (workorder.blocked_by_workorder_ids.state in ('done', 'cancel') + and workorder.blocked_by_workorder_ids.test_results not in ['报废', '返工']) + or (previous_workorder.state in ('done', 'cancel') + and not workorder.blocked_by_workorder_ids + and previous_workorder.test_results not in ['报废', '返工']) + ): workorder.state = 'ready' continue if workorder.production_id.schedule_state == '未排' and workorder.state in ('waiting', 'ready'): @@ -1045,147 +1052,115 @@ class ResMrpWorkOrder(models.Model): workorder.state = 'ready' elif workorder.production_id.reservation_state != 'assigned' and workorder.state == 'ready': workorder.state = 'waiting' - re_work = self.env['mrp.workorder'].search([('production_id', '=', workorder.production_id.id), - ('processing_panel', '=', workorder.processing_panel), - ('is_rework', '=', True), ('state', 'in', ['done', 'rework'])]) - cnc_workorder = self.env['mrp.workorder'].search( - [('production_id', '=', workorder.production_id.id), - ('processing_panel', '=', workorder.processing_panel), - ('routing_type', '=', 'CNC加工'), ('state', 'in', ['done', 'rework']), - ('test_results', '=', '返工')]) - cnc_workorder_pending = self.env['mrp.workorder'].search( - [('production_id', '=', workorder.production_id.id), - ('processing_panel', '=', workorder.processing_panel), - ('routing_type', '=', 'CNC加工'), ('state', 'in', ['pending'])]) - unclamp_workorder = self.env['mrp.workorder'].search( - [('production_id', '=', workorder.production_id.id), - ('sequence', '=', workorder.sequence - 1), - ('state', 'in', ['done'])]) - if workorder.state not in ['cancel', 'progress', 'rework']: - if workorder.production_id.state == 'rework': - if workorder.routing_type == '装夹预调' and workorder.state not in ['done', 'rework', - 'cancel']: - # # 有返工工单 - # if re_work: - # 新工单 - if workorder.is_rework is False: - if workorder.production_id.programming_state == '已编程' and workorder.production_id.is_rework is False: - if re_work or cnc_workorder: - workorder.state = 'ready' - else: - if workorder.production_id.is_rework is True: - if re_work or cnc_workorder: - workorder.state = 'waiting' - elif workorder.routing_type == 'CNC加工' and workorder.state not in ['done', 'rework', 'cancel']: - pre_workorder = self.env['mrp.workorder'].search( - [('production_id', '=', workorder.production_id.id), - ('processing_panel', '=', workorder.processing_panel), - ('routing_type', '=', '装夹预调'), ('state', '=', 'done')]) - if pre_workorder: - if re_work: - workorder.state = 'waiting' - elif workorder.routing_type == '解除装夹' and workorder.state not in ['done', 'rework', 'cancel']: - if cnc_workorder: - if not cnc_workorder_pending or unclamp_workorder.test_results == '报废': - workorder.state = 'waiting' - # else: - # if workorder.production_id.is_rework is True: - # workorder.state = 'waiting' - elif workorder.production_id.state == 'progress': - if workorder.routing_type == '装夹预调' and workorder.production_id.programming_state == '已编程' and \ - workorder.is_rework is False and workorder.state not in [ - 'done', 'rework', - 'cancel']: - if workorder.production_id.is_rework is False: - if re_work or cnc_workorder or unclamp_workorder: - workorder.state = 'ready' - # if (re_work or cnc_workorder) and workorder.production_id.is_rework is False: - # workorder.state = 'ready' - if workorder.routing_type == '表面工艺' and workorder.state not in ['done', 'progress']: - if unclamp_workorder: - if workorder.is_subcontract is False: - workorder.state = 'ready' - else: - production_programming = self.env['mrp.production'].search( - [('origin', '=', self.production_id.origin)], order='name asc') - production_no_remanufacture = production_programming.filtered( - lambda a: a.is_remanufacture is False) - production_list = [production.name for production in production_programming] - purchase_orders = self.env['purchase.order'].search( - [('origin', 'ilike', ','.join(production_list))]) - for line in purchase_orders.order_line: - if line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id and line.product_qty == len( - production_no_remanufacture): - if purchase_orders.state == 'purchase': - workorder.state = 'ready' - else: - workorder.state = 'waiting' - elif workorder.production_id.state == 'scrap': - if workorder.routing_type == '解除装夹' and unclamp_workorder.test_results == '报废': - workorder.state = 'waiting' - # if workorder.routing_type == '装夹预调' and workorder.state in ['waiting', 'ready', 'pending']: - # workorder_ids = workorder.production_id.workorder_ids - # work_bo = True - # for wo in workorder_ids.filtered(lambda a: a.routing_type == '装夹预调' and a.state == 'rework'): - # if not workorder_ids.filtered( - # lambda a: (a.routing_type == '装夹预调' and a.state not in ['rework', 'cancel'] - # and a.processing_panel == wo.processing_panel)): - # work_bo = False - # break - # if (workorder.production_id.programming_state == '已编程' and work_bo - # and not workorder_ids.filtered(lambda a: a.sequence == 0)): - # # 当工单对应制造订单的功能刀具状态为 【无效刀】时,先对的第一个装夹预调工单状态设置为 【等待组件】 - # if workorder.production_id.tool_state in ['1', '2']: - # if workorder.state in ['ready']: - # workorder.state = 'waiting' - # continue - # elif workorder.state in ['waiting']: - # continue - # elif workorder.state == 'pending' and workorder == self.search( - # [('production_id', '=', workorder.production_id.id), - # ('routing_type', '=', '装夹预调'), - # ('state', 'not in', ['rework', 'done', 'cancel'])], - # limit=1, - # order="sequence"): - # workorder.state = 'waiting' - # continue - # elif workorder.production_id.tool_state in ['0']: - # if workorder_ids.filtered(lambda a: a.state == 'rework'): - # if not workorder_ids.filtered( - # lambda a: (a.routing_type not in ['装夹预调'] and - # a.state not in ['pending', 'done', 'rework', 'cancel'])): - # # 查询工序最小的非完工、非返工的装夹预调工单 - # work_id = self.search( - # [('production_id', '=', workorder.production_id.id), - # ('state', 'not in', ['rework', 'done', 'cancel'])], - # limit=1, - # order="sequence") - # if work_id.routing_type == '装夹预调': - # if workorder == work_id: - # if workorder.production_id.reservation_state == 'assigned': - # workorder.state = 'ready' - # elif workorder.production_id.reservation_state != 'assigned': - # workorder.state = 'waiting' - # continue - # elif (workorder.name == '装夹预调' and - # workorder.state not in ['rework', 'done', 'cancel']): - # if workorder.state != 'pending': - # workorder.state = 'pending' - # if workorder.production_id.tool_state in ['1', '2'] and workorder.state == 'ready': - # workorder.state = 'waiting' - # continue - # if (workorder.production_id.tool_state in ['1', '2'] - # and not workorder.production_id.workorder_ids.filtered(lambda a: a.sequence == 0) - # and workorder.production_id.programming_state == '编程中' and workorder.name == '装夹预调'): - # if workorder.state == 'pending' and workorder == self.search( - # [('production_id', '=', workorder.production_id.id), - # ('routing_type', '=', '装夹预调'), - # ('state', 'not in', ['rework', 'done', 'cancel'])], - # limit=1, - # order="sequence"): - # workorder.state = 'waiting' - # continue + for workorder in self: + # 如果工单的工序没有进行排序则跳出循环 + if workorder.production_id.workorder_ids.filtered(lambda wk: wk.sequence == 0): + continue + # ===== 对所有按序号排序的非[进行中、完成、返工、取消]状态的工单,除了第一条之外的工单状态都设置为[等待其他工单] ===== + logging.info(workorder.state) + work_ids = workorder.production_id.workorder_ids.filtered( + lambda wk: wk.state not in ['done', 'rework', 'cancel']) + if not work_ids: + continue + min_sequence_wk = min(work_ids, key=lambda wk: wk.sequence) + if workorder.state in ['done', 'rework', 'cancel', 'progress', 'to be detected']: + continue + else: + if workorder != min_sequence_wk: + if workorder.state != 'pending': + workorder.state = 'pending' + continue + # ================= 如果制造订单刀具状态为[无效刀、缺刀] 或者 制造订单状态为[返工]========================== + if (workorder.production_id.tool_state in ['1', '2'] or workorder.production_id.state == 'rework' + or workorder.production_id.schedule_state != '已排' + or workorder.production_id.reservation_state != 'assigned' + or workorder.production_id.workorder_ids.filtered( + lambda wk: wk.sequence == workorder.sequence - 1).test_results in ['报废', '返工']): + if workorder.state != 'waiting': + workorder.state = 'waiting' + continue + if workorder.production_id.programming_state == '已编程': + workorder.state = 'ready' + elif workorder.state != 'waiting': + workorder.state = 'waiting' + # re_work = self.env['mrp.workorder'].search([('production_id', '=', workorder.production_id.id), + # ('processing_panel', '=', workorder.processing_panel), + # ('is_rework', '=', True), ('state', 'in', ['done', 'rework'])]) + # cnc_workorder = self.env['mrp.workorder'].search( + # [('production_id', '=', workorder.production_id.id), + # ('processing_panel', '=', workorder.processing_panel), + # ('routing_type', '=', 'CNC加工'), ('state', 'in', ['done', 'rework']), + # ('test_results', '=', '返工')]) + # cnc_workorder_pending = self.env['mrp.workorder'].search( + # [('production_id', '=', workorder.production_id.id), + # ('processing_panel', '=', workorder.processing_panel), + # ('routing_type', '=', 'CNC加工'), ('state', 'in', ['pending'])]) + # unclamp_workorder = self.env['mrp.workorder'].search( + # [('production_id', '=', workorder.production_id.id), + # ('sequence', '=', workorder.sequence - 1), + # ('state', 'in', ['done'])]) + # if workorder.state not in ['cancel', 'progress', 'rework']: + # if workorder.production_id.state == 'rework': + # if workorder.routing_type == '装夹预调': + # # # 有返工工单 + # # if re_work: + # # 新工单 + # if workorder.is_rework is False: + # if (workorder.production_id.programming_state == '已编程' + # and workorder.production_id.is_rework is False): + # if re_work or cnc_workorder: + # workorder.state = 'ready' + # else: + # if workorder.production_id.is_rework is True: + # if re_work or cnc_workorder: + # workorder.state = 'waiting' + # + # elif workorder.routing_type == 'CNC加工': + # pre_workorder = self.env['mrp.workorder'].search( + # [('production_id', '=', workorder.production_id.id), + # ('processing_panel', '=', workorder.processing_panel), + # ('routing_type', '=', '装夹预调'), ('state', '=', 'done')]) + # if pre_workorder: + # if re_work: + # workorder.state = 'waiting' + # elif workorder.routing_type == '解除装夹': + # if cnc_workorder: + # if not cnc_workorder_pending or unclamp_workorder.test_results == '报废': + # workorder.state = 'waiting' + # # else: + # # if workorder.production_id.is_rework is True: + # # workorder.state = 'waiting' + # elif workorder.production_id.state == 'progress': + # if (workorder.routing_type == '装夹预调' and workorder.production_id.programming_state == '已编程' + # and workorder.is_rework is False and workorder.state not in ['done', 'rework', 'cancel']): + # if workorder.production_id.is_rework is False: + # if re_work or cnc_workorder or unclamp_workorder: + # workorder.state = 'ready' + # # if (re_work or cnc_workorder) and workorder.production_id.is_rework is False: + # # workorder.state = 'ready' + # if workorder.routing_type == '表面工艺' and workorder.state not in ['done', 'progress']: + # if unclamp_workorder: + # if workorder.is_subcontract is False: + # workorder.state = 'ready' + # else: + # production_programming = self.env['mrp.production'].search( + # [('origin', '=', self.production_id.origin)], order='name asc') + # production_no_remanufacture = production_programming.filtered( + # lambda a: a.is_remanufacture is False) + # production_list = [production.name for production in production_programming] + # purchase_orders = self.env['purchase.order'].search( + # [('origin', 'ilike', ','.join(production_list))]) + # for line in purchase_orders.order_line: + # if line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id and line.product_qty == len( + # production_no_remanufacture): + # if purchase_orders.state == 'purchase': + # workorder.state = 'ready' + # else: + # workorder.state = 'waiting' + # elif workorder.production_id.state == 'scrap': + # if workorder.routing_type == '解除装夹' and unclamp_workorder.test_results == '报废': + # workorder.state = 'waiting' # 重写工单开始按钮方法 def button_start(self): @@ -2032,7 +2007,7 @@ class CMMprogram(models.Model): })) return cmm_program - def update_work_start_end(self,date_planned_start,date_planned_end): + def update_work_start_end(self, date_planned_start, date_planned_end): self.leave_id.write({ 'date_from': date_planned_start, 'date_to': date_planned_end, @@ -2070,7 +2045,8 @@ class CMMprogram(models.Model): date_planned_end = date_planned_start + duration_expected last_time = date_planned_end return date_planned_start, date_planned_end, last_time - def manual_offline_process(self,last_time,is_first): + + def manual_offline_process(self, last_time, is_first): date_planned_end = None date_planned_start = None duration_expected = datetime.timedelta(minutes=self.duration_expected) @@ -2082,4 +2058,4 @@ class CMMprogram(models.Model): else: date_planned_start = last_time + reserve_time date_planned_end = date_planned_start + duration_expected - return date_planned_start, date_planned_end,last_time \ No newline at end of file + return date_planned_start, date_planned_end, last_time diff --git a/sf_manufacturing/models/sf_technology_design.py b/sf_manufacturing/models/sf_technology_design.py index b1bd229d..a38e7897 100644 --- a/sf_manufacturing/models/sf_technology_design.py +++ b/sf_manufacturing/models/sf_technology_design.py @@ -18,7 +18,7 @@ class sf_technology_design(models.Model): def json_technology_design_str(self, k, route, i, process_parameter): workorders_values_str = [0, '', { - 'route_id': route.id, + 'route_id': route.id if route.routing_type in ['表面工艺'] else route.route_workcenter_id.id, 'panel': k, 'process_parameters_id': False if route.routing_type != '表面工艺' else self.env[ 'sf.production.process.parameter'].search( diff --git a/sf_manufacturing/models/stock.py b/sf_manufacturing/models/stock.py index 5fa12979..65a01e68 100644 --- a/sf_manufacturing/models/stock.py +++ b/sf_manufacturing/models/stock.py @@ -321,7 +321,6 @@ class StockRule(models.Model): i = 0 if production_item.product_id.categ_id.type == '成品': # 根据加工面板的面数及成品工序模板生成工序设计 - for k in (production_item.product_id.model_processing_panel.split(',')): if production_item.production_type == '自动化产线加工': product_routing_workcenter = self.env['sf.product.model.type.routing.sort'].search( @@ -337,7 +336,7 @@ class StockRule(models.Model): i += 1 technology_design_values.append( self.env['sf.technology.design'].json_technology_design_str(k, route, i, False)) - elif production.product_id.categ_id.type == '坯料': + elif production_item.product_id.categ_id.type == '坯料': embryo_routing_workcenter = self.env['sf.embryo.model.type.routing.sort'].search( [('embryo_model_type_id', '=', production_item.product_id.embryo_model_type_id.id)], order='sequence asc' @@ -378,7 +377,6 @@ class StockRule(models.Model): process_parameter)) productions.technology_design_ids = technology_design_values - return True @@ -661,41 +659,40 @@ class StockPicking(models.Model): def create_outcontract_picking(self, sorted_workorders_arr, item): if len(sorted_workorders_arr) > 1: sorted_workorders_arr = sorted_workorders_arr[0] - stock_picking = self.env['stock.picking'].search( - [('origin', '=', sorted_workorders_arr.production_id.name), ('name', 'ilike', 'OCOUT')]) - if not stock_picking: + stock_picking = self.env['stock.picking'].search([('origin', '=', item.name), ('name', 'ilike', 'OCOUT')]) + if not stock_picking or sorted_workorders_arr: for sorted_workorders in sorted_workorders_arr: # pick_ids = [] if not sorted_workorders.picking_ids: - outcontract_stock_move = self.env['stock.move'].search([('production_id', '=', item.id)]) - if not outcontract_stock_move: - new_picking = True - location_id = self.env['stock.location'].search( - [('barcode', 'ilike', 'VL-SPOC')]).id, - location_dest_id = self.env['stock.location'].search( - [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id, - outcontract_picking_type_in = self.env.ref( - 'sf_manufacturing.outcontract_picking_in').id, - outcontract_picking_type_out = self.env.ref( - 'sf_manufacturing.outcontract_picking_out').id, - moves_out = self.env['stock.move'].sudo().create( - self.env['stock.move']._get_stock_move_values_Res(item, location_dest_id, location_id, - outcontract_picking_type_out)) - picking_out = self.create( - moves_out._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCOUT/')) - # pick_ids.append(picking_out.id) - moves_out.write( - {'picking_id': picking_out.id, 'state': 'waiting'}) - moves_out._assign_picking_post_process(new=new_picking) - moves_in = self.env['stock.move'].sudo().create( - self.env['stock.move']._get_stock_move_values_Res(item, location_id, location_dest_id, - outcontract_picking_type_in)) - picking_in = self.create( - moves_in._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCIN/')) - # pick_ids.append(picking_in.id) - moves_in.write( - {'picking_id': picking_in.id, 'state': 'waiting'}) - moves_in._assign_picking_post_process(new=new_picking) + # outcontract_stock_move = self.env['stock.move'].search([('production_id', '=', item.id)]) + # if not outcontract_stock_move: + new_picking = True + location_id = self.env['stock.location'].search( + [('barcode', 'ilike', 'VL-SPOC')]).id, + location_dest_id = self.env['stock.location'].search( + [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id, + outcontract_picking_type_in = self.env.ref( + 'sf_manufacturing.outcontract_picking_in').id, + outcontract_picking_type_out = self.env.ref( + 'sf_manufacturing.outcontract_picking_out').id, + moves_out = self.env['stock.move'].sudo().create( + self.env['stock.move']._get_stock_move_values_Res(item, location_dest_id, location_id, + outcontract_picking_type_out)) + picking_out = self.create( + moves_out._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCOUT/')) + # pick_ids.append(picking_out.id) + moves_out.write( + {'picking_id': picking_out.id, 'state': 'waiting'}) + moves_out._assign_picking_post_process(new=new_picking) + moves_in = self.env['stock.move'].sudo().create( + self.env['stock.move']._get_stock_move_values_Res(item, location_id, location_dest_id, + outcontract_picking_type_in)) + picking_in = self.create( + moves_in._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCIN/')) + # pick_ids.append(picking_in.id) + moves_in.write( + {'picking_id': picking_in.id, 'state': 'waiting'}) + moves_in._assign_picking_post_process(new=new_picking) class ReStockMove(models.Model): @@ -731,7 +728,7 @@ class ReStockMove(models.Model): return { 'name': self.env['stock.picking']._get_name_Res(rescode), 'origin': item.name, - # 'surface_technics_parameters_id': sorted_workorders.surface_technics_parameters_id.id, + 'surface_technics_parameters_id': sorted_workorders.surface_technics_parameters_id.id, 'company_id': self.mapped('company_id').id, 'user_id': False, 'move_type': self.mapped('group_id').move_type or 'direct', diff --git a/sf_manufacturing/views/mrp_production_addional_change.xml b/sf_manufacturing/views/mrp_production_addional_change.xml index d967551e..725f5eb8 100644 --- a/sf_manufacturing/views/mrp_production_addional_change.xml +++ b/sf_manufacturing/views/mrp_production_addional_change.xml @@ -84,6 +84,12 @@ technology_to_confirmed,confirmed,pending_cam,progress,rework,scrap,done + + 1 + + + 1 + @@ -139,7 +145,7 @@ + attrs="{'invisible': [('state', '!=', 'technology_to_confirmed')]}">