โดเมนไดนามิกทำงานไม่ถูกต้องใน odoo9

ใน 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>

หวังว่านี่อาจช่วยใครซักคนได้


person Juraj Bezručka    schedule 16.07.2018    source แหล่งที่มา
comment
สวัสดี โปรดบอกฉันถ้าคุณมีคำตอบ ฉันมีปัญหาเดียวกัน   -  person Gabriel Asqui    schedule 15.07.2019
comment
@GabrielAsqui ในขณะนี้ดูเหมือนว่าจะทำงานได้อย่างถูกต้อง จริงๆ แล้ว ฉันไม่รู้ว่าอะไรได้ผลสำหรับฉันจริงๆ เนื่องจากปัญหานี้มีอายุได้หนึ่งปีแล้ว อย่างไรก็ตาม ฉันเปรียบเทียบโค้ดที่ส่งมากับเวอร์ชันปัจจุบัน และฉันคิดว่าความแตกต่างที่เกี่ยวข้องเพียงอย่างเดียวคือ ฉันทำให้ lead_id มองไม่เห็น& อ่านอย่างเดียว (ดังนั้น onchange จะถูกเรียกเมื่อเรนเดอร์วิซาร์ด) และลบวิดเจ็ตวิทยุออกจากฟิลด์ที่สอง ฉันใส่การเปลี่ยนแปลงไว้ใต้คำถามเดิม   -  person Juraj Bezručka    schedule 16.07.2019