Merge branch 'feature/修复报废' into develop
This commit is contained in:
@@ -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)])
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)]}"
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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': '该制造订单暂未开始'}
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user