Merge branch 'feature/优化最新版报废' into develop

This commit is contained in:
jinling.yang
2024-08-20 14:39:21 +08:00
8 changed files with 256 additions and 81 deletions

View File

@@ -36,7 +36,7 @@ class Http(models.AbstractModel):
post_time = int(datas['HTTP_TIMESTAMP']) post_time = int(datas['HTTP_TIMESTAMP'])
datetime_post = datetime.fromtimestamp(post_time) datetime_post = datetime.fromtimestamp(post_time)
datetime_now = datetime.now().replace(microsecond=0) datetime_now = datetime.now().replace(microsecond=0)
datetime_del = datetime_now + timedelta(seconds=5) datetime_del = datetime_now + timedelta(seconds=30)
if datetime_post > datetime_del: if datetime_post > datetime_del:
raise AuthenticationError('请求已过期') raise AuthenticationError('请求已过期')
check_str = '%s%s%s' % (datas['HTTP_TOKEN'], post_time, factory_secret.sf_secret_key) check_str = '%s%s%s' % (datas['HTTP_TOKEN'], post_time, factory_secret.sf_secret_key)

View File

@@ -6,7 +6,9 @@ import os
import re import re
import requests import requests
from itertools import groupby from itertools import groupby
from odoo import api, fields, models, _ from datetime import datetime
from collections import defaultdict, namedtuple
from odoo import api, fields, models, SUPERUSER_ID, _
from odoo.exceptions import UserError, ValidationError from odoo.exceptions import UserError, ValidationError
from odoo.addons.sf_base.commons.common import Common from odoo.addons.sf_base.commons.common import Common
from odoo.tools import float_compare, float_round, float_is_zero, format_datetime from odoo.tools import float_compare, float_round, float_is_zero, format_datetime
@@ -77,9 +79,10 @@ class MrpProduction(models.Model):
('pending_cam', '待加工'), ('pending_cam', '待加工'),
('progress', '加工中'), ('progress', '加工中'),
('rework', '返工'), ('rework', '返工'),
('scrap', '报废'),
('to_close', 'To Close'), ('to_close', 'To Close'),
('done', 'Done'), ('done', 'Done'),
('cancel', '报废')], string='State', ('cancel', '已取消')], string='State',
compute='_compute_state', copy=False, index=True, readonly=True, compute='_compute_state', copy=False, index=True, readonly=True,
store=True, tracking=True, store=True, tracking=True,
help=" * Draft: The MO is not confirmed yet.\n" help=" * Draft: The MO is not confirmed yet.\n"
@@ -122,6 +125,7 @@ class MrpProduction(models.Model):
manual_quotation = fields.Boolean('人工编程', default=False, readonly=True) manual_quotation = fields.Boolean('人工编程', default=False, readonly=True)
is_scrap = fields.Boolean('是否报废', default=False) is_scrap = fields.Boolean('是否报废', default=False)
is_remanufacture = fields.Boolean('是否重新制造', default=False)
@api.depends( @api.depends(
'move_raw_ids.state', 'move_raw_ids.quantity_done', 'move_finished_ids.state', 'tool_state', 'move_raw_ids.state', 'move_raw_ids.quantity_done', 'move_finished_ids.state', 'tool_state',
@@ -166,7 +170,7 @@ class MrpProduction(models.Model):
production.state = 'pending_cam' production.state = 'pending_cam'
if production.state == 'progress': if production.state == 'progress':
if all(wo_state not in ('progress', 'done', 'rework') for wo_state in if all(wo_state not in ('progress', 'done', 'rework', 'scrap') for wo_state in
production.workorder_ids.mapped('state')): production.workorder_ids.mapped('state')):
production.state = 'pending_cam' production.state = 'pending_cam'
if production.is_rework is True: if production.is_rework is True:
@@ -184,9 +188,14 @@ class MrpProduction(models.Model):
for wo in for wo in
production.workorder_ids): production.workorder_ids):
production.state = 'rework' production.state = 'rework'
if any(wo.test_results == '报废' and wo.state == 'done' for wo in production.workorder_ids):
production.state = 'scrap'
if any(dr.test_results == '报废' and dr.handle_result == '已处理' for dr in
production.detection_result_ids):
production.state = 'cancel'
# 如果制造订单的功能刀具为【无效刀】则制造订单状态改为返工 # 如果制造订单的功能刀具为【无效刀】则制造订单状态改为返工
# if production.tool_state == '2': if production.tool_state == '2':
# production.state = 'rework' production.state = 'rework'
def action_check(self): def action_check(self):
""" """
@@ -788,6 +797,22 @@ class MrpProduction(models.Model):
}) })
return action return action
# 返工
def button_scrap_new(self):
cloud_programming = self._cron_get_programming_state()
return {
'name': _('报废'),
'type': 'ir.actions.act_window',
'view_mode': 'form',
'res_model': 'sf.production.wizard',
'target': 'new',
'context': {
'default_production_id': self.id,
'default_programming_state': cloud_programming['programming_state'],
'default_is_reprogramming': True if cloud_programming['programming_state'] in ['已下发'] else False
}
}
# 返工 # 返工
def button_rework(self): def button_rework(self):
cloud_programming = None cloud_programming = None
@@ -912,44 +937,117 @@ class MrpProduction(models.Model):
logging.info('get_new_program error:%s' % e) logging.info('get_new_program error:%s' % e)
raise UserError("从云平台获取最新程序失败,请联系管理员") raise UserError("从云平台获取最新程序失败,请联系管理员")
def recreateManufacturing(self): def recreateManufacturing(self, item):
""" """
重新生成制造订单 重新生成制造订单
""" """
if self.is_scrap is True: if self.is_scrap is True:
sale_order = self.env['sale.order'].sudo().search([('name', '=', productions.origin)]) procurement_requests = []
values = self.env['mrp.production'].create_production1_values(self.production_id) sale_order = self.env['sale.order'].sudo().search([('name', '=', self.origin)])
productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company( values = self.env['mrp.production'].create_production1_values(self)
self.production_id.company_id).create( # productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company(
values) # self.company_id).create(
# self.env['stock.move'].sudo().create(productions._get_moves_raw_values()) # values)
self.env['stock.move'].sudo().create(productions._get_moves_finished_values()) # 查询出库移动记录
productions._create_workorder() out_picking = self.env['stock.picking'].search(
productions.filtered(lambda p: (not p.orderpoint_id and p.move_raw_ids) or \ [('origin', '=', sale_order.name), ('name', 'ilike', 'WH/OUT/')])
( move = out_picking.move_ids.filtered(lambda pd: pd.product_id == self.product_id)
p.move_dest_ids.procure_method != 'make_to_order' and move_values = {'product_description_variants': '',
not p.move_raw_ids and not p.workorder_ids)).action_confirm() 'date_planned': datetime.now(),
for production_item in productions: 'date_deadline': datetime.now(),
process_parameter_workorder = self.env['mrp.workorder'].search( # 'move_dest_ids': self.env['stock.move'].search([('id', '=', move.id)]),
[('surface_technics_parameters_id', '!=', False), ('production_id', '=', production_item.id), 'move_dest_ids': move,
('is_subcontract', '=', True)]) 'group_id': False,
if process_parameter_workorder: 'route_ids': [],
is_pick = False 'warehouse_id': self.warehouse_id,
consecutive_workorders = [] 'priority': 0,
m = 0 'orderpoint_id': False,
sorted_workorders = sorted(process_parameter_workorder, key=lambda w: w.id) 'product_packaging_id': False}
for i in range(len(sorted_workorders) - 1): rule = self.env['stock.rule'].search(
if m == 0: [('action', '=', 'pull'), ('procure_method', '=', 'mts_else_mto'), (
is_pick = False 'location_dest_id', '=', self.env['stock.location'].search([('parent_path', '=', '2/5/')]).id),
if sorted_workorders[i].supplier_id.id == sorted_workorders[i + 1].supplier_id.id and \ ('location_src_id', '=', self.env['stock.location'].search(
sorted_workorders[i].is_subcontract == sorted_workorders[i + 1].is_subcontract and \ [('barcode', '=', 'CP')]).id)])
sorted_workorders[i].id == sorted_workorders[i + 1].id - 1: origin = move._prepare_procurement_origin()
if sorted_workorders[i] not in consecutive_workorders: procurement_requests.append(self.env['procurement.group'].Procurement(
consecutive_workorders.append(sorted_workorders[i]) move.product_id, 1.0, move.product_uom,
consecutive_workorders.append(sorted_workorders[i + 1]) self.env['stock.location'].search([('barcode', '=', 'CP')]),
m += 1 rule and rule.name or "/",
continue origin, move.company_id, move_values))
else: 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')
for mo in move:
print(mo.id)
if mo.name in ['/', '']:
if mo.name == '/':
domain = [('barcode', '=', 'WH-PC'), ('sequence_code', '=', 'PC')]
elif mo.name == '':
domain = [('barcode', '=', 'WH-INTERNAL'), ('sequence_code', '=', 'INT')]
picking_type = self.env['stock.picking.type'].search(domain)
mo.picking_type_id = picking_type.id
mo._assign_picking()
mo.reference = mo.picking_id.name
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)])})
scarp_process_parameter_workorder = self.env['mrp.workorder'].search(
[('surface_technics_parameters_id', '!=', False), ('production_id', '=', self.id),
('is_subcontract', '=', True)])
if scarp_process_parameter_workorder:
production_programming = self.env['mrp.production'].search(
[('programming_no', '=', self.programming_no)], order='name asc')
production_list = [production.name for production in production_programming]
purchase_orders = self.env['purchase.order'].search([('origin', '=', ','.join(production_list))])
for purchase_item in purchase_orders.order_line:
for process_item in scarp_process_parameter_workorder:
if purchase_item.product_id.categ_type == '表面工艺':
if purchase_item.product_id.server_product_process_parameters_id == process_item.surface_technics_parameters_id:
print(purchase_orders.find(productions.name))
if purchase_orders.find(productions.name) == -1:
purchase_orders.origin += productions.name
if item['is_reprogramming'] is False:
productions._create_workorder(item)
productions.programming_state = '已编程'
for production_item in productions:
process_parameter_workorder = self.env['mrp.workorder'].search(
[('surface_technics_parameters_id', '!=', False), ('production_id', '=', production_item.id),
('is_subcontract', '=', True)])
if process_parameter_workorder:
is_pick = False
consecutive_workorders = []
m = 0
sorted_workorders = sorted(process_parameter_workorder, key=lambda w: w.id)
for i in range(len(sorted_workorders) - 1):
if m == 0:
is_pick = False
if sorted_workorders[i].supplier_id.id == sorted_workorders[i + 1].supplier_id.id and \
sorted_workorders[i].is_subcontract == sorted_workorders[i + 1].is_subcontract and \
sorted_workorders[i].id == sorted_workorders[i + 1].id - 1:
if sorted_workorders[i] not in consecutive_workorders:
consecutive_workorders.append(sorted_workorders[i])
consecutive_workorders.append(sorted_workorders[i + 1])
m += 1
continue
else:
if m == len(consecutive_workorders) - 1 and m != 0:
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders,
production_item)
if sorted_workorders[i] in consecutive_workorders:
is_pick = True
consecutive_workorders = []
m = 0
# 当前面的连续工序生成对应的外协出入库单再生成当前工序的外协出入库单
if is_pick is False:
self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i],
production_item)
if m == len(consecutive_workorders) - 1 and m != 0: if m == len(consecutive_workorders) - 1 and m != 0:
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, self.env['stock.picking'].create_outcontract_picking(consecutive_workorders,
production_item) production_item)
@@ -957,25 +1055,17 @@ class MrpProduction(models.Model):
is_pick = True is_pick = True
consecutive_workorders = [] consecutive_workorders = []
m = 0 m = 0
# 当前面的连续工序生成对应的外协出入库单再生成当前工序的外协出入库单
if is_pick is False:
self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i],
production_item)
if m == len(consecutive_workorders) - 1 and m != 0: if m == len(consecutive_workorders) - 1 and m != 0:
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, self.env['stock.picking'].create_outcontract_picking(consecutive_workorders,
production_item) production_item)
if sorted_workorders[i] in consecutive_workorders: if is_pick is False and m == 0:
is_pick = True if len(sorted_workorders) == 1:
consecutive_workorders = [] self.env['stock.picking'].create_outcontract_picking(sorted_workorders, production_item)
m = 0 else:
if m == len(consecutive_workorders) - 1 and m != 0: self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i],
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production_item) production_item)
if is_pick is False and m == 0: else:
if len(sorted_workorders) == 1: productions.programming_state = '编程中'
self.env['stock.picking'].create_outcontract_picking(sorted_workorders, production_item)
else:
self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i], production_item)
for production in productions: for production in productions:
origin_production = production.move_dest_ids and production.move_dest_ids[ origin_production = production.move_dest_ids and production.move_dest_ids[
0].raw_material_production_id or False 0].raw_material_production_id or False
@@ -1005,9 +1095,8 @@ class MrpProduction(models.Model):
workorder_duration += workorder.duration_expected workorder_duration += workorder.duration_expected
if sale_order: if sale_order:
sale_order.mrp_production_ids |= productions # sale_order.mrp_production_ids |= productions
# sale_order.write({'schedule_status': 'to schedule'}) self.env['sf.production.plan'].sudo().with_company(self.company_id).create({
self.env['sf.production.plan'].sudo().with_company(self.production_id.company_id).create({
'name': productions.name, 'name': productions.name,
'order_deadline': sale_order.deadline_of_delivery, 'order_deadline': sale_order.deadline_of_delivery,
'production_id': productions.id, 'production_id': productions.id,
@@ -1017,11 +1106,13 @@ class MrpProduction(models.Model):
'product_id': productions.product_id.id, 'product_id': productions.product_id.id,
'state': 'draft', 'state': 'draft',
}) })
return productions
# 在之前的销售单上重新生成制造订单 # 在之前的销售单上重新生成制造订单
def create_production1_values(self, production, sale_order): def create_production1_values(self, production):
production_values_str = {'origin': production.origin, production_values_str = {'origin': production.origin,
'product_id': production.product_id.id, 'product_id': production.product_id.id,
'programming_state': '已编程',
'product_description_variants': production.product_description_variants, 'product_description_variants': production.product_description_variants,
'product_qty': production.product_qty, 'product_qty': production.product_qty,
'product_uom_id': production.product_uom_id.id, 'product_uom_id': production.product_uom_id.id,
@@ -1031,7 +1122,8 @@ class MrpProduction(models.Model):
'date_deadline': production.date_deadline, 'date_deadline': production.date_deadline,
'date_planned_start': production.date_planned_start, 'date_planned_start': production.date_planned_start,
'date_planned_finished': production.date_planned_finished, 'date_planned_finished': production.date_planned_finished,
'procurement_group_id': sale_order.id, # 'procurement_group_id': self.env["procurement.group"].create(
# {'name': production.name}).id,
'propagate_cancel': production.propagate_cancel, 'propagate_cancel': production.propagate_cancel,
'orderpoint_id': production.orderpoint_id.id, 'orderpoint_id': production.orderpoint_id.id,
'picking_type_id': production.picking_type_id.id, 'picking_type_id': production.picking_type_id.id,

View File

@@ -934,7 +934,7 @@ class ResMrpWorkOrder(models.Model):
workorder.state = 'waiting' workorder.state = 'waiting'
elif workorder.routing_type == '解除装夹' and workorder.state not in ['done', 'rework', 'cancel']: elif workorder.routing_type == '解除装夹' and workorder.state not in ['done', 'rework', 'cancel']:
if cnc_workorder: if cnc_workorder:
if not cnc_workorder_pending: if not cnc_workorder_pending or unclamp_workorder.test_results == '报废':
workorder.state = 'waiting' workorder.state = 'waiting'
# else: # else:
# if workorder.production_id.is_rework is True: # if workorder.production_id.is_rework is True:
@@ -1173,7 +1173,8 @@ class ResMrpWorkOrder(models.Model):
'detailed_reason': record.detailed_reason, 'detailed_reason': record.detailed_reason,
'processing_panel': record.processing_panel, 'processing_panel': record.processing_panel,
'routing_type': record.routing_type, 'routing_type': record.routing_type,
'handle_result': '待处理' if record.test_results == '返工' or record.is_rework is True else '', 'handle_result': '待处理' if record.test_results in ['返工',
'报废'] or record.is_rework is True else '',
'test_results': record.test_results, 'test_results': record.test_results,
'test_report': record.detection_report})], 'test_report': record.detection_report})],
'is_scrap': True if record.test_results == '报废' else False}) 'is_scrap': True if record.test_results == '报废' else False})

View File

@@ -68,6 +68,7 @@ class StockRule(models.Model):
@api.model @api.model
def _run_pull(self, procurements): def _run_pull(self, procurements):
logging.info(procurements)
moves_values_by_company = defaultdict(list) moves_values_by_company = defaultdict(list)
mtso_products_by_locations = defaultdict(list) mtso_products_by_locations = defaultdict(list)
@@ -176,7 +177,9 @@ class StockRule(models.Model):
for company_id, moves_values in moves_values_by_company.items(): 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 # 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) # 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) 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. # Since action_confirm launch following procurement_group we should activate it.
moves._action_confirm() moves._action_confirm()

View File

@@ -7,10 +7,10 @@
<field name="model">mrp.production</field> <field name="model">mrp.production</field>
<field name="inherit_id" ref="mrp.mrp_production_tree_view"/> <field name="inherit_id" ref="mrp.mrp_production_tree_view"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<!-- <xpath expr="//button[@name='do_unreserve']" position="after">--> <!-- <xpath expr="//button[@name='do_unreserve']" position="after">-->
<!-- <button name="do_update_program" type="object" string="更新程序"--> <!-- <button name="do_update_program" type="object" string="更新程序"-->
<!-- groups="sf_base.group_sf_mrp_user"/>--> <!-- groups="sf_base.group_sf_mrp_user"/>-->
<!-- </xpath>--> <!-- </xpath>-->
<xpath expr="//field[@name='product_id']" position="replace"/> <xpath expr="//field[@name='product_id']" position="replace"/>
<xpath expr="//field[@name='product_qty']" position="replace"/> <xpath expr="//field[@name='product_qty']" position="replace"/>
<xpath expr="//field[@name='product_uom_id']" position="replace"/> <xpath expr="//field[@name='product_uom_id']" position="replace"/>
@@ -70,7 +70,7 @@
<!-- <attribute name="statusbar_visible">draft,confirmed,progress,pending_processing,completed,done --> <!-- <attribute name="statusbar_visible">draft,confirmed,progress,pending_processing,completed,done -->
<!-- </attribute> --> <!-- </attribute> -->
<attribute name="statusbar_visible"> <attribute name="statusbar_visible">
confirmed,pending_cam,progress,done confirmed,pending_cam,progress,rework,scrap,done
</attribute> </attribute>
</xpath> </xpath>
<xpath expr="//sheet//group//group[2]//label" position="before"> <xpath expr="//sheet//group//group[2]//label" position="before">
@@ -128,9 +128,9 @@
attrs="{'invisible': ['|',('state', '!=', 'rework'),('programming_state', '!=', '已编程未下发')]}"/> attrs="{'invisible': ['|',('state', '!=', 'rework'),('programming_state', '!=', '已编程未下发')]}"/>
<button name="button_rework" string="返工" type="object" groups="sf_base.group_sf_mrp_user" <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', '!=', '已编程')]}"/>
<!-- <button name="%(sf_manufacturing.action_sf_production_wizard)d" string="报废" type="action"--> <button name="button_scrap_new" string="报废" type="object"
<!-- groups="sf_base.group_sf_mrp_user"--> groups="sf_base.group_sf_mrp_user"
<!-- attrs="{'invisible': [('is_scrap', '=', False)]}"/>--> attrs="{'invisible': [('is_scrap', '=', False)]}"/>
</xpath> </xpath>
<xpath expr="(//header//button[@name='button_mark_done'])[3]" position="replace"> <xpath expr="(//header//button[@name='button_mark_done'])[3]" position="replace">
<button name="button_mark_done" attrs="{'invisible': [ <button name="button_mark_done" attrs="{'invisible': [
@@ -460,6 +460,7 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//filter[@name='filter_in_progress']" position="before"> <xpath expr="//filter[@name='filter_in_progress']" position="before">
<filter string="返工" name="filter_rework" domain="[('state', '=', 'rework')]"/> <filter string="返工" name="filter_rework" domain="[('state', '=', 'rework')]"/>
<filter string="报废" name="filter_scrap" domain="[('state', '=', 'scrap')]"/>
</xpath> </xpath>
<xpath expr="//filter[@name='planning_issues']" position="before"> <xpath expr="//filter[@name='planning_issues']" position="before">
<separator/> <separator/>

View File

@@ -218,7 +218,7 @@
<xpath expr="//label[1]" position="before"> <xpath expr="//label[1]" position="before">
<field name='routing_type' readonly="1"/> <field name='routing_type' readonly="1"/>
<field name='process_state' attrs='{"invisible": [("routing_type","!=","装夹预调")]}'/> <field name='process_state' attrs='{"invisible": [("routing_type","!=","装夹预调")]}'/>
<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)]}"/> attrs="{'invisible': [('rfid_code_old', '!=', 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)]}"/>
</xpath> </xpath>
@@ -538,7 +538,7 @@
<xpath expr="//page[1]" position="before"> <xpath expr="//page[1]" position="before">
<page string="CNC程序" attrs='{"invisible": [("routing_type","!=","CNC加工")]}'> <page string="CNC程序" attrs='{"invisible": [("routing_type","!=","CNC加工")]}'>
<field name="cnc_ids" widget="one2many" string="工作程序" default_order="sequence_number,id" <field name="cnc_ids" widget="one2many" string="工作程序" default_order="sequence_number,id"
readonly="1"> readonly="0">
<tree> <tree>
<field name="sequence_number"/> <field name="sequence_number"/>
<field name="program_name"/> <field name="program_name"/>

View File

@@ -2,6 +2,8 @@
# Part of YiZuo. See LICENSE file for full copyright and licensing details. # Part of YiZuo. See LICENSE file for full copyright and licensing details.
import logging import logging
from odoo.exceptions import UserError, ValidationError from odoo.exceptions import UserError, ValidationError
from collections import defaultdict, namedtuple
from odoo.addons.stock.models.stock_rule import ProcurementException
from datetime import datetime from datetime import datetime
from odoo import models, api, fields, _ from odoo import models, api, fields, _
@@ -11,11 +13,81 @@ class ProductionWizard(models.TransientModel):
_description = '制造订单向导' _description = '制造订单向导'
production_id = fields.Many2one('mrp.production', string='制造订单号') production_id = fields.Many2one('mrp.production', string='制造订单号')
is_reprogramming = fields.Boolean(string='申请重新编程', default=True) is_reprogramming = fields.Boolean(string='申请重新编程', default=False)
is_remanufacture = fields.Boolean(string='重新生成制造订单', default=True) is_remanufacture = fields.Boolean(string='重新生成制造订单', default=True)
programming_state = fields.Selection(
[('待编程', '待编程'), ('编程中', '编程中'), ('已编程', '已编程'), ('已编程未下发', '已编程未下发'),
('已下发', '已下发')],
string='编程状态')
def confirm(self): def confirm(self):
if self.is_reprogramming is True: self.production_id.action_cancel()
self.production_id.update_programming_state() self.production_id.detection_result_ids.write({'handle_result': '已处理'})
self.production_id.action_cancel() 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,
'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'})]})
if self.is_remanufacture is True:
ret = {'programming_list': [], 'is_reprogramming': self.is_reprogramming}
if self.is_reprogramming is True:
self.production_id.update_programming_state()
else:
scrap_cnc = self.production_id.workorder_ids.filtered(lambda crw: crw.routing_type == 'CNC加工').cnc_ids
scrap_cmm = self.production_id.workorder_ids.filtered(lambda cm: cm.routing_type == 'CNC加工').cmm_ids
for item_line in scrap_cnc:
vals = {
'sequence_number': item_line.sequence_number,
'program_name': item_line.program_name,
'cutting_tool_name': item_line.cutting_tool_name,
'cutting_tool_no': item_line.cutting_tool_no,
'processing_type': item_line.processing_type,
'margin_x_y': item_line.margin_x_y,
'margin_z': item_line.margin_z,
'depth_of_processing_z': item_line.depth_of_processing_z,
'cutting_tool_extension_length': item_line.cutting_tool_extension_length,
'estimated_processing_time': item_line.estimated_processing_time,
'cutting_tool_handle_type': item_line.cutting_tool_handle_type,
'ftp_path': item_line.program_path,
'processing_panel': item_line.workorder_id.processing_panel,
'program_create_date': datetime.strftime(item_line.program_create_date,
'%Y-%m-%d %H:%M:%S'),
'remark': item_line.remark
}
ret['programming_list'].append(vals)
for cmm_line in scrap_cmm:
vals = {
'sequence_number': cmm_line.sequence_number,
'program_name': cmm_line.program_name,
'ftp_path': cmm_line.program_path,
'processing_panel': item_line.workorder_id.processing_panel,
'program_create_date': datetime.strftime(
cmm_line.program_create_date,
'%Y-%m-%d %H:%M:%S')
}
ret['programming_list'].append(vals)
new_production = self.production_id.recreateManufacturing(ret)
if self.is_reprogramming is False:
for panel in new_production.product_id.model_processing_panel.split(','):
scrap_cnc_workorder = max(
self.production_id.workorder_ids.filtered(
lambda
scn: scn.processing_panel == panel and scn.routing_type == 'CNC加工'),
key=lambda w: w.create_date)
scrap_pre_workorder = max(self.production_id.workorder_ids.filtered(
lambda
pr: pr.processing_panel == panel and pr.routing_type == '装夹预调'),
key=lambda w1: w1.create_date)
new_cnc_workorder = new_production.workorder_ids.filtered(
lambda
nc: nc.processing_panel == panel and nc.routing_type == 'CNC加工')
new_cnc_workorder.write({'cnc_worksheet': scrap_cnc_workorder.cnc_worksheet})
new_pre_workorder = new_production.workorder_ids.filtered(lambda
p: p.routing_type == '装夹预调' and p.processing_panel == panel)
new_pre_workorder.write({'processing_drawing': scrap_pre_workorder.processing_drawing})

View File

@@ -6,14 +6,17 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<form> <form>
<sheet> <sheet>
<field name="production_id" invisible="True"/> <field name="production_id" invisible="1"/>
<field name="programming_state" invisible="1"/>
<div> <div>
重新生成制造订单 重新生成制造订单
<field name="is_remanufacture"/> <field name="is_remanufacture" force_save="1"/>
</div> </div>
<div> <div>
申请重新编程 <span style='font-weight:bold;'>申请重新编程
<field name="is_reprogramming" attrs='{"invisible": [("is_remanufacture","=",False)]}'/> <field name="is_reprogramming" force_save="1"
attrs='{"readonly": [("programming_state","not in",["已下发"])]}'/>
</span>
</div> </div>
<footer> <footer>
<button string="确认" name="confirm" type="object" class="oe_highlight" confirm="是否确认报废"/> <button string="确认" name="confirm" type="object" class="oe_highlight" confirm="是否确认报废"/>
@@ -28,6 +31,9 @@
<field name="name">报废</field> <field name="name">报废</field>
<field name="res_model">sf.production.wizard</field> <field name="res_model">sf.production.wizard</field>
<field name="view_mode">form</field> <field name="view_mode">form</field>
<!-- <field name="context">{-->
<!-- 'default_production_id': active_id}-->
<!-- </field>-->
<field name="target">new</field> <field name="target">new</field>
</record> </record>