取消接单需求进行中
This commit is contained in:
@@ -27,6 +27,7 @@
|
|||||||
'wizard/production_technology_re_adjust_wizard_views.xml',
|
'wizard/production_technology_re_adjust_wizard_views.xml',
|
||||||
'wizard/mrp_workorder_batch_replan_wizard_views.xml',
|
'wizard/mrp_workorder_batch_replan_wizard_views.xml',
|
||||||
'wizard/sf_programming_reason_views.xml',
|
'wizard/sf_programming_reason_views.xml',
|
||||||
|
'wizard/sale_order_cancel_views.xml',
|
||||||
'views/mrp_views_menus.xml',
|
'views/mrp_views_menus.xml',
|
||||||
'views/agv_scheduling_views.xml',
|
'views/agv_scheduling_views.xml',
|
||||||
'views/stock_lot_views.xml',
|
'views/stock_lot_views.xml',
|
||||||
|
|||||||
@@ -150,6 +150,23 @@ class SaleOrder(models.Model):
|
|||||||
purchase_embryo)
|
purchase_embryo)
|
||||||
return super(SaleOrder, self).action_confirm()
|
return super(SaleOrder, self).action_confirm()
|
||||||
|
|
||||||
|
def action_show_cancel_wizard(self):
|
||||||
|
wizard = self.env['sf.sale.order.cancel.wizard'].create({
|
||||||
|
'order_id': self.id,
|
||||||
|
})
|
||||||
|
|
||||||
|
# 创建关联单据行
|
||||||
|
self.env['sf.sale.order.cancel.line'].create_from_order(wizard.id, self)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'name': '取消销售订单',
|
||||||
|
'type': 'ir.actions.act_window',
|
||||||
|
'res_model': 'sf.sale.order.cancel.wizard',
|
||||||
|
'view_mode': 'form',
|
||||||
|
'target': 'new',
|
||||||
|
'res_id': wizard.id,
|
||||||
|
}
|
||||||
|
|
||||||
class SaleOrderLine(models.Model):
|
class SaleOrderLine(models.Model):
|
||||||
_inherit = 'sale.order.line'
|
_inherit = 'sale.order.line'
|
||||||
part_number = fields.Char('零件图号', related='product_id.part_number', readonly=True)
|
part_number = fields.Char('零件图号', related='product_id.part_number', readonly=True)
|
||||||
|
|||||||
@@ -192,3 +192,5 @@ access_sf_programming_reason,sf_programming_reason,model_sf_programming_reason,b
|
|||||||
access_sf_programming_record,sf_programming_record,model_sf_programming_record,base.group_user,1,1,1,0
|
access_sf_programming_record,sf_programming_record,model_sf_programming_record,base.group_user,1,1,1,0
|
||||||
access_sf_work_individuation_page,sf_work_individuation_page,model_sf_work_individuation_page,sf_base.group_sf_mrp_user,1,1,1,0
|
access_sf_work_individuation_page,sf_work_individuation_page,model_sf_work_individuation_page,sf_base.group_sf_mrp_user,1,1,1,0
|
||||||
access_sf_work_individuation_page_group_plan_dispatch,sf_work_individuation_page_group_plan_dispatch,model_sf_work_individuation_page,sf_base.group_plan_dispatch,1,1,0,0
|
access_sf_work_individuation_page_group_plan_dispatch,sf_work_individuation_page_group_plan_dispatch,model_sf_work_individuation_page,sf_base.group_plan_dispatch,1,1,0,0
|
||||||
|
access_sf_sale_order_cancel_wizard,sf_sale_order_cancel_wizard,model_sf_sale_order_cancel_wizard,sf_base.group_sf_order_user,1,1,1,0
|
||||||
|
access_sf_sale_order_cancel_line,sf_sale_order_cancel_line,model_sf_sale_order_cancel_line,sf_base.group_sf_order_user,1,1,1,0
|
||||||
|
@@ -27,10 +27,20 @@
|
|||||||
<!-- </xpath> -->
|
<!-- </xpath> -->
|
||||||
<xpath expr="//header/button[@name='action_cancel']" position="attributes">
|
<xpath expr="//header/button[@name='action_cancel']" position="attributes">
|
||||||
<attribute name="attrs">{'invisible': [('state', 'not in', ['draft', 'supply method', 'sale', 'processing'])]}</attribute>
|
<attribute name="attrs">{'invisible': [('state', 'not in', ['draft', 'supply method', 'sale', 'processing'])]}</attribute>
|
||||||
|
<attribute name="confirm">警告:取消操作将不可逆,是否确定要取消该单据?</attribute>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//header/button[@name='action_quotation_send'][5]" position="attributes">
|
<xpath expr="//header/button[@name='action_quotation_send'][5]" position="attributes">
|
||||||
<attribute name="attrs">{'invisible': ['|','&',('check_status', '!=', 'approved'),('state', 'in', ['draft','cancel','supply method']),'&',('check_status', '=', 'approved'),('state', 'in', ['sale','cancel','supply method'])]}</attribute>
|
<attribute name="attrs">{'invisible': ['|','&',('check_status', '!=', 'approved'),('state', 'in', ['draft','cancel','supply method']),'&',('check_status', '=', 'approved'),('state', 'in', ['sale','cancel','supply method'])]}</attribute>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
|
||||||
|
<xpath expr="//header/button[@name='action_cancel']" position="after">
|
||||||
|
<button
|
||||||
|
name="action_show_cancel_wizard"
|
||||||
|
string="取消(关联单据)"
|
||||||
|
type="object"
|
||||||
|
attrs="{'invisible': [('state', 'not in', ['draft', 'supply method', 'sale', 'processing'])]}"
|
||||||
|
/>
|
||||||
|
</xpath>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|||||||
@@ -5,3 +5,4 @@ from . import production_technology_wizard
|
|||||||
from . import production_technology_re_adjust_wizard
|
from . import production_technology_re_adjust_wizard
|
||||||
from . import mrp_workorder_batch_replan_wizard
|
from . import mrp_workorder_batch_replan_wizard
|
||||||
from . import sf_programming_reason
|
from . import sf_programming_reason
|
||||||
|
from . import sale_order_cancel
|
||||||
|
|||||||
103
sf_manufacturing/wizard/sale_order_cancel.py
Normal file
103
sf_manufacturing/wizard/sale_order_cancel.py
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
from odoo import models, fields, api
|
||||||
|
|
||||||
|
class SFSaleOrderCancelWizard(models.TransientModel):
|
||||||
|
_name = 'sf.sale.order.cancel.wizard'
|
||||||
|
_description = '销售订单取消向导'
|
||||||
|
|
||||||
|
order_id = fields.Many2one('sale.order', string='销售订单')
|
||||||
|
related_docs = fields.One2many('sf.sale.order.cancel.line', 'wizard_id', string='相关单据')
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def default_get(self, fields_list):
|
||||||
|
defaults = super().default_get(fields_list)
|
||||||
|
if self._context.get('active_id'):
|
||||||
|
order = self.env['sale.order'].browse(self._context.get('active_id'))
|
||||||
|
defaults['order_id'] = order.id
|
||||||
|
# 创建向导时自动创建关联单据行
|
||||||
|
wizard = self.create(defaults)
|
||||||
|
self.env['sf.sale.order.cancel.line'].create_from_order(wizard.id, order)
|
||||||
|
defaults['related_docs'] = wizard.related_docs.ids
|
||||||
|
return defaults
|
||||||
|
|
||||||
|
def action_confirm_cancel(self):
|
||||||
|
self.ensure_one()
|
||||||
|
return self.order_id.action_cancel()
|
||||||
|
|
||||||
|
class SFSaleOrderCancelLine(models.TransientModel):
|
||||||
|
_name = 'sf.sale.order.cancel.line'
|
||||||
|
_description = '销售订单取消行'
|
||||||
|
|
||||||
|
wizard_id = fields.Many2one('sf.sale.order.cancel.wizard')
|
||||||
|
sequence = fields.Integer('序号')
|
||||||
|
category = fields.Char('大类')
|
||||||
|
doc_name = fields.Char('单据名称')
|
||||||
|
operation_type = fields.Char('作业类型')
|
||||||
|
doc_number = fields.Char('单据编号')
|
||||||
|
line_number = fields.Char('行号')
|
||||||
|
product_name = fields.Char('产品名称')
|
||||||
|
quantity = fields.Float('数量')
|
||||||
|
doc_state = fields.Char('单据状态')
|
||||||
|
cancel_reason = fields.Char('禁止取消原因')
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def create_from_order(self, wizard_id, order):
|
||||||
|
sequence = 1
|
||||||
|
lines = []
|
||||||
|
|
||||||
|
# 检查销售订单
|
||||||
|
if order.invoice_ids:
|
||||||
|
for invoice in order.invoice_ids:
|
||||||
|
vals = {
|
||||||
|
'wizard_id': wizard_id,
|
||||||
|
'sequence': sequence,
|
||||||
|
'category': '销售',
|
||||||
|
'doc_name': '销售订单',
|
||||||
|
'operation_type': '销售',
|
||||||
|
'doc_number': invoice.name,
|
||||||
|
'product_name': invoice.product_id.name,
|
||||||
|
'quantity': invoice.quantity,
|
||||||
|
'doc_state': invoice.state,
|
||||||
|
'cancel_reason': '已有异动' if invoice.state != 'draft' else ''
|
||||||
|
}
|
||||||
|
lines.append(self.create(vals))
|
||||||
|
sequence += 1
|
||||||
|
|
||||||
|
# 检查交货单
|
||||||
|
if order.picking_ids:
|
||||||
|
for picking in order.picking_ids:
|
||||||
|
vals = {
|
||||||
|
'wizard_id': wizard_id,
|
||||||
|
'sequence': sequence,
|
||||||
|
'category': '库存',
|
||||||
|
'doc_name': '交货单',
|
||||||
|
'operation_type': '调拨',
|
||||||
|
'doc_number': picking.name,
|
||||||
|
'product_name': picking.product_id.name if picking.product_id else '',
|
||||||
|
'quantity': picking.product_qty if hasattr(picking, 'product_qty') else 0,
|
||||||
|
'doc_state': picking.state,
|
||||||
|
'cancel_reason': '已有异动' if picking.state not in ['draft', 'cancel', 'waiting'] else ''
|
||||||
|
}
|
||||||
|
lines.append(self.create(vals))
|
||||||
|
sequence += 1
|
||||||
|
|
||||||
|
# 检查制造订单
|
||||||
|
manufacturing_orders = self.env['mrp.production'].search([
|
||||||
|
('origin', '=', order.name)
|
||||||
|
])
|
||||||
|
for mo in manufacturing_orders:
|
||||||
|
vals = {
|
||||||
|
'wizard_id': wizard_id,
|
||||||
|
'sequence': sequence,
|
||||||
|
'category': '制造',
|
||||||
|
'doc_name': '制造订单',
|
||||||
|
'operation_type': '制造',
|
||||||
|
'doc_number': mo.name,
|
||||||
|
'product_name': mo.product_id.name,
|
||||||
|
'quantity': mo.product_qty,
|
||||||
|
'doc_state': mo.state,
|
||||||
|
'cancel_reason': '已有异动' if mo.state not in ['draft', 'cancel'] else ''
|
||||||
|
}
|
||||||
|
lines.append(self.create(vals))
|
||||||
|
sequence += 1
|
||||||
|
|
||||||
|
return lines
|
||||||
42
sf_manufacturing/wizard/sale_order_cancel_views.xml
Normal file
42
sf_manufacturing/wizard/sale_order_cancel_views.xml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<record id="view_sf_sale_order_cancel_wizard" model="ir.ui.view">
|
||||||
|
<field name="name">sf.sale.order.cancel.wizard.form</field>
|
||||||
|
<field name="model">sf.sale.order.cancel.wizard</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="下游单据清单">
|
||||||
|
<group>
|
||||||
|
<field name="order_id" invisible="1"/>
|
||||||
|
</group>
|
||||||
|
<div class="alert alert-warning" role="alert">
|
||||||
|
<span>弹窗描述:</span><br/>
|
||||||
|
<span>1) 若无异动,描述为: 确认所有下游单据全部取消?</span><br/>
|
||||||
|
<span>2) 若有异动,描述为: 部分或全部下游单据存在异动,无法取消,详情如下:</span>
|
||||||
|
</div>
|
||||||
|
<field name="related_docs">
|
||||||
|
<tree string="下游单据" create="false" edit="false" delete="false">
|
||||||
|
<field name="sequence" string="序号"/>
|
||||||
|
<field name="category" string="大类"/>
|
||||||
|
<field name="doc_name" string="单据名称"/>
|
||||||
|
<field name="operation_type" string="作业类型"/>
|
||||||
|
<field name="doc_number" string="单据编号"/>
|
||||||
|
<field name="line_number" string="行号"/>
|
||||||
|
<field name="product_name" string="产品名称"/>
|
||||||
|
<field name="quantity" string="数量"/>
|
||||||
|
<field name="doc_state" string="单据状态"/>
|
||||||
|
<field name="cancel_reason" string="禁止取消原因"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
<footer>
|
||||||
|
<button name="action_confirm_cancel"
|
||||||
|
string="确认取消"
|
||||||
|
type="object"
|
||||||
|
class="btn-primary"/>
|
||||||
|
<button string="关闭"
|
||||||
|
class="btn-secondary"
|
||||||
|
special="cancel"/>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
Reference in New Issue
Block a user