I have hospital appointment registration model that is relates to lab test model :
'lab_test_ids': fields.one2many('oeh.medical.lab.test','apoointment','Lab Tests', readonly=False,states={'Completed': [('readonly', True)]}),
in the view I have a TAB (page) under appointment form :
page string="Lab Tests"> <field name="lab_test_ids" context="{'default_appointment': active_id}" domain="[('appointment', '=', active_id)">
My challenge is that I have patient and physician in both views (selection fields) that relate to two other models. I was wondering if I could SET value for a patient field in the parent view and inherit that value to the child view (Lab test). how can I do that?
NOW i use domain to filter through the patient. and the candidate patient is Only one . how can I set this value to the field automatically.
> <field name="patient" domain="[('id', '=', parent.patient)]"
I appreciate your help.
I'm not sure I 100% fully understand the question but you only have a few options to handle the scenario of copying field data between views.
1.
Onchange Field. Create an onchange if they are on the same view. (Don't believe this will work for you.)
lab_test = fields.One2many(...)
#api.onchange('lab_test')
def _onchange_set_lab_test(self):
self.other_field = self.lab_test
2.
Related Field. Setup the child as a related field if it's of the same type:
child = fields.One2many(related='lab_test')
3.
Computed Field. Setup the child as a computed field with pulls whatever information you need.
child = fields.One2many(compute='_compute_child_field')
Related
example/models/example.py
class Example(models.Model)
_name = 'example.model'
product_tmpl_id = fields.Many2one('product.template','Product Template',delegate=True,ondelete='cascade',required=True)
example/models/product_template.py
class ProductTemplate(models.Model)
_inherit='product.template
example_ids = fields.One2many('example.model','product_tmpl_id',string='Item')
example/views/example.xml
<form>
<field name="product_tmpl_id" widget="many2one"/>
</form>
My understanding was that a product_template record would be automatically created with example, but this field is required and not letting me save a new record. When I perform an import of the example data adding these columns at the beginning for product_template ("exampleNN", "name", "type", "categ_id/id", "sale_ok", "purchase_ok",...) I get a matching product template with an id of "exampleNN_product_template" and identical name (though example does not have name so it must be using product template).
product_tmpl_id does not like being on the form view as it is required, yet not created yet with delegation inheritance. I used tree view instead to see product_tmpl_id. I was curious about its value after doing an import.
I'm looking for a way to filter subsequent selections depending on which ones of them are filled.
I want to have a tree-like structure for setting locations as such:
=>Country
==>State
===> District
So say you enter the district first, you'd only have one choice in the other two.
Say you enter the country first, you'd have a more limited selection of the latter two.
I know i should be going with many2one fields but all i can get working at this point is multiple selections that turn visible/invisible which is highly inefficient.
I'm fairly new to Odoo and am finding the docs somewhat lacking. Any help would be appreciated!
I would play around with many2one fields and domains using the operator =?
For example:
class MyModel(models.Model):
_name = "my.model"
country_id = fields.Many2one(comodel_name="res.country")
state_id = fields.Many2one(comodel_name="res.country.state")
disctrict_id = fields.Many2one(comodel_name="res.country.state.district")
I don't know if the model names are correct, but you should already know them.
And in the view use the domain with the mentioned operator:
<field name="country_id"
domain="[('state_ids', '=?', state_id),('state_ids.district_ids', '=?', district_id)]" />
<field name="state_id"
domain="[('country_id', '=?', country_id),('district_ids', '=?', district_id)]" />
<field name="disctrict_id"
domain="[('state_id', '=?', state_id),('state_ids.country_id', '=?', country_id)]" />
I didn't make any tests on those AND conditions/domains. And i don't know the structure of those 3 models. My assumption is, that there is a one2many or many2many relation on res.country -> res.country.state and res.country.state -> res.country.state.district.
I add a button that open a new wizard, this last is contain only one field is number , that's number is the number of fields that i want to creat on my tree notebook tree view with default value
for example if i type 20 , thene whene i submit should i get 20 entries in the tree view
Here is a capture of the model :
Look to my code :
#api.multi
def creat_fields(self):
numbers = self.w_qtt
for values in numbers:
# self.env['sale.order.line'].create(lignes_vales)
self.env['sale.order.line'].create({
'contrat_name_id': self.w_contrat_name,
'contrat_lignes_id' : self.w_contrat_line,
'product_id' : self.w_product_name,
'bons_po' : self.w_po_number,
'product_uom_qty' : 1,
'price_unit' : self.w_prix,
})
and on the xml :
<footer>
<button string="Cancel" class="oe_link" special="cancel"/>
<button
name="creat_fields"
string="Enregistrer"
class="oe_highlight"
context="{'default_source_record_id': active_id}"/>
</footer>
I'm assuming that this is a one2many field. One2many fields are linked to your model by specifying the record id number in a field that you specify when you define the many2one field.
For example:
child_ids = fields.One2many('child.model.name', 'parent_id', 'Child Records')
So when you create a new line using the one2many field, a new record is created of model "child.model.name" and the parent_id field is set to the id of the current record.
So to create a number of empty lines in your form, all you have to do is create records with the "parent_id" field set to the originating records id.
Firstly, you will need to pass the originating record's id to the wizard, which you would do in the button definition:
<button name="%(wizard_action)d"
string="Wizard Button"
type="action"
context="{'default_source_record_id': active_id}" />
You will need a field called "source_record_id" in your wizard, which will be a many2one field with the same model that you are calling it from, and you will need to have that field in your wizard view, but you can make it invisible if you want.
In the code you're calling from the wizard, you will create a loop to call the create method on the "child.model.name" model to create that number of empty records. It would look something like this:
iterations = self.nombre
for i in range(iterations):
self.env['child.model.name'].create({
'parent_id': self.source_record_id.id
})
That will create the empty records and they will be displayed in your one2many field.
I have some data in a tree structure. One of the fields are computed (not stored) using data from the children.
In a form view, I show the computed field and the parent field.
Because of this, I end up reading many records from the model - and Odoo seems to compute the computed field for all of these records, even though the view only needs the computed field for one record.
I thought this was caused by the prefetch mechanism, but I tried to set prefetch_fields=False in the context, and that didn't help.
Any idea how I can avoid computing all the unnecessary values? (Storing the computed field is not an option).
A quick example to give an idea of the construction:
parent_id = fields.Many2one(...)
child_ids = fields.One2many(...) # Inverse parent relation
comp = fields.Integer(compute="_compute_comp")
#api.one
def _compute_comp(self):
sum = 0
for c in self.child_ids:
sum += c._get_complicated_value()
self.comp = sum
and a view with:
<field name="parent_id" />
<field name="comp" />
comp is always computed for the children's children. With <field name="parent_id" /> it is also computed for ALL the parent's children.
you can use #api.depends
#api.depends
This decorator will trigger the call to the decorated function if any of the fields specified in the decorator is altered by ORM or changed in the form:
#api.depends('name', 'an_other_field')
def afun(self):
pass
Note:
when you redefine depends you have to redefine all #api.depends, so it
loses some of his interest.
One of the great improvement of the new API is that the depends are automatically inserted into the form for you in a simple way. You do not have to worry about modifying views anymore.
#api.one
#api.depends('child_ids')
def _compute_comp(self):
sum = 0
for c in self.child_ids:
sum += c._get_complicated_value()
self.comp = sum
In OpenERP version 7, I need to show or hide a field in the Form View of the "Add Object" based on the values from the Parent Object.
For example, I have a field demo_field1 in sale_order. When I create a Sale Order Line, I do not want to show the field "th_weight" if the demo_field1 for the Sale Order is greater than 200.
using attrs="{'invisible': [('demo_field', '>', '200')]}" or attrs="{'invisible': [('order_id.demo_field', '>', '200')]}" shows invalid field in domain.
How to achieve this?
I also had the same issue some time before. What i did was to add a related field in the sale_order_line and define attriute based on that related field. ie;
In sale order line i defined a related field to the field demo_field1 as:
'test_field_new': fields.related('order_id', 'client_order_ref', string="Test Field", type="float")
But the related field will only be loaded at the time of saving the record. So i passed the default value of the field test_field_new from xml file as:
<field name="order_line" context="{'default_test_field_new': demo_field1}"/>
so that when i click on "Add new item" in one2many field, the value of the field demo_field1 will be loaded by default to test_field_new and i defined the attribute using the field test_field_new.
<field name="price_unit" attrs="{'invisible': [('test_field_new', '>', 200)]}"/>
I am not sure this is a clean method to do...