ใน Odoo9 ฉันต้องการโดเมนไดนามิกที่ขึ้นอยู่กับฟิลด์ many2one
ในตัวช่วยสร้าง ฉันทำให้มันใช้งานได้โดยใช้ตัวอย่างต่างๆ แต่ค่าที่กรองจะใช้ได้กับตัวเลือกก่อนหน้าเสมอ หรือจะใช้ได้หากฉันเลือกตัวเลือก (ไม่ถูกต้อง) จากโดเมนที่กรอง
รายละเอียด:
ในตอนท้ายของขั้นตอนการทำงานของโอกาส พนักงานขายควรประเมินโอกาสโดยเลือกความน่าจะเป็นที่จะประสบความสำเร็จ มีหลายระดับให้เลือกในตัวช่วยพิเศษ ("แน่ใจ 100%" "ไม่แน่ใจ" "อาจจะ" ฯลฯ) ฉันใช้ fields.Selection
สำหรับสิ่งนี้ จากนั้น ฉันได้เปิดตัวโอกาสประเภทใหม่ (การรักษาลูกค้า) ซึ่งควรมีเพียง 100% และ 0% เท่านั้น ดังนั้นฉันจึงสร้างโมเดลใหม่ evaluation_option
แทนที่ fields.Selection
ด้วย fields.Many2one
และจากค่าเหล่านี้ ฉันกรองตัวเลือกที่อนุญาตออก (ด้วย retention=True
)
นี่คือโมเดลตัวช่วยสร้างของฉัน:
class evaluation_wizard(models.TransientModel):
_name = 'evaluation.wizard'
_description = 'Wizard to evaluate opportunity'
lead_id = fields.Many2one('crm.lead')
evaluation_option_id = fields.Many2one('evaluation.option')
def get_object(self, model, fieldname):
ids = self._context.get(fieldname)
if ids is None:
ids = self._context.get('default_' + fieldname)
return self.env[model].browse(ids)
@api.onchange('lead_id')
def _onchange_lead_id(self):
# I check the context to get lead_id
lead_id = self.lead_id if self else self.get_object('crm.lead', 'lead_id')
dom = [('retention', '=', True)] if lead_id.retention else []
return {'domain': {'evaluation_option_id': dom}}
และนี่คือพ่อมดตัวจริง
<record id="evaluation_wizard_view" model="ir.ui.view">
<field name="name">evaluation.wizard.view</field>
<field name="model">evaluation.wizard</field>
<field name="arch" type="xml">
<form string="Evaluate opportunity">
<sheet class="row">
<group>
<group>
<field name="lead_id" invisible="False"/>
<field name="evaluation_option_id" required="True"
create="False" edit="False" widget="radio"
/>
</group>
</group>
<footer>
<button name="evaluate"
type="object"
string="Confirm"
class="oe_highlight"
context="{'lead_id': default_lead_id,
'active_id': default_lead_id,
'evaluation_option_id': evaluation_option_id}"/>
</footer>
</sheet>
</form>
</field>
</record>
ฉันสร้างวิธี onchange สำหรับการเปลี่ยนโดเมนแบบไดนามิกดังที่แสดงด้านบน ฉันพยายามคำนวณโดเมนเช่นนี้: evaluation_option_id = fields.Many2one('evaluation.option', domain=_compute_domain)
โดยที่ compute_domain
เป็นวิธีการเดียวกันกับ onchange แต่ตกแต่งด้วย api.depends
ไม่มีวิธีใดได้ผลตามที่คาดไว้
ฉันใช้โมเดลชั่วคราวที่มีค่า (เช่น lead_id
) ที่กรอกไว้ล่วงหน้าด้วยค่าเริ่มต้น (default_lead_id
) ผ่านปุ่มเปิดบริบท
ไม่ว่าฉันจะพยายามอะไรก็ตาม เมื่อฉันทำให้โดเมนใช้งานได้จริง มันจะกรองค่าออกไป แต่จะใช้ได้กับการเลือกก่อนหน้าเสมอ หมายความว่าหากฉันเลือกโอกาสการรักษาลูกค้า ฉันจะได้รับตัวเลือกทั้งหมด หากฉันเลือกโอกาสปกติ ฉันจะได้รับตัวเลือกการรักษาลูกค้า หากโอกาสถัดไปเป็นโอกาสปกติ ตัวเลือกนั้นถูกต้อง อย่างไรก็ตาม หากฉันเลือกโอกาสในการคงผู้ใช้ไว้ (และแสดงตัวเลือกที่ไม่ถูกต้อง) แล้วเลือกตัวเลือกที่ไม่ถูกต้อง ตัวเลือกที่ไม่ถูกต้องจะถูกกรองออกทันที ฉันไม่แน่ใจ แต่สำหรับฉันแล้วดูเหมือนว่ามีปัญหาเดียวกันนี้ถูกอ้างถึงที่นี่: ตัวกรองโดเมนสำหรับฟิลด์ many2one ใน odoo? ในความคิดเห็นสุดท้ายของคำตอบที่ยอมรับ
คุณเห็นข้อผิดพลาดที่ชัดเจนไหม หรือคุณรู้วิธีอื่นในการเปลี่ยนโดเมนแบบไดนามิกหรือไม่
-- แก้ไข:
ในที่สุดฉันก็สามารถทำให้มันใช้งานได้ ฉันจำไม่ได้ว่าฉันทำอะไรไปเมื่อปีที่แล้ว แต่การเปรียบเทียบระหว่างโค้ดเวอร์ชันเก่ากับเวอร์ชันปัจจุบันแสดงสิ่งนี้:
1) ฉันอัปเดตเมธอด get_object เพื่อรับ lead_id โดยตรงจากแบบฟอร์ม จากนั้นหากไม่สำเร็จ ให้ลองขุดจากบริบท
def get_object(self, model, fieldname):
value = getattr(self, fieldname, None)
if value is not None:
return value
ids = self._context.get(fieldname, None)
if ids is None:
ids = self._context.get('default_' + fieldname)
ids = [] if ids is None else ids
return self.env[model].browse(ids)
@api.onchange('lead_id')
def _onchange_lead_id(self):
lead_id = self.get_object('crm.lead', 'lead_id')
dom = [('retention', '=', True)] if lead_id.is_retention_opp else []
return {'domain': {'evaluation_option_id': dom}}
2) การเปลี่ยนแปลงอื่น ๆ อยู่ใน xml - อ่านอย่างเดียว lead_id
(เพื่อให้ถูกเรียกเพียงครั้งเดียวเมื่อเรนเดอร์วิซาร์ด) และลบวิดเจ็ตวิทยุออกจาก evaluation_option_id
:
<group>
<field name="lead_id" invisible="True" readonly="True"/>
<field name="evaluation_option_id" required="True"
options="{'no_create': True}"/>
</group>
หวังว่านี่อาจช่วยใครซักคนได้
lead_id
มองไม่เห็น& อ่านอย่างเดียว (ดังนั้น onchange จะถูกเรียกเมื่อเรนเดอร์วิซาร์ด) และลบวิดเจ็ตวิทยุออกจากฟิลด์ที่สอง ฉันใส่การเปลี่ยนแปลงไว้ใต้คำถามเดิม - person Juraj Bezručka   schedule 16.07.2019