From 567ea84b00ee27ce860faaa54005a5309f70d12d Mon Sep 17 00:00:00 2001
From: mgw <1392924357@qq.com>
Date: Mon, 17 Feb 2025 15:37:30 +0800
Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E4=BA=BA=E5=B7=A5=E7=BC=96?=
=?UTF-8?q?=E7=A8=8B=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sf_manufacturing/models/mrp_production.py | 40 ++++--
sf_manufacturing/views/sale_order_views.xml | 6 +-
sf_manufacturing/wizard/sale_order_cancel.py | 130 ++++++++++++++-----
sf_quality/models/quality.py | 4 +-
4 files changed, 131 insertions(+), 49 deletions(-)
diff --git a/sf_manufacturing/models/mrp_production.py b/sf_manufacturing/models/mrp_production.py
index d49fe4f2..1af65426 100644
--- a/sf_manufacturing/models/mrp_production.py
+++ b/sf_manufacturing/models/mrp_production.py
@@ -235,7 +235,7 @@ class MrpProduction(models.Model):
programming_no = fields.Char('编程单号')
work_state = fields.Char('业务状态')
programming_state = fields.Selection(
- [('编程中', '编程中'), ('已编程', '已编程'), ('已编程未下发', '已编程未下发'), ('已下发', '已下发')],
+ [('编程中', '编程中'), ('已编程', '已编程'), ('已编程未下发', '已编程未下发'), ('已下发', '已下发'), ('已取消', '已取消')],
string='编程状态',
tracking=True)
glb_file = fields.Binary("glb模型文件")
@@ -646,6 +646,28 @@ class MrpProduction(models.Model):
logging.info('update_programming_state error:%s' % e)
raise UserError("更新编程单状态失败,请联系管理员")
+ # 修改编程单状态
+ def _change_programming_state(self):
+ try:
+ res = {"programming_no": self.programming_no, "state": "已取消"}
+ logging.info('res=%s:' % res)
+ configsettings = self.env['res.config.settings'].get_values()
+ config_header = Common.get_headers(self, configsettings['token'], configsettings['sf_secret_key'])
+ url = '/api/intelligent_programming/set_state'
+ config_url = configsettings['sf_url'] + url
+ ret = requests.post(config_url, json=res, data=None, headers=config_header)
+ ret = ret.json()
+ result = json.loads(ret['result'])
+ logging.info('change_programming_state-ret:%s' % result)
+ if result['status'] == 1:
+ self.write({'programming_state': '已取消'})
+ else:
+ raise UserError(ret['message'])
+ except Exception as e:
+ logging.info('change_programming_state error:%s' % e)
+ raise UserError("修改编程单状态失败,请联系管理员")
+
+
# cnc程序获取
def fetchCNC(self, production_names):
cnc = self.env['mrp.production'].search([('id', '=', self.id)])
@@ -701,14 +723,14 @@ class MrpProduction(models.Model):
config_url = configsettings['sf_url'] + url
res['token'] = configsettings['token']
# res_str = json.dumps(res)
- # ret = requests.post(config_url, json={}, data=res, headers=config_header)
- # ret = ret.json()
- # logging.info('fetchCNC-ret:%s' % ret)
- # if ret['status'] == 1:
- # self.write(
- # {'programming_no': ret['programming_no'], 'programming_state': '编程中', 'work_state': '编程中'})
- # else:
- # raise UserError(ret['message'])
+ ret = requests.post(config_url, json={}, data=res, headers=config_header)
+ ret = ret.json()
+ logging.info('fetchCNC-ret:%s' % ret)
+ if ret['status'] == 1:
+ self.write(
+ {'programming_no': ret['programming_no'], 'programming_state': '编程中', 'work_state': '编程中'})
+ else:
+ raise UserError(ret['message'])
except Exception as e:
logging.info('fetchCNC error:%s' % e)
raise UserError("cnc程序获取编程单失败,请联系管理员")
diff --git a/sf_manufacturing/views/sale_order_views.xml b/sf_manufacturing/views/sale_order_views.xml
index e17c1546..353739c1 100644
--- a/sf_manufacturing/views/sale_order_views.xml
+++ b/sf_manufacturing/views/sale_order_views.xml
@@ -26,7 +26,7 @@
- {'invisible': [('state', 'not in', ['draft', 'supply method', 'sale', 'processing'])]}
+ {'invisible': [('state', 'not in', ['draft', 'supply method'])]}
警告:取消操作将不可逆,是否确定要取消该单据?
@@ -36,9 +36,9 @@
diff --git a/sf_manufacturing/wizard/sale_order_cancel.py b/sf_manufacturing/wizard/sale_order_cancel.py
index 6e1d35ef..f50ff306 100644
--- a/sf_manufacturing/wizard/sale_order_cancel.py
+++ b/sf_manufacturing/wizard/sale_order_cancel.py
@@ -34,16 +34,46 @@ class SFSaleOrderCancelWizard(models.TransientModel):
def action_confirm_cancel(self):
self.ensure_one()
+
+ # 取消销售订单关联的采购单
+ purchase_orders = self.env['purchase.order'].search([
+ ('origin', '=', self.order_id.name)
+ ])
+ if purchase_orders:
+ purchase_orders.write({'state': 'cancel'})
+
# 取消销售订单
result = self.order_id.action_cancel()
- # 取消关联的制造订单
+
+ # 取消关联的制造订单及其采购单
manufacturing_orders = self.env['mrp.production'].search([
('origin', '=', self.order_id.name)
])
- if manufacturing_orders:
- manufacturing_orders.action_cancel()
- return result
+ for mo in manufacturing_orders:
+ # 取消制造订单关联的采购单,但保持关联关系
+ mo_purchase_orders = self.env['purchase.order'].search([
+ ('origin', '=', mo.name)
+ ])
+ if mo_purchase_orders:
+ mo_purchase_orders.write({'state': 'cancel'})
+
+ # 取消制造订单
+ mo.action_cancel()
+ # 取消制造订单关联的编程单
+ mo._change_programming_state()
+
+ # 取消组件的制造单关联的采购单
+ for comp_mo in self.env['mrp.production'].search([
+ ('origin', '=', mo.name)
+ ]):
+ comp_purchase_orders = self.env['purchase.order'].search([
+ ('origin', '=', comp_mo.name)
+ ])
+ if comp_purchase_orders:
+ comp_purchase_orders.button_cancel()
+
+ return result
class SFSaleOrderCancelLine(models.TransientModel):
_name = 'sf.sale.order.cancel.line'
@@ -65,6 +95,16 @@ class SFSaleOrderCancelLine(models.TransientModel):
def create_from_order(self, wizard_id, order):
sequence = 1
lines = []
+ map_dict = {
+ 'waiting': '等待其他作业',
+ 'to approve': '待批准',
+ 'technology_to_confirmed': '待工艺确认',
+ 'confirmed': '已确认',
+ 'pending': '等待其他工单',
+ 'none': '待处理',
+ 'draft': '报价',
+ 'cancel': '已取消'
+ }
# 检查销售订单
if order.invoice_ids:
@@ -97,7 +137,7 @@ class SFSaleOrderCancelLine(models.TransientModel):
'product_name': picking.product_id.name if picking.product_id else '',
# 'quantity': picking.product_qty if hasattr(picking, 'product_qty') else 0,
'quantity': sum(picking.move_ids.mapped('product_uom_qty') or [0]),
- 'doc_state': picking.state,
+ 'doc_state': map_dict.get(picking.state, picking.state),
'cancel_reason': '已有异动' if picking.state not in ['draft', 'cancel', 'waiting'] else ''
}
lines.append(self.create(vals))
@@ -118,7 +158,7 @@ class SFSaleOrderCancelLine(models.TransientModel):
'doc_number': po.name,
'product_name': po.order_line[0].product_id.name if po.order_line else '',
'quantity': po.order_line[0].product_qty if po.order_line else 0,
- 'doc_state': po.state,
+ 'doc_state': map_dict.get(po.state, po.state),
'cancel_reason': '已有异动' if po.state not in ['draft', 'cancel'] else ''
}
lines.append(self.create(vals))
@@ -139,8 +179,8 @@ class SFSaleOrderCancelLine(models.TransientModel):
'operation_type': '制造',
'product_name': mo.product_id.name,
'quantity': mo.product_qty,
- 'doc_state': mo.state,
- 'cancel_reason': '已有异动' if mo.state not in ['technology_to_confirmed'] else ''
+ 'doc_state': map_dict.get(mo.state, mo.state),
+ 'cancel_reason': '已有异动' if mo.state not in ['technology_to_confirmed', 'cancel'] else ''
}
lines.append(self.create(vals))
sequence += 1
@@ -160,7 +200,7 @@ class SFSaleOrderCancelLine(models.TransientModel):
'operation_type': '制造采购',
'product_name': po.order_line[0].product_id.name if po.order_line else '',
'quantity': po.order_line[0].product_qty if po.order_line else 0,
- 'doc_state': po.state,
+ 'doc_state': map_dict.get(po.state, po.state),
'cancel_reason': '已有异动' if po.state not in ['draft', 'cancel'] else ''
}
lines.append(self.create(vals))
@@ -178,7 +218,7 @@ class SFSaleOrderCancelLine(models.TransientModel):
'operation_type': picking.picking_type_id.name,
'product_name': picking.product_id.name if picking.product_id else '',
'quantity': sum(picking.move_ids.mapped('product_uom_qty') or [0]),
- 'doc_state': picking.state,
+ 'doc_state': map_dict.get(picking.state, picking.state),
'cancel_reason': '已有异动' if picking.state not in ['draft', 'cancel', 'waiting'] else ''
}
lines.append(self.create(vals))
@@ -196,34 +236,34 @@ class SFSaleOrderCancelLine(models.TransientModel):
'operation_type': workorder.workcenter_id.name,
'product_name': mo.product_id.name,
'quantity': workorder.qty_production,
- 'doc_state': workorder.state,
- 'cancel_reason': '已有异动' if workorder.state not in ['draft', 'cancel', 'pending'] else ''
+ 'doc_state': map_dict.get(workorder.state, workorder.state),
+ 'cancel_reason': '已有异动' if workorder.state not in ['draft', 'cancel', 'pending', 'waiting'] else ''
}
lines.append(self.create(vals))
sequence += 1
# 检查制造订单组件的采购单和制造单
for move in mo.move_raw_ids:
- # 检查组件的采购单
- component_pos = self.env['purchase.order'].search([
- ('origin', '=', mo.name),
- ('order_line.product_id', '=', move.product_id.id)
- ])
- for po in component_pos:
- vals = {
- 'wizard_id': wizard_id,
- 'sequence': sequence,
- 'category': '制造',
- 'doc_name': '组件采购单',
- 'operation_type': '组件采购',
- 'doc_number': po.name,
- 'product_name': move.product_id.name,
- 'quantity': po.order_line[0].product_qty if po.order_line else 0,
- 'doc_state': po.state,
- 'cancel_reason': '已有异动' if po.state not in ['draft', 'cancel'] else ''
- }
- lines.append(self.create(vals))
- sequence += 1
+ # # 检查组件的采购单
+ # component_pos = self.env['purchase.order'].search([
+ # ('origin', '=', mo.name),
+ # ('order_line.product_id', '=', move.product_id.id)
+ # ])
+ # for po in component_pos:
+ # vals = {
+ # 'wizard_id': wizard_id,
+ # 'sequence': sequence,
+ # 'category': '制造',
+ # 'doc_name': '组件采购单',
+ # 'operation_type': '组件采购',
+ # 'doc_number': po.name,
+ # 'product_name': move.product_id.name,
+ # 'quantity': po.order_line[0].product_qty if po.order_line else 0,
+ # 'doc_state': po.state,
+ # 'cancel_reason': '已有异动' if po.state not in ['draft', 'cancel'] else ''
+ # }
+ # lines.append(self.create(vals))
+ # sequence += 1
# 检查组件的制造单
component_mos = self.env['mrp.production'].search([
@@ -240,7 +280,7 @@ class SFSaleOrderCancelLine(models.TransientModel):
'doc_number': comp_mo.name,
'product_name': move.product_id.name,
'quantity': comp_mo.product_qty,
- 'doc_state': comp_mo.state,
+ 'doc_state': map_dict.get(comp_mo.state, comp_mo.state),
'cancel_reason': '已有异动' if comp_mo.state not in ['technology_to_confirmed'] else ''
}
lines.append(self.create(vals))
@@ -257,12 +297,32 @@ class SFSaleOrderCancelLine(models.TransientModel):
'sequence': sequence,
'category': '制造',
'doc_name': '质检单',
+ 'operation_type': '质检',
'doc_number': check.name,
'product_name': check.product_id.name,
- 'doc_state': check.state,
- 'cancel_reason': '已有异动' if check.state not in ['draft', 'cancel'] else ''
+ 'quantity': 1,
+ 'doc_state': map_dict.get(check.quality_state, check.quality_state),
+ 'cancel_reason': '已有异动' if check.quality_state not in ['none'] else ''
}
lines.append(self.create(vals))
sequence += 1
+ # 检查制造订单的编程单
+ cloud_programming = mo._cron_get_programming_state()
+ if cloud_programming:
+ vals = {
+ 'wizard_id': wizard_id,
+ 'sequence': sequence,
+ 'category': '编程',
+ 'doc_name': '编程单',
+ 'operation_type': '编程',
+ 'doc_number': cloud_programming['programming_no'],
+ 'product_name': cloud_programming['production_order_no'],
+ 'quantity': 1,
+ 'doc_state': cloud_programming['programming_state'],
+ 'cancel_reason': ''
+ }
+ lines.append(self.create(vals))
+ sequence += 1
+
return lines
diff --git a/sf_quality/models/quality.py b/sf_quality/models/quality.py
index 201103f1..4b6c1774 100644
--- a/sf_quality/models/quality.py
+++ b/sf_quality/models/quality.py
@@ -14,7 +14,8 @@ class QualityCheck(models.Model):
('waiting', '等待'),
('none', '待处理'),
('pass', '通过的'),
- ('fail', '失败的')], string='状态', tracking=True, store=True,
+ ('fail', '失败的'),
+ ('cancel', '已取消'), ], string='状态', tracking=True, store=True,
default='none', copy=False, compute='_compute_quality_state')
individuation_page_PTD = fields.Boolean('个性化记录(是否显示后置三元检测[PTD]页签)', related='workorder_id.individuation_page_PTD')
@@ -110,4 +111,3 @@ class QualityCheck(models.Model):
return "零件特采发送成功"
else:
raise ValidationError("零件特采发送失败")
-