Accept Merge Request #2288: (feature/物料需求计划管理 -> develop)
Merge Request: 下达计划按钮重复点击生成重复数据 Created By: @管欢 Reviewed By: @胡尧 Approved By: @胡尧 Accepted By: @管欢 URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/2288
This commit is contained in:
@@ -30,6 +30,7 @@
|
|||||||
'web.assets_backend': [
|
'web.assets_backend': [
|
||||||
'sf_demand_plan/static/src/scss/style.css',
|
'sf_demand_plan/static/src/scss/style.css',
|
||||||
'sf_demand_plan/static/src/js/print_demand.js',
|
'sf_demand_plan/static/src/js/print_demand.js',
|
||||||
|
'sf_demand_plan/static/src/js/custom_button.js',
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
'license': 'LGPL-3',
|
'license': 'LGPL-3',
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class PurchaseOrderLine(models.Model):
|
|||||||
@api.model
|
@api.model
|
||||||
def create(self, vals):
|
def create(self, vals):
|
||||||
res = super(PurchaseOrderLine, self).create(vals)
|
res = super(PurchaseOrderLine, self).create(vals)
|
||||||
if not res.demand_plan_line_id:
|
if not res.demand_plan_line_id and res.order_id.origin:
|
||||||
origin = [origin.replace(' ', '') for origin in res.order_id.origin.split(',')]
|
origin = [origin.replace(' ', '') for origin in res.order_id.origin.split(',')]
|
||||||
if self.env.context.get('demand_plan_line_id'):
|
if self.env.context.get('demand_plan_line_id'):
|
||||||
res.demand_plan_line_id = self.env.context.get('demand_plan_line_id')
|
res.demand_plan_line_id = self.env.context.get('demand_plan_line_id')
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
_description = 'sf_production_demand_plan'
|
_description = 'sf_production_demand_plan'
|
||||||
|
|
||||||
def get_location_id(self):
|
def get_location_id(self):
|
||||||
stock_location = self.env['stock.location'].sudo().search([('name', '=', '客户')], limit=1)
|
customer_location_id = self.env['ir.model.data']._xmlid_to_res_id('stock.stock_location_customers')
|
||||||
return stock_location.id
|
return customer_location_id
|
||||||
|
|
||||||
priority = fields.Selection(related='demand_plan_id.priority', string='优先级')
|
priority = fields.Selection(related='demand_plan_id.priority', string='优先级', store=True)
|
||||||
status = fields.Selection([
|
status = fields.Selection([
|
||||||
('10', '草稿'),
|
('10', '草稿'),
|
||||||
('20', '待确认'),
|
('20', '待确认'),
|
||||||
@@ -34,7 +34,7 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
company_id = fields.Many2one(
|
company_id = fields.Many2one(
|
||||||
related='sale_order_id.company_id',
|
related='sale_order_id.company_id',
|
||||||
store=True, index=True, precompute=True)
|
store=True, index=True, precompute=True)
|
||||||
customer_name = fields.Char('客户', related='sale_order_id.customer_name')
|
customer_name = fields.Char('客户', related='sale_order_id.customer_name', store=True)
|
||||||
order_remark = fields.Text(related='sale_order_id.remark',
|
order_remark = fields.Text(related='sale_order_id.remark',
|
||||||
string="订单备注", store=True)
|
string="订单备注", store=True)
|
||||||
glb_url = fields.Char(related='sale_order_line_id.glb_url', string='glb文件地址')
|
glb_url = fields.Char(related='sale_order_line_id.glb_url', string='glb文件地址')
|
||||||
@@ -83,7 +83,7 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
related='product_id.blank_precision')
|
related='product_id.blank_precision')
|
||||||
unit_number = fields.Float('单件用量', digits=(16, 3), related='product_id.unit_number')
|
unit_number = fields.Float('单件用量', digits=(16, 3), related='product_id.unit_number')
|
||||||
embryo_long = fields.Char('坯料尺寸(mm)', related='demand_plan_id.embryo_long')
|
embryo_long = fields.Char('坯料尺寸(mm)', related='demand_plan_id.embryo_long')
|
||||||
materials_id = fields.Char('材料', related='demand_plan_id.materials_id')
|
materials_id = fields.Char('材料', related='demand_plan_id.materials_id', store=True)
|
||||||
model_machining_precision = fields.Selection(related='product_id.model_machining_precision', string='精度')
|
model_machining_precision = fields.Selection(related='product_id.model_machining_precision', string='精度')
|
||||||
model_process_parameters_ids = fields.Many2many(related='demand_plan_id.model_process_parameters_ids',
|
model_process_parameters_ids = fields.Many2many(related='demand_plan_id.model_process_parameters_ids',
|
||||||
string='表面工艺', )
|
string='表面工艺', )
|
||||||
@@ -127,6 +127,12 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
string='字段自制类型只读'
|
string='字段自制类型只读'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
is_processing = fields.Boolean(
|
||||||
|
string='正在处理中',
|
||||||
|
default=False,
|
||||||
|
help='用于防止重复点击按钮'
|
||||||
|
)
|
||||||
|
|
||||||
# hide_action_open_mrp_production = fields.Boolean(
|
# hide_action_open_mrp_production = fields.Boolean(
|
||||||
# string='显示待工艺确认按钮',
|
# string='显示待工艺确认按钮',
|
||||||
# compute='_compute_hid_button',
|
# compute='_compute_hid_button',
|
||||||
@@ -660,6 +666,9 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
|
|
||||||
def button_release_plan(self):
|
def button_release_plan(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
|
if self.is_processing:
|
||||||
|
return
|
||||||
|
self.is_processing = True
|
||||||
check_overdelivery_allowed = False
|
check_overdelivery_allowed = False
|
||||||
if not self.demand_plan_id.overdelivery_allowed:
|
if not self.demand_plan_id.overdelivery_allowed:
|
||||||
customer_location_id = self.env['ir.model.data']._xmlid_to_res_id('stock.stock_location_customers')
|
customer_location_id = self.env['ir.model.data']._xmlid_to_res_id('stock.stock_location_customers')
|
||||||
@@ -699,18 +708,6 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
self.update_sale_order_state()
|
self.update_sale_order_state()
|
||||||
|
|
||||||
def mrp_bom_create(self):
|
def mrp_bom_create(self):
|
||||||
if self.supply_method in ('automation', 'manual'):
|
|
||||||
line_ids = self.demand_plan_id.line_ids.filtered(
|
|
||||||
lambda p: p.supply_method in ('automation', 'manual') and p.status in ('50', '60'))
|
|
||||||
if line_ids:
|
|
||||||
self.bom_id = line_ids[0].bom_id.id
|
|
||||||
return
|
|
||||||
elif self.supply_method == 'outsourcing':
|
|
||||||
line_ids = self.demand_plan_id.line_ids.filtered(
|
|
||||||
lambda p: p.supply_method == 'outsourcing' and p.status == '60')
|
|
||||||
if line_ids:
|
|
||||||
self.bom_id = line_ids[0].bom_id.id
|
|
||||||
return
|
|
||||||
bom_type = ''
|
bom_type = ''
|
||||||
# 根据供货方式修改成品模板
|
# 根据供货方式修改成品模板
|
||||||
if self.supply_method == 'automation':
|
if self.supply_method == 'automation':
|
||||||
@@ -730,6 +727,18 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
|
|
||||||
# 复制成品模板上的属性
|
# 复制成品模板上的属性
|
||||||
self.product_id.product_tmpl_id.copy_template(product_template_id)
|
self.product_id.product_tmpl_id.copy_template(product_template_id)
|
||||||
|
if self.supply_method in ('automation', 'manual'):
|
||||||
|
line_ids = self.demand_plan_id.line_ids.filtered(
|
||||||
|
lambda p: p.supply_method in ('automation', 'manual') and p.status in ('50', '60'))
|
||||||
|
if line_ids:
|
||||||
|
self.bom_id = line_ids[0].bom_id.id
|
||||||
|
return
|
||||||
|
elif self.supply_method == 'outsourcing':
|
||||||
|
line_ids = self.demand_plan_id.line_ids.filtered(
|
||||||
|
lambda p: p.supply_method == 'outsourcing' and p.status == '60')
|
||||||
|
if line_ids:
|
||||||
|
self.bom_id = line_ids[0].bom_id.id
|
||||||
|
return
|
||||||
future_time = datetime.now() + timedelta(hours=8)
|
future_time = datetime.now() + timedelta(hours=8)
|
||||||
# 生成BOM单据编码
|
# 生成BOM单据编码
|
||||||
code = f"{self.product_id.default_code}-{bom_type}-{future_time.strftime('%Y%m%d%H%M%S')}"
|
code = f"{self.product_id.default_code}-{bom_type}-{future_time.strftime('%Y%m%d%H%M%S')}"
|
||||||
@@ -909,3 +918,6 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
'demand_plan_line_id': self.id
|
'demand_plan_line_id': self.id
|
||||||
}
|
}
|
||||||
return values
|
return values
|
||||||
|
|
||||||
|
def button_plan_detail(self):
|
||||||
|
pass
|
||||||
|
|||||||
59
sf_demand_plan/static/src/js/custom_button.js
Normal file
59
sf_demand_plan/static/src/js/custom_button.js
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/** @odoo-module **/
|
||||||
|
|
||||||
|
import { registry } from "@web/core/registry";
|
||||||
|
import { ListRenderer } from "@web/views/list/list_renderer";
|
||||||
|
import { useService } from "@web/core/utils/hooks";
|
||||||
|
import { useEffect } from "@odoo/owl";
|
||||||
|
|
||||||
|
export class CustomDemandPlanListRenderer extends ListRenderer {
|
||||||
|
setup() {
|
||||||
|
super.setup();
|
||||||
|
this.orm = useService("orm");
|
||||||
|
this.notification = useService("notification");
|
||||||
|
console.log('setup', this.props);
|
||||||
|
|
||||||
|
// 监听selection属性的变化
|
||||||
|
useEffect(() => {
|
||||||
|
this.updateButtonState();
|
||||||
|
}, () => [this.props.list.selection]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新按钮状态
|
||||||
|
*/
|
||||||
|
async updateButtonState() {
|
||||||
|
const selectedRecords = this.props.list.selection;
|
||||||
|
const isStatus30 = selectedRecords.some(record => record.data.status != "30");
|
||||||
|
const button = $(this.__owl__.parent.bdom.parentEl).find('button[name="button_batch_release_plan"]');
|
||||||
|
console.log('isStatus30', isStatus30, button);
|
||||||
|
if (isStatus30) {
|
||||||
|
// 禁用按钮
|
||||||
|
button.attr('disabled', true);
|
||||||
|
} else {
|
||||||
|
button.attr('disabled', false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 使用setTimeout延迟注册,避免在模块加载时立即执行
|
||||||
|
setTimeout(() => {
|
||||||
|
const registerCustomRenderer = () => {
|
||||||
|
try {
|
||||||
|
const listView = registry.category("views").get("list");
|
||||||
|
if (listView) {
|
||||||
|
registry.category("views").add("custom_demand_plan_list", {
|
||||||
|
...listView,
|
||||||
|
Renderer: CustomDemandPlanListRenderer,
|
||||||
|
});
|
||||||
|
console.log("Custom demand plan list renderer registered successfully");
|
||||||
|
} else {
|
||||||
|
console.warn("List view not found, retrying...");
|
||||||
|
// 如果还没找到,再等一段时间
|
||||||
|
setTimeout(registerCustomRenderer, 1000);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error registering custom renderer:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
registerCustomRenderer();
|
||||||
|
}, 1000);
|
||||||
@@ -4,7 +4,8 @@
|
|||||||
<field name="model">sf.production.demand.plan</field>
|
<field name="model">sf.production.demand.plan</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree string="需求计划" default_order="sequence desc,id desc" editable="bottom"
|
<tree string="需求计划" default_order="sequence desc,id desc" editable="bottom"
|
||||||
class="demand_plan_tree freeze-columns-before-part_number" create="false" delete="false">
|
class="demand_plan_tree freeze-columns-before-part_number" create="false" delete="false"
|
||||||
|
js_class="custom_demand_plan_list">
|
||||||
<header>
|
<header>
|
||||||
<button string="打印" name="button_action_print" type="object"
|
<button string="打印" name="button_action_print" type="object"
|
||||||
class="btn-primary"/>
|
class="btn-primary"/>
|
||||||
|
|||||||
@@ -108,6 +108,9 @@
|
|||||||
class="btn-primary"
|
class="btn-primary"
|
||||||
attrs="{'invisible': [('hide_release_production_order', '=', False)]}"
|
attrs="{'invisible': [('hide_release_production_order', '=', False)]}"
|
||||||
/>
|
/>
|
||||||
|
<button string="详情" name="button_plan_detail" type="object"
|
||||||
|
class="btn-primary"
|
||||||
|
/>
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
</page>
|
</page>
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class SfDemandPlanPrintWizard(models.TransientModel):
|
|||||||
if pdf_data:
|
if pdf_data:
|
||||||
try:
|
try:
|
||||||
# 执行打印
|
# 执行打印
|
||||||
self.env['jikimo.printing'].sudo().print_pdf(pdf_data)
|
# self.env['jikimo.printing'].sudo().print_pdf(pdf_data)
|
||||||
record.status = 'success'
|
record.status = 'success'
|
||||||
production_demand_plan_id = self.env['sf.production.demand.plan'].sudo().search(
|
production_demand_plan_id = self.env['sf.production.demand.plan'].sudo().search(
|
||||||
[('model_id', '=', record.model_id)])
|
[('model_id', '=', record.model_id)])
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import logging
|
import logging
|
||||||
from odoo import models, fields, api, _
|
from odoo import models, fields, api, _
|
||||||
|
from werkzeug.exceptions import InternalServerError
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -17,4 +18,10 @@ class SfReleasePlanWizard(models.TransientModel):
|
|||||||
def confirm(self):
|
def confirm(self):
|
||||||
if self.demand_plan_line_id:
|
if self.demand_plan_line_id:
|
||||||
for demand_plan_line_id in self.demand_plan_line_id:
|
for demand_plan_line_id in self.demand_plan_line_id:
|
||||||
demand_plan_line_id.action_confirm()
|
try:
|
||||||
|
demand_plan_line_id.action_confirm()
|
||||||
|
except Exception as e:
|
||||||
|
self.env.cr.rollback()
|
||||||
|
demand_plan_line_id.write({'is_processing': False})
|
||||||
|
self.env.cr.commit()
|
||||||
|
raise InternalServerError('操作失败', e)
|
||||||
|
|||||||
Reference in New Issue
Block a user