i have a many2many table,But i need to give domain as only the partner's record in the model needs to be shown in the many2many table - odoo

class HealthProfileInherit(models.Model):
_inherit = 'health.profile'
health_profile_health_test_id = fields.Many2many('health.test',
string ='Laboratory Test')
this the field connecting the 2 tables, how will give domain here? Do I wanna write a function or can give domain inside the field?

The following domain:
domain="[('partner_id', '=', partner_id)]"
will filter records shown in the popup list after you click on the add item button link. only the test records with the profile partner will be visible.
String domains are supposed to be dynamic and evaluated on the client-side only.
By default, users can create records from the popup list and they can select any partner in the partner_id field.
If you want to disable the creation option from the popup list use the no_create option:
options="{'no_create': True}"
If you want to keep the create button and force users to select the profile partner, you can create a new form for the health.test model and set the partner field invisible then pass the default partner value in context and force the many2many field to use that form.
<field name="health_profile_health_test_id"
domain="[('partner_id', '=', partner_id)]"
context="{'form_view_ref': 'module_name.health_test_form', 'default_partner_id': partner_id}"/>
Remember that the form view with the lowest priority will be used as the default form view (The default priority value is 16):
Example:
<record id="health_test_form" model="ir.ui.view">
<field name="name">health.test Form</field>
<field name="model">health.test</field>
<field name="priority" eval="20"/>
<field name="arch" type="xml">
<form>
<group>
<field name="partner_id" invisible="True"/>
....
</group>
....
</form>
</field>
</record>
Edit:
String domains are dynamic and evaluated in client-side, for example the "[('partner_id', '=', partner_id)]" string domain will be evaluated to [('partner_id', '=', 26)] and if the list has already selected records, the records will be excluded using ['!', ['id', 'in', list_of_ids]].
But when passing the domain as a list with the many2one field reference, the value will be of type Many2one and the server should raise a RecursionError when trying to get field attributes (tested in v12, v13).
If you look in the Odoo source code you will find many examples using a list domain but with simple values like booleans, strings, etc.

Related

How to not allow Many2many to be able to remove its element in form view?

I have a many2many field that represents a list of student. I want to only add student to that list but not remove any students from that list (in form view). Is it possible to implement that?
I think it's possible to do it. You need to override the #write method. Each time that an update will be made on your object, you need the compare the actual length of your many2many field current_length and the new length of students made by the update new_length.
If new_length > current_length, it's means that the update is an adding, so you can consider the changes. Otherwise, it's means that the update is a removing, so you just need to ignore the changes.
Please find below, an exemple of implementation :
#api.multi
def write(self, values):
current_length = len(self.student_list)
new_length = len(values['student_list'])
if current_length > new_length:
\* Removing of students *\
values['student_list'] = self.student_list
res = super(Object, self).write(values)
return res
Note that you can go further by making another comparaison between the ids of the current and new list, in order to be sure that the students are the same.
It s not possible using the many2many_tags widget, but using the xml tree view as part of your Form view, you can add the delete-attribute on the tree-node inside the scope of your own field:
<form>
<notebook>
<sheet>
<page string="Graduated" name="gratuated_students">
<field name="students_ids" >
<tree string="Students" editable="bottom" delete="0" >
<field name="name"/>
<field name="birthday"/>
<field name="score" readonly="1"/>
</tree>
</field>
</page>
</notebook>
</sheet>
</form>
If this view comes from an odoo's module (no custom module): you'd rather inherit this view and add the attribute "delete=0" to the existing student_ids field:
<xpath expr="//form[1]/sheet[1]/notebook[1]/page[1]/field[#name='students_ids']/tree[1]" position="attributes">
<attribute name="delete">0</attribute>
</xpath>
Otherwise, if you really want to use the many2many_tags widget and if your are experienced with odoo's js-framework, you could develop your own option "no_delete" on the basis of the following OCA module:
https://odoo-community.org/shop/web-m2x-options-2661#attr=10772

How to give user groups(XML) in the model ir.actions.server odoo 12?

I used this xml code to add a button inside the 'Action',But i need to restrict the button to some user groups,
<record id="specialist_no_show_action" model="ir.actions.server">
<field name="name">No Show </field>
<field name="type">ir.actions.server</field>
<field name="binding_model_id" ref="second_opinion.model_consultation"/>
<field name="model_id" ref="second_opinion.model_consultation"/>
<field name="state">code</field>
<field name="code">
action = model.update_no_show()
</field>
</record>
The ir.actions.actions get_bindings method will try to retrieve the list of actions bound to the given model and discard unauthorized actions then read action definitions.
The method will use groups_id field to check if the user may not perform an action.
groups_id
Many2many field to the groups allowed to view/use the current report
So a groups_id field is added to ir.actions.report to allow groups to view/use the current report
Unfortunately, the groups_id field is not implemented in ir.actions.server
Fortunately, the get_bindings method is implemented in the ir.actions.actions model which is the base model for both models ir.actions.report and ir.actions.server, so to use the same logic in server actions just add a groups_id field in ir.action.server and use it from the XML definition to restrict access to some groups.
Use the groups_id field for server action:
Inherit server action model and add the groups_id field:
class IrActionsServer(models.Model):
_inherit = 'ir.actions.server'
groups_id = fields.Many2many('res.groups', 'res_groups_server_rel', 'uid', 'gid', string='Groups')
Then set the groups_id field value from XML, the following example will use the special commands format to add the Administration/Access Rights group to the groups_id field:
<field name='groups_id' eval="[(4, ref('base.group_erp_manager'))]"/>
I don't think it is possible to restrict its visibility in the action menu, but as a workaround you could do the following in the code of the server action:
if not env.user.has_group('base.group_erp_manager'):
raise Warning("You do not have access to trigger this action")
Replace "base.group_erp_manager" with your user group's XML ID.

Create custom search view to search based on two fields in one2many field along with the other fields present in the module

I created a module for managing employee resume in Odoo. Employees will fill their work_experience, education, technology-wise experience, etc. I wanted to make the search view search for all these parameters. The technology-wise Experience here is a One2Many field. I wanted to search this field based on both the parameter together (i.e experience and technology). Please help me find a way to do this.
In Model
technology_experience =
fields.One2many("hr.employee.work.technology.experience",
inverse_name='resume_id', string='Technology Experience')
In view
`<field name="technology_experience">
<tree editable="bottom" create="0">
<field name="name" required="1"/>
<field name="experience" required="1"/>
</tree>
</field>
`

Odoo If statement with category

Hi I am using Odoo10 and I have some products assigned to categorys. On my Sale Order screen I have 2 selection boxes one is Carpet and the other is Flooring. Below is my code for showing cetain fields
#api.onchange('squarebox')
def _onchange_default_code(self):
if self.flooring2:
self.boxes = (self.squaremtr) / (self.squarebox or 1)
self.squaremtrsold = (self.squarebox or 1) * (self.suggestbox)
Instead of using a selection field I was wondering if it is possible to do an IF statement based on Category the product is in. So instead of if self.flooring2:something like
if self.productid is in category Carpet:
First add this two category in Category Master then select this Internal category in Product you want.
Your XML File :
<record id="category_flooring" model="product.category">
<field name="name">Flooring</field>
<field name="type">normal</field>
<field name="property_cost_method">standard</field>
<field name="property_valuation">manual_periodic</field>
</record>
<record id="category_carpet" model="product.category">
<field name="name">Carpet</field>
<field name="type">normal</field>
<field name="property_cost_method">standard</field>
<field name="property_valuation">manual_periodic</field>
</record>
Now your python code goes like this:-
#api.onchange('product_id')
def _onchange_default_code(self):
if self.product_id.categ_id.id == self.env.ref('your_module_name.category_flooring').id:
# Your code belongs to flooring category
elif self.product_id.categ_id.id == self.env.ref('your_module_name.category_carpet').id:
# Your code belongs to carpet category
If I understand correctly, you want to show or hide some fields depending on values from other fields of the same record.
To do so use the invisible attribute on the form view definition, not a python function. I would use a python function decorated with an #api.onchange to calculate other values that depend on squarebox.
See for example addons/sale/views/sale_views.xml around line 227:
<field name="validity_date" attrs="{'invisible': [('state', 'in', ['sale', 'done'])]}"/>
The line above translates to plain English as: Show the validity_date field except when the state field is either sale or done.

filter tree view of header model on base of values of the detail model

I have a model 'purchase_approval_item' with an invoice_id
multiple people approve the invoice and they are registered in the model 'purchase_approval_item_line'
Now i need to show the 'purchase_approval_item' in a tree view, but filter is for the logged in user.
I want to add one2many field in 'purchase_approval_item', approved_by_ids which should be the uids of the approvers. And i want to use that one2many field to filter the treeview.
How can i do this with the openerp framework?
You want to filter the purchase_approval_item tree to have only the records where the approved_by_ids one2many field contains a certain a user - probably the current one.
You should have a search view for your purchase_approval_item model, with:
<filter domain="[('approved_by_ids', 'in', [uid])]"
name="filter_my_approvals" string="My Approvals" />
You can also add a record rule. which will let user to see only record approved by him/her in tree view.
<record model="ir.rule" id="resource_approved_record">
<field name="name">See Own Approved record</field>
<field name="model_id" ref="model_purchase_approval_item"/>
<field name="domain_force">[('approved_by_ids', 'in', [user.id]])]</field>
</record>