库存移动新增需求计划关联
This commit is contained in:
@@ -10,7 +10,7 @@
|
|||||||
""",
|
""",
|
||||||
'category': 'sf',
|
'category': 'sf',
|
||||||
'website': 'https://www.sf.jikimo.com',
|
'website': 'https://www.sf.jikimo.com',
|
||||||
'depends': ['sf_plan', 'jikimo_printing'],
|
'depends': ['sf_plan', 'jikimo_printing', 'purchase_request', 'purchase_request_tier_validation'],
|
||||||
'data': [
|
'data': [
|
||||||
'security/ir.model.access.csv',
|
'security/ir.model.access.csv',
|
||||||
'data/stock_route_group.xml',
|
'data/stock_route_group.xml',
|
||||||
@@ -32,7 +32,6 @@
|
|||||||
'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',
|
'sf_demand_plan/static/src/js/custom_button.js',
|
||||||
'sf_demand_plan/static/src/js/custom_made_type_listener.js',
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
'license': 'LGPL-3',
|
'license': 'LGPL-3',
|
||||||
|
|||||||
@@ -9,3 +9,4 @@ from . import mrp_production
|
|||||||
from . import stock_rule
|
from . import stock_rule
|
||||||
from . import purchase_request
|
from . import purchase_request
|
||||||
from . import purchase_order
|
from . import purchase_order
|
||||||
|
from . import stock_move
|
||||||
|
|||||||
@@ -922,6 +922,11 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
], limit=1))
|
], limit=1))
|
||||||
|
|
||||||
def button_plan_detail(self):
|
def button_plan_detail(self):
|
||||||
|
self.ensure_one()
|
||||||
|
purchase_request_ids = self.env['purchase.request'].sudo().search(
|
||||||
|
[('line_ids.demand_plan_line_id', 'in', self.ids)])
|
||||||
|
purchase_order_ids = self.env['purchase.order'].sudo().search(
|
||||||
|
[('order_line.demand_plan_line_id', 'in', self.ids)])
|
||||||
return {
|
return {
|
||||||
'name': _('详情'),
|
'name': _('详情'),
|
||||||
'type': 'ir.actions.act_window',
|
'type': 'ir.actions.act_window',
|
||||||
@@ -930,6 +935,18 @@ class SfProductionDemandPlan(models.Model):
|
|||||||
'target': 'new',
|
'target': 'new',
|
||||||
'views': [(False, 'form')],
|
'views': [(False, 'form')],
|
||||||
'context': {
|
'context': {
|
||||||
'default_demand_plan_line_ids': self.ids,
|
|
||||||
'default_mrp_production_ids': self.mrp_production_ids.ids,
|
'default_mrp_production_ids': self.mrp_production_ids.ids,
|
||||||
|
'default_purchase_request_ids': purchase_request_ids.ids,
|
||||||
|
'default_standard_purchase_order_ids': purchase_order_ids.filtered(
|
||||||
|
lambda o: o.purchase_type == 'standard'
|
||||||
|
).ids,
|
||||||
|
'default_consignment_purchase_order_ids': purchase_order_ids.filtered(
|
||||||
|
lambda o: o.purchase_type == 'consignment'
|
||||||
|
).ids,
|
||||||
|
'default_outsourcing_purchase_order_ids': purchase_order_ids.filtered(
|
||||||
|
lambda o: o.purchase_type == 'outsourcing'
|
||||||
|
).ids,
|
||||||
|
'default_outside_purchase_order_ids': purchase_order_ids.filtered(
|
||||||
|
lambda o: o.purchase_type == 'outside'
|
||||||
|
).ids,
|
||||||
}}
|
}}
|
||||||
|
|||||||
37
sf_demand_plan/models/stock_move.py
Normal file
37
sf_demand_plan/models/stock_move.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from odoo import api, fields, models
|
||||||
|
|
||||||
|
|
||||||
|
class StockMove(models.Model):
|
||||||
|
_inherit = 'stock.move'
|
||||||
|
|
||||||
|
demand_plan_line_ids = fields.Many2many(comodel_name="sf.production.demand.plan",
|
||||||
|
string="需求计划明细", compute='_compute_demand_plan_line_ids', store=True)
|
||||||
|
|
||||||
|
@api.depends('origin', 'move_orig_ids')
|
||||||
|
def _compute_demand_plan_line_ids(self):
|
||||||
|
sorted_records = self.sorted(key=lambda r: -r.id)
|
||||||
|
for line in sorted_records:
|
||||||
|
origin = [origin.replace(' ', '') for origin in line.origin.split(',')]
|
||||||
|
if line.created_purchase_request_line_id:
|
||||||
|
line.demand_plan_line_ids = line.created_purchase_request_line_id.demand_plan_line_id.ids
|
||||||
|
elif line.origin and 'MO' in line.origin:
|
||||||
|
mp_ids = self.env['mrp.production'].sudo().search([('name', '=', origin[0])])
|
||||||
|
line.demand_plan_line_ids = mp_ids.demand_plan_line_id.ids if mp_ids else []
|
||||||
|
elif line.origin and 'P' in line.origin:
|
||||||
|
purchase_order_ids = self.env['purchase.order'].sudo().search([('name', '=', origin[0])])
|
||||||
|
if purchase_order_ids.order_line:
|
||||||
|
line.demand_plan_line_ids = purchase_order_ids.order_line.demand_plan_line_id.ids
|
||||||
|
elif line.move_orig_ids:
|
||||||
|
demand_plan_lines = self.env['sf.production.demand.plan']
|
||||||
|
for move_orig in line.move_orig_ids:
|
||||||
|
demand_plan_lines |= move_orig.demand_plan_line_ids
|
||||||
|
line.demand_plan_line_ids = demand_plan_lines.ids
|
||||||
|
else:
|
||||||
|
line.demand_plan_line_ids = []
|
||||||
|
|
||||||
|
if not line.demand_plan_line_ids and self.env.context.get('demand_plan_line_id'):
|
||||||
|
plan_ids = self.env.context['demand_plan_line_id']
|
||||||
|
line.demand_plan_line_ids = [plan_ids]
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
/** @odoo-module */
|
|
||||||
import {patch} from '@web/core/utils/patch';
|
|
||||||
import {ListRenderer} from "@web/views/list/list_renderer";
|
|
||||||
import { useService } from "@web/core/utils/hooks";
|
|
||||||
import { ConfirmationDialog } from "@web/core/confirmation_dialog/confirmation_dialog";
|
|
||||||
|
|
||||||
patch(ListRenderer.prototype, 'jikimo_sf_demand_plan.ListRenderer', {
|
|
||||||
setup() {
|
|
||||||
// 获取各种服务
|
|
||||||
this.dialog = useService("dialog");
|
|
||||||
this.notification = useService("notification");
|
|
||||||
this.orm = useService("orm");
|
|
||||||
|
|
||||||
owl.onMounted(() => {
|
|
||||||
this.listenSelect();
|
|
||||||
});
|
|
||||||
return this._super(...arguments);
|
|
||||||
},
|
|
||||||
|
|
||||||
listenSelect() {
|
|
||||||
// console.log('listenSelect 被调用');
|
|
||||||
const dom = $(this.__owl__.bdom.el);
|
|
||||||
const _this = this;
|
|
||||||
if(dom.hasClass('custom_made_type_listener_select2')) {
|
|
||||||
this.listenSelect2();
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if(!dom.hasClass('custom_made_type_listener_select')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 检查是否包含custom_made_type字段
|
|
||||||
const hasCustomMadeTypeField = dom.find('[name="custom_made_type"]').length > 0;
|
|
||||||
|
|
||||||
if (hasCustomMadeTypeField) {
|
|
||||||
// console.log('找到custom_made_type字段,设置监听器');
|
|
||||||
|
|
||||||
dom.on('change', '[name="custom_made_type"] select', function (event) {
|
|
||||||
// console.log('检测到custom_made_type变化');
|
|
||||||
|
|
||||||
const record = _this.props.list.records;
|
|
||||||
const limitData = record.find(item =>
|
|
||||||
item.data.status == '30' &&
|
|
||||||
item.data.new_supply_method == 'custom_made'
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!limitData) {
|
|
||||||
// console.log('未找到符合条件的记录');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let limitVal = limitData.data.custom_made_type;
|
|
||||||
if (!limitVal) {
|
|
||||||
// console.log('limitVal为空');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const v = $(this).val();
|
|
||||||
limitVal = '"' + limitVal + '"';
|
|
||||||
// console.log('当前值:', v, '限制值:', limitVal);
|
|
||||||
|
|
||||||
if (v != limitVal) {
|
|
||||||
// console.log('值不匹配,显示确认对话框');
|
|
||||||
|
|
||||||
// 方法1:使用Odoo的确认对话框服务(推荐)
|
|
||||||
_this.showConfirmationDialog2(event.target, limitVal);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.log('未找到custom_made_type字段');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
listenSelect2() {
|
|
||||||
// console.log('listenSelect2 被调用',this);
|
|
||||||
const dom = $(this.__owl__.bdom.el);
|
|
||||||
const _this = this;
|
|
||||||
dom.on('change', '[name="custom_made_type"] select', function (event) {
|
|
||||||
// console.log('检测到custom_made_type变化', event);
|
|
||||||
const record = _this.props.list.records;
|
|
||||||
const index = $(this).parents('tr').index();
|
|
||||||
const data = record[index].data;
|
|
||||||
const data_id = data.id;
|
|
||||||
const product_id = data.product_id[0]
|
|
||||||
const v = $(this).val();
|
|
||||||
const limitVal = $(this).find('option:selected').siblings(':not([value=false])').attr('value');
|
|
||||||
// 请求接口
|
|
||||||
_this.orm.call('sf.production.demand.plan', 'check_other_custom_made_demands', [data_id, product_id, v]).then(res => {
|
|
||||||
if(res) {
|
|
||||||
_this.showConfirmationDialog2(event.target, limitVal);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 方法2:使用ConfirmationDialog组件
|
|
||||||
*/
|
|
||||||
async showConfirmationDialog2(target, correctValue) {
|
|
||||||
const confirmed = await this.dialog.add(ConfirmationDialog, {
|
|
||||||
title: "确认",
|
|
||||||
body: "请选择正确的类型",
|
|
||||||
confirm: () => {
|
|
||||||
console.log('用户确认');
|
|
||||||
$(target).val(correctValue);
|
|
||||||
},
|
|
||||||
cancel: () => {
|
|
||||||
console.log('用户取消');
|
|
||||||
$(target).val(correctValue);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
<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 custom_made_type_listener_select2" create="false" delete="false"
|
class="demand_plan_tree freeze-columns-before-part_number" create="false" delete="false"
|
||||||
js_class="custom_demand_plan_list">
|
js_class="custom_demand_plan_list">
|
||||||
<header>
|
<header>
|
||||||
<button string="打印" name="button_action_print" type="object"
|
<button string="打印" name="button_action_print" type="object"
|
||||||
|
|||||||
@@ -78,7 +78,7 @@
|
|||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
<field name="line_ids" attrs="{'invisible': [('state', 'not in', ('40','50'))]}">
|
<field name="line_ids" attrs="{'invisible': [('state', 'not in', ('40','50'))]}">
|
||||||
<tree editable="bottom" class="custom_made_type_listener_select">
|
<tree editable="bottom">
|
||||||
<field name="status"/>
|
<field name="status"/>
|
||||||
<field name="readonly_custom_made_type" invisible="1"/>
|
<field name="readonly_custom_made_type" invisible="1"/>
|
||||||
<field name="new_supply_method" attrs="{'readonly': [('status', '!=', '30')]}"/>
|
<field name="new_supply_method" attrs="{'readonly': [('status', '!=', '30')]}"/>
|
||||||
@@ -110,6 +110,7 @@
|
|||||||
/>
|
/>
|
||||||
<button string="详情" name="button_plan_detail" type="object"
|
<button string="详情" name="button_plan_detail" type="object"
|
||||||
class="btn-primary"
|
class="btn-primary"
|
||||||
|
attrs="{'invisible': [('status', 'not in', ('50','60'))]}"
|
||||||
/>
|
/>
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
|
|||||||
@@ -9,7 +9,21 @@ class SfDemandPlanDetailWizard(models.TransientModel):
|
|||||||
_name = 'sf.demand.plan.detail.wizard'
|
_name = 'sf.demand.plan.detail.wizard'
|
||||||
_description = u'需求计划详情向导'
|
_description = u'需求计划详情向导'
|
||||||
|
|
||||||
demand_plan_line_ids = fields.Many2many(comodel_name="sf.production.demand.plan",
|
|
||||||
string="需求计划明细", readonly=True)
|
|
||||||
|
|
||||||
mrp_production_ids = fields.Many2many('mrp.production', string='关联制造订单', readonly=True)
|
mrp_production_ids = fields.Many2many('mrp.production', string='关联制造订单', readonly=True)
|
||||||
|
purchase_request_ids = fields.Many2many('purchase.request', string='关联采购申请', readonly=True)
|
||||||
|
standard_purchase_order_ids = fields.Many2many('purchase.order', string='关联标准采购',
|
||||||
|
relation='standard_purchase_order_rel',
|
||||||
|
column1='plan_detail_wizard_id', column2='purchase_order_id',
|
||||||
|
readonly=True)
|
||||||
|
consignment_purchase_order_ids = fields.Many2many('purchase.order', string='关联工序外协采购',
|
||||||
|
relation='consignment_purchase_order_rel',
|
||||||
|
column1='plan_detail_wizard_id', column2='purchase_order_id',
|
||||||
|
readonly=True)
|
||||||
|
outsourcing_purchase_order_ids = fields.Many2many('purchase.order', string='关联委外加工采购',
|
||||||
|
relation='outsourcing_purchase_order_rel',
|
||||||
|
column1='plan_detail_wizard_id', column2='purchase_order_id',
|
||||||
|
readonly=True)
|
||||||
|
outside_purchase_order_ids = fields.Many2many('purchase.order', string='关联外购订单采购',
|
||||||
|
relation='outside_purchase_order_rel',
|
||||||
|
column1='plan_detail_wizard_id', column2='purchase_order_id',
|
||||||
|
readonly=True)
|
||||||
|
|||||||
@@ -6,13 +6,23 @@
|
|||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<form string="详情">
|
<form string="详情">
|
||||||
<notebook>
|
<notebook>
|
||||||
<page string="制造订单">
|
<page string="采购申请" attrs="{'invisible': [('purchase_request_ids', '=', [])]}">
|
||||||
<field name="mrp_production_ids"
|
<field name="purchase_request_ids" widget="many2many"/>
|
||||||
widget="many2many"
|
</page>
|
||||||
options="{
|
<page string="制造订单" attrs="{'invisible': [('mrp_production_ids', '=', [])]}">
|
||||||
'views': [[false, 'tree'], [false, 'form']],
|
<field name="mrp_production_ids" widget="many2many"/>
|
||||||
'context': {'tree_view_ref': 'mrp.mrp_production_tree_view'}
|
</page>
|
||||||
}"/>
|
<page string="标准采购" attrs="{'invisible': [('standard_purchase_order_ids', '=', [])]}">
|
||||||
|
<field name="standard_purchase_order_ids" widget="many2many"/>
|
||||||
|
</page>
|
||||||
|
<page string="工序外协采购" attrs="{'invisible': [('consignment_purchase_order_ids', '=', [])]}">
|
||||||
|
<field name="consignment_purchase_order_ids" widget="many2many"/>
|
||||||
|
</page>
|
||||||
|
<page string="委外加工采购" attrs="{'invisible': [('outsourcing_purchase_order_ids', '=', [])]}">
|
||||||
|
<field name="outsourcing_purchase_order_ids" widget="many2many"/>
|
||||||
|
</page>
|
||||||
|
<page string="外购订单采购" attrs="{'invisible': [('outside_purchase_order_ids', '=', [])]}">
|
||||||
|
<field name="outside_purchase_order_ids" widget="many2many"/>
|
||||||
</page>
|
</page>
|
||||||
</notebook>
|
</notebook>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
Reference in New Issue
Block a user