批量处理工艺调整

This commit is contained in:
jinling.yang
2024-11-14 18:02:24 +08:00
parent 33a1837274
commit 018d51e25f
6 changed files with 158 additions and 95 deletions

View File

@@ -194,6 +194,8 @@ class ResMrpWorkOrder(models.Model):
else: else:
domain = [('origin', '=', ','.join(production_list))] domain = [('origin', '=', ','.join(production_list))]
purchase = self.env['purchase.order'].search(domain) purchase = self.env['purchase.order'].search(domain)
if not purchase:
order.surface_technics_purchase_count = 0
for line in purchase.order_line: for line in purchase.order_line:
if line.product_id.server_product_process_parameters_id == order.surface_technics_parameters_id: if line.product_id.server_product_process_parameters_id == order.surface_technics_parameters_id:
if (line.product_qty == len(production_no_remanufacture)) or technology_design.is_auto is False: if (line.product_qty == len(production_no_remanufacture)) or technology_design.is_auto is False:
@@ -908,25 +910,44 @@ class ResMrpWorkOrder(models.Model):
return workorders_values_str return workorders_values_str
@api.depends('production_availability', 'blocked_by_workorder_ids', 'blocked_by_workorder_ids.state', @api.depends('production_availability', 'blocked_by_workorder_ids', 'blocked_by_workorder_ids.state',
'production_id.tool_state') 'production_id.tool_state', 'production_id.schedule_state')
def _compute_state(self): def _compute_state(self):
# super()._compute_state() # super()._compute_state()
for workorder in self: for workorder in self:
logging.info(workorder.name) logging.info(workorder.name)
logging.info(workorder.state) logging.info(workorder.state)
logging.info(workorder.sequence) logging.info(workorder.sequence)
logging.info(workorder.id)
# logging.info(workorder.blocked_by_workorder_ids)
# logging.info(workorder.blocked_by_workorder_ids.name)
# logging.info(workorder.blocked_by_workorder_ids.sequence)
logging.info('----------------------')
if workorder.sequence != 1:
previous_workorder = self.env['mrp.workorder'].search(
[('production_id', '=', workorder.production_id.id),
('sequence', '=', workorder.sequence - 1)])
if workorder.state == 'pending': if workorder.state == 'pending':
if all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]): if all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]):
workorder.state = 'ready' if workorder.production_id.reservation_state == 'assigned' else 'waiting' if workorder.production_id.reservation_state == 'assigned' and workorder.production_id.schedule_state == '已排':
continue 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):
workorder.state = 'ready'
continue
if workorder.production_id.schedule_state == '未排' and workorder.state in ('waiting', 'ready'):
if workorder.sequence != 1:
workorder.state = 'pending'
continue
if workorder.state not in ('waiting', 'ready'): if workorder.state not in ('waiting', 'ready'):
continue continue
if workorder.state in (
'waiting') and workorder.sequence == 1 and workorder.production_id.schedule_state == '已排':
workorder.state = 'ready'
continue
if not all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]): if not all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]):
workorder.state = 'pending' workorder.state = 'pending'
if workorder.state in ['waiting']: if workorder.state in ['waiting']:
previous_workorder = self.env['mrp.workorder'].search(
[('production_id', '=', workorder.production_id.id),
('sequence', '=', workorder.sequence - 1)])
if previous_workorder.state == 'waiting': if previous_workorder.state == 'waiting':
workorder.state = 'pending' workorder.state = 'pending'
if workorder.sequence == 1 and workorder.state == 'pending': if workorder.sequence == 1 and workorder.state == 'pending':
@@ -934,7 +955,7 @@ class ResMrpWorkOrder(models.Model):
continue continue
if workorder.production_id.reservation_state not in ('waiting', 'confirmed', 'assigned'): if workorder.production_id.reservation_state not in ('waiting', 'confirmed', 'assigned'):
continue continue
if workorder.production_id.reservation_state == 'assigned' and workorder.state == 'waiting': if workorder.production_id.reservation_state == 'assigned' and workorder.state == 'waiting' and workorder.production_id.schedule_state == '已排':
workorder.state = 'ready' workorder.state = 'ready'
elif workorder.production_id.reservation_state != 'assigned' and workorder.state == 'ready': elif workorder.production_id.reservation_state != 'assigned' and workorder.state == 'ready':
workorder.state = 'waiting' workorder.state = 'waiting'
@@ -991,7 +1012,7 @@ class ResMrpWorkOrder(models.Model):
'done', 'rework', 'done', 'rework',
'cancel']: 'cancel']:
if workorder.production_id.is_rework is False: if workorder.production_id.is_rework is False:
if re_work or cnc_workorder or unclamp_workorder: if re_work or cnc_workorder or unclamp_workorder :
workorder.state = 'ready' workorder.state = 'ready'
# if (re_work or cnc_workorder) and workorder.production_id.is_rework is False: # if (re_work or cnc_workorder) and workorder.production_id.is_rework is False:
# workorder.state = 'ready' # workorder.state = 'ready'
@@ -1001,7 +1022,7 @@ class ResMrpWorkOrder(models.Model):
workorder.state = 'ready' workorder.state = 'ready'
else: else:
production_programming = self.env['mrp.production'].search( production_programming = self.env['mrp.production'].search(
[('programming_no', '=', self.production_id.programming_no)], order='name asc') [('origin', '=', self.production_id.origin)], order='name asc')
production_no_remanufacture = production_programming.filtered( production_no_remanufacture = production_programming.filtered(
lambda a: a.is_remanufacture is False) lambda a: a.is_remanufacture is False)
production_list = [production.name for production in production_programming] production_list = [production.name for production in production_programming]
@@ -1088,7 +1109,7 @@ class ResMrpWorkOrder(models.Model):
'actual_start_time': datetime.now() 'actual_start_time': datetime.now()
}) })
if self.routing_type == '装夹预调': if self.sequence == 1:
# 判断是否有坯料的序列号信息 # 判断是否有坯料的序列号信息
boolean = False boolean = False
if self.production_id.move_raw_ids: if self.production_id.move_raw_ids:
@@ -1196,9 +1217,9 @@ class ResMrpWorkOrder(models.Model):
if record.routing_type == '装夹预调': if record.routing_type == '装夹预调':
if not record.rfid_code and record.is_rework is False: if not record.rfid_code and record.is_rework is False:
raise UserError("请扫RFID码进行绑定") raise UserError("请扫RFID码进行绑定")
if record.is_rework is False: # if record.is_rework is False:
if not record.material_center_point: # if not record.material_center_point:
raise UserError("坯料中心点为空,请检查") # raise UserError("坯料中心点为空,请检查")
# if record.X_deviation_angle <= 0: # if record.X_deviation_angle <= 0:
# raise UserError("X偏差角度小于等于0请检查本次计算的X偏差角度为%s" % record.X_deviation_angle) # raise UserError("X偏差角度小于等于0请检查本次计算的X偏差角度为%s" % record.X_deviation_angle)
record.process_state = '待加工' record.process_state = '待加工'
@@ -1230,23 +1251,10 @@ class ResMrpWorkOrder(models.Model):
''' '''
record.date_finished = datetime.now() record.date_finished = datetime.now()
if record.routing_type == '表面工艺': if record.routing_type == '表面工艺':
logging.info('record.picking_ids:%s' % record.picking_ids)
logging.info('record.picking_out:%s' % record.picking_ids[0])
if record.picking_ids: if record.picking_ids:
for pick_item in record.picking_ids: picks = record.picking_ids.filtered(lambda p: p.state not in ('done'))
if pick_item.state not in ['done']: # if picks:
raise UserError( # raise UserError('请先完成该工单的工艺外协再进行操作')
'请先完成该工单的工艺外协再进行操作')
picking_out = record.env['stock.move.line'].search(
[('picking_id', '=', record.picking_ids[0].id)])
logging.info('picking_out:%s' % picking_out.picking_id.name)
# if picking_out:
# order_line_ids = []
# logging.info('surface_technics_parameters_id:%s' % record.surface_technics_parameters_id.name)
#
# else:
# raise UserError(
# '请先在产品中配置表面工艺为%s相关的外协服务产品' % item.surface_technics_parameters_id.name)
tem_date_planned_finished = record.date_planned_finished tem_date_planned_finished = record.date_planned_finished
tem_date_finished = record.date_finished tem_date_finished = record.date_finished
logging.info('routing_type:%s' % record.routing_type) logging.info('routing_type:%s' % record.routing_type)

View File

@@ -659,32 +659,27 @@ class StockPicking(models.Model):
return '%s%s' % (rescode, num) return '%s%s' % (rescode, num)
def button_validate(self): def button_validate(self):
move_out = self.env['stock.move'].search( if self.picking_type_id.barcode == 'OCOUT':
[('location_id', '=', self.env['stock.location'].search( move_out = self.env['stock.move'].search(
[('barcode', 'ilike', 'WH-PREPRODUCTION')]).id), [('location_id', '=', self.env['stock.location'].search(
('location_dest_id', '=', self.env['stock.location'].search( [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id),
[('barcode', 'ilike', 'VL-SPOC')]).id), ('location_dest_id', '=', self.env['stock.location'].search(
('origin', '=', self.origin)]) [('barcode', 'ilike', 'VL-SPOC')]).id),
# if self.id == move_out.picking_id.id: ('origin', '=', self.origin)])
# if move_out.move_line_ids.workorder_id.state not in ['progress']: move_in = self.env['stock.move'].search(
# raise UserError( [('location_dest_id', '=', self.env['stock.location'].search(
# _('该出库单里源单据内的单号为%s的工单还未开始不能进行验证操作' % move_out.move_line_ids.workorder_id.name)) [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id),
# 入库单验证 ('location_id', '=', self.env['stock.location'].search(
move_in = self.env['stock.move'].search( [('barcode', 'ilike', 'VL-SPOC')]).id),
[('location_dest_id', '=', self.env['stock.location'].search( ('origin', '=', self.origin), ('picking_id', '=', self.id)])
[('barcode', 'ilike', 'WH-PREPRODUCTION')]).id), if self.location_id == move_in.location_id and self.location_dest_id == move_in.location_dest_id:
('location_id', '=', self.env['stock.location'].search( if move_out.origin == move_in.origin:
[('barcode', 'ilike', 'VL-SPOC')]).id), move_in.write({'production_id': False})
('origin', '=', self.origin), ('picking_id', '=', self.id)]) if move_out.picking_id.state != 'done':
if self.location_id == move_in.location_id and self.location_dest_id == move_in.location_dest_id: raise UserError(
if move_out.origin == move_in.origin: _('该入库单对应的单号为%s的出库单还未完成,不能进行验证操作!' % move_out.picking_id.name))
move_in.write({'production_id': False})
if move_out.picking_id.state != 'done':
raise UserError(
_('该入库单对应的单号为%s的出库单还未完成,不能进行验证操作!' % move_out.picking_id.name))
res = super().button_validate() res = super().button_validate()
if res is True and self.picking_type_id: if res is True and self.picking_type_id.barcode == 'OCIN':
if self.id == move_out.picking_id.id: if self.id == move_out.picking_id.id:
# if move_out.move_line_ids.workorder_id.state == 'progress': # if move_out.move_line_ids.workorder_id.state == 'progress':
move_in = self.env['stock.move'].search( move_in = self.env['stock.move'].search(
@@ -704,36 +699,37 @@ class StockPicking(models.Model):
def create_outcontract_picking(self, sorted_workorders_arr, item): def create_outcontract_picking(self, sorted_workorders_arr, item):
for sorted_workorders in sorted_workorders_arr: for sorted_workorders in sorted_workorders_arr:
# pick_ids = [] # pick_ids = []
outcontract_stock_move = self.env['stock.move'].search( if not sorted_workorders.picking_ids:
[('workorder_id', '=', sorted_workorders.id), ('production_id', '=', item.id)]) outcontract_stock_move = self.env['stock.move'].search(
if not outcontract_stock_move: [('workorder_id', '=', sorted_workorders.id), ('production_id', '=', item.id)])
new_picking = True if not outcontract_stock_move:
location_id = self.env['stock.location'].search( new_picking = True
[('barcode', 'ilike', 'VL-SPOC')]).id, location_id = self.env['stock.location'].search(
location_dest_id = self.env['stock.location'].search( [('barcode', 'ilike', 'VL-SPOC')]).id,
[('barcode', 'ilike', 'WH-PREPRODUCTION')]).id, location_dest_id = self.env['stock.location'].search(
outcontract_picking_type_in = self.env.ref( [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id,
'sf_manufacturing.outcontract_picking_in').id, outcontract_picking_type_in = self.env.ref(
outcontract_picking_type_out = self.env.ref( 'sf_manufacturing.outcontract_picking_in').id,
'sf_manufacturing.outcontract_picking_out').id, outcontract_picking_type_out = self.env.ref(
moves_out = self.env['stock.move'].sudo().create( 'sf_manufacturing.outcontract_picking_out').id,
self.env['stock.move']._get_stock_move_values_Res(item, location_dest_id, location_id, moves_out = self.env['stock.move'].sudo().create(
outcontract_picking_type_out)) self.env['stock.move']._get_stock_move_values_Res(item, location_dest_id, location_id,
picking_out = self.create( outcontract_picking_type_out))
moves_out._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCOUT/')) picking_out = self.create(
# pick_ids.append(picking_out.id) moves_out._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCOUT/'))
moves_out.write( # pick_ids.append(picking_out.id)
{'picking_id': picking_out.id, 'state': 'waiting', 'workorder_id': sorted_workorders.id}) moves_out.write(
moves_out._assign_picking_post_process(new=new_picking) {'picking_id': picking_out.id, 'state': 'waiting', 'workorder_id': sorted_workorders.id})
moves_in = self.env['stock.move'].sudo().create( moves_out._assign_picking_post_process(new=new_picking)
self.env['stock.move']._get_stock_move_values_Res(item, location_id, location_dest_id, moves_in = self.env['stock.move'].sudo().create(
outcontract_picking_type_in)) self.env['stock.move']._get_stock_move_values_Res(item, location_id, location_dest_id,
picking_in = self.create( outcontract_picking_type_in))
moves_in._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCIN/')) picking_in = self.create(
# pick_ids.append(picking_in.id) moves_in._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCIN/'))
moves_in.write( # pick_ids.append(picking_in.id)
{'picking_id': picking_in.id, 'state': 'waiting', 'workorder_id': sorted_workorders.id}) moves_in.write(
moves_in._assign_picking_post_process(new=new_picking) {'picking_id': picking_in.id, 'state': 'waiting', 'workorder_id': sorted_workorders.id})
moves_in._assign_picking_post_process(new=new_picking)
# sorted_workorders.write({'picking_ids': [(6, 0, pick_ids)]}) # sorted_workorders.write({'picking_ids': [(6, 0, pick_ids)]})
@@ -791,7 +787,7 @@ class ReStockMove(models.Model):
'picking_id': self.picking_id.id, 'picking_id': self.picking_id.id,
'reserved_uom_qty': 1.0, 'reserved_uom_qty': 1.0,
'lot_id': production_id.move_line_raw_ids.lot_id.id, 'lot_id': production_id.move_line_raw_ids.lot_id.id,
'company_id': self.company_id.id, 'company_id': self.env.company.id,
# 'workorder_id': '' if not sorted_workorders else sorted_workorders.id, # 'workorder_id': '' if not sorted_workorders else sorted_workorders.id,
# 'production_id': '' if not sorted_workorders else sorted_workorders.production_id.id, # 'production_id': '' if not sorted_workorders else sorted_workorders.production_id.id,
'state': 'assigned', 'state': 'assigned',

View File

@@ -347,6 +347,7 @@
<field name="technology_design_ids" widget="one2many"> <field name="technology_design_ids" widget="one2many">
<tree editable="bottom"> <tree editable="bottom">
<field name="sequence" widget="handle"/> <field name="sequence" widget="handle"/>
<field name="sequence"/>
<field name="route_id" context="{'production_id': production_id}" <field name="route_id" context="{'production_id': production_id}"
attrs="{'readonly': [('is_auto', '=', True)]}" options="{'no_create': True}"/> attrs="{'readonly': [('is_auto', '=', True)]}" options="{'no_create': True}"/>
<field name="process_parameters_id" attrs="{'readonly': [('is_auto', '=', True)]}" <field name="process_parameters_id" attrs="{'readonly': [('is_auto', '=', True)]}"

View File

@@ -248,8 +248,8 @@
<field name='tag_type' readonly="1" attrs='{"invisible": [("tag_type","=",False)]}' <field name='tag_type' readonly="1" attrs='{"invisible": [("tag_type","=",False)]}'
decoration-danger="tag_type == '重新加工'"/> decoration-danger="tag_type == '重新加工'"/>
<field name="is_test_env" invisible="1"/> <field name="is_test_env" invisible="1"/>
<field name="rfid_code" force_save="1" readonly="1" cache="True" <field name="rfid_code" force_save="1" readonly="0" cache="True"
attrs="{'invisible': [('rfid_code_old', '!=', False)]}" widget='qrcode_widget'/> attrs="{'invisible': [('rfid_code_old', '!=', False)]}"/>
<field name="rfid_code" string="RFID码(手动输入框)" force_save="1" readonly="0" cache="True" <field name="rfid_code" string="RFID码(手动输入框)" force_save="1" readonly="0" cache="True"
attrs="{'invisible': ['|',('rfid_code_old', '!=', False), ('is_test_env', '=', False)]}"/> attrs="{'invisible': ['|',('rfid_code_old', '!=', False), ('is_test_env', '=', False)]}"/>
<field name="rfid_code_old" readonly="1" attrs="{'invisible': [('rfid_code_old', '=', False)]}"/> <field name="rfid_code_old" readonly="1" attrs="{'invisible': [('rfid_code_old', '=', False)]}"/>

View File

@@ -17,11 +17,41 @@ class ProductionTechnologyReAdjustWizard(models.TransientModel):
domain = [('origin', '=', self.origin), ('state', '=', 'confirmed')] domain = [('origin', '=', self.origin), ('state', '=', 'confirmed')]
else: else:
domain = [('id', '=', self.production_id.id)] domain = [('id', '=', self.production_id.id)]
technology_designs = self.production_id.technology_design_ids
productions = self.env['mrp.production'].search(domain) productions = self.env['mrp.production'].search(domain)
workorders_values = [] workorders_values = []
for item in productions: for production_my in productions:
# 该制造订单的其他同一销售订单的制造订单的工艺设计处理
if production_my != self.production_id:
for td_other in production_my.technology_design_ids:
for td_main in technology_designs:
route_other = production_my.technology_design_ids.filtered(
lambda td: td.route_id.id == td_main.route_id.id)
if not route_other:
production_my.write({'technology_design_ids': [(0, 0, {
'route_id': td_main.route_id.id,
'process_parameters_id': False if td_main.process_parameters_id is False else
self.env[
'sf.production.process.parameter'].search(
[('id', '=', td_main.process_parameters_id.id)]).id,
'sequence': td_main.sequence})]})
else:
if td_main.route_id == td_other.route_id:
if td_main.route_id.routing_type == '表面工艺':
display_name = td_main.process_parameters_id.display_name
else:
display_name = td_main.route_id.display_name
if (td_main.panel is not False and td_main.panel == td_other.panel) or (
display_name == td_other.display_name):
if td_main.sequence != td_other.sequence:
td_other.write({'sequence': td_main.sequence})
logging.info(td_main.route_id.name)
logging.info(td_main.sequence)
logging.info(td_other.route_id.name)
logging.info(td_other.sequence)
special_design = self.env['sf.technology.design'].sudo().search( special_design = self.env['sf.technology.design'].sudo().search(
[('routing_tag', '=', 'special'), ('production_id', '=', item.id), [('routing_tag', '=', 'special'), ('production_id', '=', production_my.id),
('is_auto', '=', False), ('active', 'in', [True, False])]) ('is_auto', '=', False), ('active', 'in', [True, False])])
for special in special_design: for special in special_design:
if special.active is False: if special.active is False:
@@ -42,7 +72,12 @@ class ProductionTechnologyReAdjustWizard(models.TransientModel):
if line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id: if line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id:
purchase_order.write({'state': 'cancel'}) purchase_order.write({'state': 'cancel'})
else: else:
workorder = self.env['mrp.workorder'].search([('name', '=', special.route_id.display_name)]) if special.route_id.routing_type == '表面工艺':
display_name = special.process_parameters_id.display_name
else:
display_name = special.route_id.display_name
workorder = self.env['mrp.workorder'].search(
[('name', '=', display_name), ('production_id', '=', special.production_id.id)])
if not workorder: if not workorder:
if special.route_id.routing_type == '表面工艺': if special.route_id.routing_type == '表面工艺':
product_production_process = self.env['product.template'].search( product_production_process = self.env['product.template'].search(
@@ -57,10 +92,16 @@ class ProductionTechnologyReAdjustWizard(models.TransientModel):
else: else:
workorders_values.append( workorders_values.append(
self.env['mrp.workorder'].json_workorder_str(special.production_id, special)) self.env['mrp.workorder'].json_workorder_str(special.production_id, special))
if workorders_values: special.production_id.write({'workorder_ids': workorders_values})
productions.write({'workorder_ids': workorders_values}) special.production_id.get_subcontract_pick()
productions.get_subcontract_pick() special.production_id._reset_work_order_sequence()
productions._reset_work_order_sequence() workorders_values = []
else:
if len(workorder.blocked_by_workorder_ids) > 1:
if workorder.sequence == 1:
workorder.blocked_by_workorder_ids = None
else:
workorder.blocked_by_workorder_ids = blocked_by_workorder_ids[0]
for item in productions: for item in productions:
workorder = item.workorder_ids.filtered(lambda wo: wo.state not in ('cancel')).sorted( workorder = item.workorder_ids.filtered(lambda wo: wo.state not in ('cancel')).sorted(
key=lambda a: a.sequence) key=lambda a: a.sequence)

View File

@@ -18,8 +18,24 @@ class ProductionTechnologyWizard(models.TransientModel):
domain = [('origin', '=', self.origin)] domain = [('origin', '=', self.origin)]
else: else:
domain = [('id', '=', self.production_id.id)] domain = [('id', '=', self.production_id.id)]
technology_designs = self.production_id.technology_design_ids
productions = self.env['mrp.production'].search(domain) productions = self.env['mrp.production'].search(domain)
for production in productions: for production in productions:
if production != self.production_id:
for td_other in production.technology_design_ids:
for td_main in technology_designs:
route_other = production.technology_design_ids.filtered(
lambda td: td.route_id.id == td_main.route_id.id)
if not route_other:
production.write({'technology_design_ids': [(0, 0, {
'route_id': td_main.route_id.id,
'process_parameters_id': False if td_main.process_parameters_id is False else self.env[
'sf.production.process.parameter'].search(
[('id', '=', td_main.process_parameters_id.id)]).id,
'sequence': td_main.sequence})]})
else:
if td_main.sequence != td_other.sequence:
td_other.sequence = td_main.sequence
special = production.technology_design_ids.filtered( special = production.technology_design_ids.filtered(
lambda td: td.is_auto is False and td.process_parameters_id is not False) lambda td: td.is_auto is False and td.process_parameters_id is not False)
if special: if special:
@@ -28,4 +44,5 @@ class ProductionTechnologyWizard(models.TransientModel):
for item in productions: for item in productions:
workorder = item.workorder_ids.filtered(lambda wo: wo.state not in ('cancel')).sorted( workorder = item.workorder_ids.filtered(lambda wo: wo.state not in ('cancel')).sorted(
key=lambda a: a.sequence) key=lambda a: a.sequence)
workorder[0].state = 'waiting' if workorder[0].state in ['pending']:
workorder[0].state = 'waiting'