Merge branch 'feature/修复报废' into develop

This commit is contained in:
jinling.yang
2024-08-27 11:33:04 +08:00
7 changed files with 102 additions and 42 deletions

View File

@@ -131,6 +131,31 @@ class MrpProduction(models.Model):
manual_quotation = fields.Boolean('人工编程', default=False, compute=_compute_manual_quotation, store=True)
is_scrap = fields.Boolean('是否报废', default=False)
is_remanufacture = fields.Boolean('是否重新制造', default=False)
remanufacture_count = fields.Integer("重新制造订单数量", compute='_compute_remanufacture_production_ids')
remanufacture_production_id = fields.Many2one('mrp.production', string='')
@api.depends('remanufacture_production_id')
def _compute_remanufacture_production_ids(self):
for production in self:
if production.remanufacture_production_id:
remanufacture_production = self.env['mrp.production'].search(
[('id', '=', production.remanufacture_production_id.id)])
if remanufacture_production:
production.remanufacture_count = len(remanufacture_production)
else:
production.remanufacture_count = 0
def action_view_remanufacture_productions(self):
self.ensure_one()
mrp_production = self.env['mrp.production'].search(
[('id', '=', self.remanufacture_production_id.id)])
action = {
'res_model': 'mrp.production',
'type': 'ir.actions.act_window',
'view_mode': 'form',
'res_id': mrp_production.id,
}
return action
@api.depends(
'move_raw_ids.state', 'move_raw_ids.quantity_done', 'move_finished_ids.state', 'tool_state',
@@ -813,8 +838,8 @@ class MrpProduction(models.Model):
'target': 'new',
'context': {
'default_production_id': self.id,
'default_programming_state': '编程中' if cloud_programming[
'programming_state'] != '已下发' else '已下发',
'default_reprogramming_num': cloud_programming['reprogramming_num'],
'default_programming_states': cloud_programming['programming_state'],
'default_is_reprogramming': True if cloud_programming['programming_state'] in ['已下发'] else False
}
}
@@ -961,32 +986,19 @@ class MrpProduction(models.Model):
move_values = {'product_description_variants': '',
'date_planned': datetime.now(),
'date_deadline': datetime.now(),
# 'move_dest_ids': self.env['stock.move'].search([('id', '=', move.id)]),
'move_dest_ids': move,
'group_id': False,
'group_id': move.group_id,
'route_ids': [],
'warehouse_id': self.warehouse_id,
'priority': 0,
'orderpoint_id': False,
'product_packaging_id': False}
rule = self.env['stock.rule'].search(
[('action', '=', 'pull'), ('procure_method', '=', 'mts_else_mto'), (
'location_dest_id', '=', self.env['stock.location'].search([('parent_path', '=', '2/5/')]).id),
('location_src_id', '=', self.env['stock.location'].search(
[('barcode', '=', 'CP')]).id)])
# origin = move._prepare_procurement_origin()
procurement_requests.append(self.env['procurement.group'].Procurement(
move.product_id, 1.0, move.product_uom,
self.env['stock.location'].search([('barcode', '=', 'CP')]),
rule and rule.name or "/",
move.location_id, move.rule_id and move.rule_id.name or "/",
sale_order.name, move.company_id, move_values))
self.env['procurement.group'].run(procurement_requests,
raise_user_error=not self.env.context.get('from_orderpoint'))
# self.env['stock.move'].sudo().create(productions._get_moves_finished_values())
# productions.filtered(lambda p: (not p.orderpoint_id and p.move_raw_ids) or \
# (
# p.move_dest_ids.procure_method != 'make_to_order' and
# not p.move_raw_ids and not p.workorder_ids)).action_confirm()
productions = self.env['mrp.production'].sudo().search(
[('origin', '=', self.origin)], order='id desc', limit=1)
move = self.env['stock.move'].search([('origin', '=', productions.name)], order='id desc')
@@ -1014,8 +1026,29 @@ class MrpProduction(models.Model):
'picking_id': sfp_move.picking_id.id, 'picking_type_id': sfp_move.picking_type_id.id,
'production_id': False})
productions.write({'programming_no': self.programming_no, 'is_remanufacture': True})
productions.procurement_group_id.mrp_production_ids.move_dest_ids.write(
{'group_id': self.env['procurement.group'].search([('name', '=', sale_order.name)])})
# productions.procurement_group_id.mrp_production_ids.move_dest_ids.write(
# {'group_id': self.env['procurement.group'].search([('name', '=', sale_order.name)])})
stock_picking = None
pc_picking = self.env['stock.picking'].search(
[('origin', '=', productions.name), ('name', 'ilike', 'WH/PC/')])
stock_picking = pc_picking
int_picking = self.env['stock.picking'].search(
[('origin', '=', productions.name), ('name', 'ilike', 'WH/INT/')])
stock_picking |= int_picking
for pick in stock_picking:
if pick.move_ids:
product_type_id = pick.move_ids[0].product_id.categ_id
if product_type_id.name == '坯料':
location_id = self.env['stock.location'].search([('name', '=', '坯料存货区')])
if not location_id:
logging.info(f'没有搜索到【坯料存货区】: {location_id}')
break
if pick.picking_type_id.name == '内部调拨':
if pick.location_dest_id.product_type != product_type_id:
pick.location_dest_id = location_id.id
elif pick.picking_type_id.name == '生产发料':
if pick.location_id.product_type != product_type_id:
pick.location_id = location_id.id
scarp_process_parameter_workorder = self.env['mrp.workorder'].search(
[('surface_technics_parameters_id', '!=', False), ('production_id', '=', self.id),
('is_subcontract', '=', True)])

View File

@@ -169,7 +169,6 @@ class StockRule(models.Model):
else:
forecasted_qties_by_loc[rule.location_src_id][procurement.product_id.id] -= qty_needed
procure_method = 'make_to_stock'
move_values = rule._get_stock_move_values(*procurement)
move_values['procure_method'] = procure_method
moves_values_by_company[procurement.company_id.id].append(move_values)
@@ -177,13 +176,10 @@ class StockRule(models.Model):
for company_id, moves_values in moves_values_by_company.items():
# create the move as SUPERUSER because the current user may not have the rights to do it (mto product
# launched by a sale for example)
logging.info(moves_values)
moves = self.env['stock.move'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create(
moves_values)
logging.info(moves)
# Since action_confirm launch following procurement_group we should activate it.
moves._action_confirm()
return True
@api.model

View File

@@ -127,7 +127,7 @@
confirm="是否确认更新程序"
attrs="{'invisible': ['|',('state', '!=', 'rework'),('programming_state', '!=', '已编程未下发')]}"/>
<button name="button_rework" string="返工" type="object" groups="sf_base.group_sf_mrp_user"
attrs="{'invisible': ['|',('state', '!=', 'rework') ,('programming_state', '!=', '已编程')]}"/>
attrs="{'invisible': ['|','|',('state', '!=', 'rework') ,('programming_state', '!=', '已编程'),('is_rework', '=', True)]}"/>
<button name="button_scrap_new" string="报废" type="object"
groups="sf_base.group_sf_mrp_user"
attrs="{'invisible': ['|',('is_scrap', '=', False),('state','=','cancel')]}"/>
@@ -201,6 +201,19 @@
data-hotkey="l"/>
</xpath>
<xpath expr="//button[@name='action_view_mo_delivery']" position="before">
<button class="oe_stat_button" name="action_view_remanufacture_productions" type="object"
icon="fa-wrench" attrs="{'invisible': [('remanufacture_count', '=', 0)]}"
groups="mrp.group_mrp_user">
<div class="o_field_widget o_stat_info">
<span class="o_stat_value">
<field name="remanufacture_count"/>
</span>
<span class="o_stat_text">新的制造</span>
</div>
</button>
</xpath>
<xpath expr="//header//button[@name='action_toggle_is_locked']" position="replace">
<button name="action_toggle_is_locked"
attrs="{'invisible': ['|', ('show_lock', '=', False), ('is_locked', '=', True)]}"

View File

@@ -13,9 +13,10 @@ class ProductionWizard(models.TransientModel):
_description = '制造订单向导'
production_id = fields.Many2one('mrp.production', string='制造订单号')
reprogramming_num = fields.Integer('重新编程次数', default=0)
is_reprogramming = fields.Boolean(string='申请重新编程', default=False)
is_remanufacture = fields.Boolean(string='重新生成制造订单', default=True)
programming_state = fields.Selection(
programming_states = fields.Selection(
[('待编程', '待编程'), ('编程中', '编程中'), ('已编程', '已编程'), ('已编程未下发', '已编程未下发'),
('已下发', '已下发')],
string='编程状态')
@@ -26,18 +27,21 @@ class ProductionWizard(models.TransientModel):
self.is_reprogramming = False
def confirm(self):
self.production_id.action_cancel()
self.production_id.detection_result_ids.write({'handle_result': '已处理'})
self.production_id.write({'state': 'cancel', 'scrap_ids': [(0, 0, {
'name': self.env['ir.sequence'].next_by_code('stock.scrap') or _('New'),
'product_id': self.production_id.product_id.id,
'scrap_qty': 1,
'lot_id': self.production_id.move_line_raw_ids.lot_id.id,
'origin': self.production_id.origin,
'date_done': fields.datetime.now(),
'lot_id': self.env['stock.move.line'].search(
[('move_id', '=', self.production_id.move_raw_ids[0].id)]).lot_id.id,
'location_id': self.production_id.move_raw_ids.filtered(lambda x: x.state not in (
'done',
'cancel')) and self.production_id.location_src_id.id or self.production_id.location_dest_id.id,
'scrap_location_id': self.env['stock.scrap']._get_default_scrap_location_id(),
'state': 'done'})]})
self.production_id.action_cancel()
if self.is_remanufacture is True:
ret = {'programming_list': [], 'is_reprogramming': self.is_reprogramming}
if self.is_reprogramming is True:
@@ -78,6 +82,7 @@ class ProductionWizard(models.TransientModel):
ret['programming_list'].append(vals)
new_production = self.production_id.recreateManufacturing(ret)
self.production_id.write({'remanufacture_production_id': new_production.id})
if self.is_reprogramming is False:
for panel in new_production.product_id.model_processing_panel.split(','):
scrap_cnc_workorder = max(

View File

@@ -7,15 +7,26 @@
<form>
<sheet>
<field name="production_id" invisible="1"/>
<field name="programming_state" invisible="1"/>
<field name="programming_states" invisible="1"/>
<div>
重新生成制造订单
<field name="is_remanufacture" force_save="1"/>
</div>
<div attrs='{"invisible": [("reprogramming_num","=",0)]}'>
注意: 该制造订单产品已申请重新编程次数为<field
name="reprogramming_num" string=""
readonly="1"
style='color:red;'/>,且当前编程状态为
<field name="programming_states" string=""
decoration-info="programming_states == '待编程'"
decoration-success="programming_states == '已下发'"
decoration-warning="programming_states =='编程中'"
decoration-danger="programming_states =='已编程'" readonly="1"/>
</div>
<div attrs='{"invisible": [("is_remanufacture","=",False)]}'>
<span style='font-weight:bold;'>申请重新编程
<field name="is_reprogramming" force_save="1"
attrs='{"readonly": [("programming_state","not in",["已下发"])]}'/>
attrs='{"readonly": [("programming_states","not in",["已下发"])]}'/>
</span>
</div>
<footer>

View File

@@ -24,9 +24,11 @@ class Sf_Mrs_Connect(http.Controller):
ret = json.loads(datas)
ret = json.loads(ret['result'])
logging.info('下发编程单:%s' % ret)
domain = [('programming_no', '=', ret['programming_no'])]
if ret['manufacturing_type'] == 'scrap':
domain += [('state', 'not in', ['done', 'scrap'])]
productions = request.env['mrp.production'].with_user(
request.env.ref("base.user_admin")).search(
[('programming_no', '=', ret['programming_no'])])
request.env.ref("base.user_admin")).search(domain)
if productions:
# # 拉取所有加工面的程序文件
for r in ret['processing_panel'].split(','):
@@ -88,8 +90,8 @@ class Sf_Mrs_Connect(http.Controller):
lambda ac: ac.routing_type == 'CNC加工' and ac.state not in ['progress', 'done',
'cancel'] and ac.processing_panel == panel)
if cnc_workorder:
program_path_tmp_panel = os.path.join('C://Users//43484//Desktop//fsdownload//test',
panel)
# program_path_tmp_panel = os.path.join('C://Users//43484//Desktop//fsdownload//test',
# panel)
program_path_tmp_panel = os.path.join('/tmp', ret['folder_name'], 'return', panel)
logging.info('program_path_tmp_panel:%s' % program_path_tmp_panel)
files_panel = os.listdir(program_path_tmp_panel)
@@ -108,12 +110,12 @@ class Sf_Mrs_Connect(http.Controller):
pre_workorder.write(
{'processing_drawing': base64.b64encode(open(panel_file_path, 'rb').read())})
productions.write({'programming_state': '已编程', 'work_state': '已编程'})
cnc_program_ids = [item.id for item in productions]
workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search(
[('production_id', 'in', cnc_program_ids)])
if workpiece_delivery:
workpiece_delivery.write(
{'is_cnc_program_down': True, 'production_line_id': productions.production_line_id.id})
# cnc_program_ids = [item.id for item in productions]
# workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search(
# [('production_id', 'in', cnc_program_ids)])
# if workpiece_delivery:
# workpiece_delivery.write(
# {'is_cnc_program_down': True, 'production_line_id': productions.production_line_id.id})
return json.JSONEncoder().encode(res)
else:
res = {'status': 0, 'message': '该制造订单暂未开始'}

View File

@@ -60,7 +60,7 @@ class ReSaleOrder(models.Model):
deadline_of_delivery, payments_way, pay_way):
now_time = datetime.datetime.now()
partner = self.get_customer()
data ={
data = {
'company_id': company_id.id,
'date_order': now_time,
'name': self.env['ir.sequence'].next_by_code('sale.order', sequence_date=now_time),
@@ -79,7 +79,7 @@ class ReSaleOrder(models.Model):
if not isinstance(deadline_of_delivery, str):
data.update({'deadline_of_delivery': deadline_of_delivery})
else:
if deadline_of_delivery!="False":
if deadline_of_delivery != "False":
data.update({'deadline_of_delivery': deadline_of_delivery})
order_id = self.env['sale.order'].sudo().create(data)
@@ -258,7 +258,7 @@ class RePurchaseOrder(models.Model):
if is_exist is False:
purchase_order = self.env['purchase.order'].search(
[('state', '=', 'draft'), ('origin', '=', ','.join(production_process))])
if not purchase_order:
if not purchase_order or len(purchase_order) >= 1:
self.env['purchase.order'].sudo().create({
'partner_id': server_product.seller_ids.partner_id.id,
'origin': ','.join(production_process),