Odoo - How add a field to view from another wizard model? - odoo

I want the use a field from wizard to my form view.
Let me explain with code:
class CancelAppointmentWizard(models.Model):
_name = "cancel.appointment.wizard"
_description = "Cancel Appointment Wizard"
reason = fields.Text(string="Reason")
and i want the show this "reason" field inside of some form views.
<record id="view_hospital_appointment_form" model="ir.ui.view">
<field name="name">hospital.appointment.form</field>
<field name="model">hospital.appointment</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<field name="reason"/>
</group>
</sheet>
</form>
</field>
</record>
but of course this give me error like
hospital.appointment don't have a field like reason.
How can show this field ?
I tried to make a dummy code, i hope i was able to explain my problem.

I assume the wizard is called from the view_hospital_appointment_form. And in the wizard view let say there is a button tag with name attribute, which is this attribute associated to python method in your wizard class.
Wizard view
<record id="view_cancel_appointment_wizard_form" model="ir.ui.view">
<field name="name">cancel.appointment.wizard.form</field>
<field name="model">cancel.appointment.wizard</field>
<field name="arch" type="xml">
<form>
…
…
<footer>
<button name="action_ok" string="Ok" type="object"/>
</footer>
</form>
</field>
</record>
Python method
def action_ok(self):
ids = self.env.context.get('active_ids')
hospital_appointment = self.env['hospital.appointment'].browse(ids)
hospital_appointment.reason = self.reason
return {'type': 'ir.actions.act_window_close'}

Related

Odoo 10 - QWeb hide a view element if a field is False

I have following QWeb element:
<record id="extended_res_partner" model="ir.ui.view">
<field name="name">Extended View</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="model">res.partner</field>
<field name="arch" type="xml">
<notebook position="inside">
<page string="Foo" name="foo" attrs="{'invisible': [('is_customer', '=', False),]}">
<field name="is_customer" invisible="1"/>
<span>Foo2</span>
</page>
</notebook>
</field>
</record>
But it does not work. I get:
Field `is_customer` does not exist
If I remove attrs=... it works fine.
Even that you didn't provide the error message but this will work only if the the form view if for res.partner but i'm assuming that the form is for another model that have a many2one relation with res.partner in this case you need to create a related field in the model.
partner_id = ......
is_customer = fields.Boolean(related='partner_id.is_customer', readonly=True)
Then you need to add this field to the form view because attrs is client side feature it need the value in form in order to work.
<page string="foo" name="foo" attrs="{'invisible': [('is_customer', '=', False),]}">
<field name="is_customer" invisible="1"/>
<span>Foo2</span>
</page>
Note: if the form view is for res.partner just add the field to the form view because as I said is a client side operation it will not call the server to know what is the value of that field you need to pass it.

Odoo 11 - pull fields values from other models

I have added a custom field (many2one) in crm.lead form and a custom class for that
Here is my code (I am using odoo 11):
models.py
from odoo import models, fields, api
# Add fields to Leads
class Leads_events(models.Model):
_inherit = 'crm.lead'
venue = fields.Many2one('crm.lead.venue',String="Venue")
venue_city = fields.Char(String="City")
venue_country = fields.Many2one('res.country', string="Country")
# Create venue class
class Leads_venue(models.Model):
_name = 'crm.lead.venue'
name = fields.Char(string="Venue name")
city = fields.Char(string="City")
country = fields.Many2one('res.country', string="Country")
address = fields.Text(string="Address")
website = fields.Char(string="Website")
phone = fields.Char(string="Phone")
fax = fields.Char(string="Fax")
notes = fields.Text(string="Notes")
views.xml
<record id="crm_lead_venue_form" model="ir.ui.view">
<field name="name">crm.lead.venue.form</field>
<field name="model">crm.lead.venue</field>
<field name="arch" type="xml">
<form string="Venues">
<group>
<group>
<field name="name"/>
<field name="country"/>
<field name="city"/>
<field name="address"/>
</group>
<group>
<field name="phone"/>
<field name="fax"/>
<field name="website"/>
</group>
<group>
<field name="notes" />
</group>
</group>
</form>
</field>
</record>
<record id="crm.crm_case_form_view_oppor_events" model="ir.ui.view">
<field name="name">crm_case_form_view_oppor_events</field>
<field name="model">crm.lead</field>
<field name="inherit_id" ref="crm.crm_case_form_view_oppor"/>
<field name="arch" type="xml">
<xpath expr="//notebook" position="before">
<group string="Venue">
<field name="venue"/>
<field name="event_city" string="City"/>
<field name="event_country"/>
</group>
</xpath>
</field>
</record>
This works fine. Now what I am trying to pull is the city and country from crm.lead.venue selected record to crm.lead 'venue_city' and 'venue_country' fields.
I looked at onchange function but I cannot find how to make it work...
I've tried this following another post I read but it is not working
#api.onchange('venue')
def onchange_venue(self):
if self.venue:
self.event_city = self.venue.city
self.event_country = self.venue.country
Is there anywhere I can find a documentation or help more complete on this ? The official documentation is not very precise on this matter.
The onchange method works when the user change the field in the view, and I cant see the field on your view, so the method would be never be called. You should add "venue" field to the form and test it again.
Edit
Have you seen that it is not event_city but venue_city? The onchange should be on leads_events. Did you test that onchange is executed and has no value? Or it doesnt even execute the function ?
#api.onchange('venue')
def onchange_venue(self):
if self.venue:
self.venue_city = self.venue.city
self.venue_country = self.venue.country

Inherit TransientModel and have two views ( website.config.settings )

I am trying to inherit the Website settings menu and have two views. website.config.settings is a models.TransientModel
When I am inheriting that and viewing with a new menuitem it overwrites the previous view. Like - There are two views now, the new record I defined named Website Event Settings . When I click on that it loads the new modified view but when I click on existing Settings menu, it shows nothing.
In summary, the existing website settings menu not working and new menu does. I need both of them.
The py code and record view I used are following -
class cofair_website_design_config(models.TransientModel):
_name = 'website.config.settings'
_inherit = 'website.config.settings'
event_title = fields.Char(related='website_id.event_title', string='Event Title')
XML:
<record id="view_website_event_config_settings" model="ir.ui.view">
<field name="name">Website Event Settings</field>
<field name="model">website.config.settings</field>
<field name="arch" type="xml">
<form class="oe_form_configuration">
<header>
<button string="Apply" type="object" name="execute" class="oe_highlight"/>
<button string="Cancel" type="object" name="cancel" class="oe_link"/>
</header>
<div>
<group string="Event Page Section">
<group>
<field name="event_title_color"/>
</group>
</group>
</div>
</form>
</field>
</record>
<record id="action_website_event_configuration" model="ir.actions.act_window">
<field name="name">Website Event Settings</field>
<field name="res_model">website.config.settings</field>
<field name="view_mode">form</field>
<field name="target">inline</field>
<field name="view_id" ref="view_website_event_config_settings"/>
</record>
<menuitem id="menu_website_event_settings" parent="website.menu_website_configuration" name="Website Event Settings" action="action_website_event_configuration"/>
Instead of renaming the modules (which causes relational error), I found a workaround. I have inherited the main settings and put a view id there and called it with menuitem -
<!-- Bring settings menu out -->
<record id="website.action_website_configuration" model="ir.actions.act_window">
<field name="name">Website Settings</field>
<field name="res_model">website.config.settings</field>
<field name="view_mode">form</field>
<field name="target">inline</field>
<field name="view_id" ref="website.view_website_config_settings"/>
</record>
<menuitem id="website.menu_website_website_settings" parent="website.menu_website_configuration" name="Website Admin" action="website.action_website_configuration"/>
Then I called my record action and it loaded the view and action. Another catch point is I had to show website_id to show the values of specific websites or the transient model will always be empty.
Change the _name attribute in your model definition to something else and also modify the xml appropraitely.
class cofair_website_design_config(models.TransientModel):
_name = 'something.else'
_inherit = 'website.config.settings'
event_title = fields.Char(related='website_id.event_title', string='Event Title')
ir.ui.view
<field name="model">something.else</field>
and ir.actions.act_window
<field name="res_model">something.else</field>
That should copy all the fields and methods from website.config.settings to the new model something.else and keep it separate from website.config.settings

How to hide fields based on condition in odoo?

I have created few custom fields for products.Products appear in sales,purchase,warehouse and manufacturing module.I want to make my custom fields appear only in manufacturing module and hide everywhere else.So how to put condition on invisible attribute.I tried like this and got error as Unknown field _name in domain
attrs="{'invisible': [('_name', '!=', 'mrp.bom')]}"
Python file,
from openerp import fields,models, api
class product_template(models.Model):
_inherit = "product.template"
rim_weight = fields.Float(string='Rim Weight(KG)', readonly=True, compute='_compute_one_rim_weight')
width = fields.Float(string='Width(cm)',default='50')
length = fields.Float(string='Length(cm)',default='63')
gsm = fields.Float(string='Gram per square meter(gsm)',default='230')
Xml file,
<record id="product_template_form_view_dis_inherit" model="ir.ui.view">
<field name="name">product.template.common.form.dis.inherit</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_form_view"/>
<field name="arch" type="xml">
<xpath expr="//page[#string='Accounting']" position='after'>
<page string='Cover Page Paper'>
<group>
<field name="width"/>
<field name="length"/>
<field name="gsm"/>
<field name="rim_weight"/>
</group>
</page>
</xpath>
</field>
</record>
There are many ways to do this, however I suggest following options to you.
Modify an existing action and set context inside that and based on that context just write condition in view. (Remember here you need to override an action, and if you want to create another then you need to redefine menu to assign new action to that menu).
Create new view and set this view reference in an action of that model in which you want to show these fields. In new view you need to visible those fields, no need to extend product template existing view.
However the 1st solution is easy to achieve and 2nd one is lengthy.
Example of 1st solution:
<record id="action_name" model="ir.actions.act_window">
<field name="name">Name</field>
<field name="res_model">product.template</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="context" eval="{'is_manufacturing_model':True}" />
</record>
And then in view just write like this
<page string='Cover Page Paper'>
<group invisible="context.get('is_manufacturing_model',False)">
<field name="width"/>
<field name="length"/>
<field name="gsm"/>
<field name="rim_weight"/>
<group>
</page>

Can't remove top "Save" button from Odoo

I want to remove the top "Save" button from the formview of my custom module.
I know that we perform this by setting write/create to false in the XML, which I did and can't figure out why it is still there.
My view:
<record id="view_module_genall_form" model="ir.ui.view">
<field name="name">module.genall.form</field>
<field name="model">module.genall</field>
<field name="arch" type="xml">
<form string="Automatically generate bills" edit="false" create="false" delete="false" write="false">
<button name="generate_all" type="object" string="Generate bills" icon="oe_highlight"/>
</form>
</field>
</record>
The related action:
<record model="ir.actions.act_window" id="action_module_genall">
<field name="name">Automatically generate bills</field>
<field name="res_model">alkivi.genall</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_module_genall_form" />
</record>
Do you have an idea ? Thanks!
From it's title it looks like the purpose of your form is to run a server method to perform some business logic.
For that you should use a Wizard instead of a regular Model: for that the module.genalshould be a models.TransientModel instead of a models.Model.