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

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

Related

cannot find out why odoo sequence is incrementing twice?

I created a model with a sequence field on it:
class AimedPurchaseOrder(models.Model):
_name = "aimed.purchase.order"
name = fields.Char('Number', readonly=True, copy=False,
default=lambda self:self.env['ir.sequence'].next_by_code('aimed.purchase.order'))
And I added the sequence like this:
<record id="seq_purchase_order" model="ir.sequence">
<field name="name">Aimed Purchase Order</field>
<field name="code">aimed.purchase.order</field>
<field name="prefix">BCV</field>
<field name="padding">4</field>
<field name="company_id" eval="False"/>
</record>
The problem is that when I open the form view to create a new record, I get the next value of the sequence that it should be saved, but when I save the record it increments another time and I find records in the tree view with this sequence :
BCV0002, BCV0004, BCV0006, ...
How it that possible? How can I fix it so it saves the default value showed at first time without incrementing again?
Update:
When I remove the readonly=True it works fine, but I can't let this field editable.
I'm not fully sure but IIRC you can use force_save="1" since Odoo 11 as attribute on fields in views to tell Odoo to write values for readonly fields.
An example for a readonly field:
<field name="my_readonly_field" readonly="1" force_save="1" />
If on older Odoos (10 and less) there is a community module adding this feature to Odoo which is called web_readonly_bypass and for example can be found here for Odoo 10.

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

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.

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>
`

Disable one2many popup odoo 8

Good Day! is it possible to disable pop of tree view in the form. I tried no_open="True" readonly="1" edit="False" both on field and tree view but didn't worked.
<field name="payment_line">
<tree editable="top" create="false">
<field name="product"/>
<field name="description"/>
<field name="account"/>
<field name="unit"/>
<field name="qty"/>
<field name="amount"/>
<field name="total"/>
</tree>
</field>
I've coped with the same issue in odoo 10, my one2many treeview always make a popup on click. No matter editable='bottom' option was set.
Suddenly I've found web_tree_no_open module from codingforfun, that adds a new option:
< tree open="false" >
It's for version 8 but it can be used in 10 just renaming openerp.py to manifest.py
It can be downloaded from here:
https://github.com/initOS/web/tree/8.0-tree-view-no-select/web_tree_no_open
Worked for me, I hope it helps
Use this style to disable click in read as well as edit mode:
<field name="your_o2m" style="pointer-events:none;" />
Use editable='bottom' in this case, like:
<field name='line_ids'>
<tree create='false' editable='bottom'>
<field name='so_line_id' readonly='1'/>
<tree>
</field>
Odoo Version 10.0
web_tree_no_open module adds a new option: <tree open="false">
Lists
The root element of list views is <tree> 3. The list view's root can have the following attributes:
editable
by default, selecting a list view's row opens the corresponding form view. The editable attributes makes the list view itself editable in-place.
Valid values are top and bottom, making new records appear respectively at the top or bottom of the list.
The architecture for the inline form view is derived from the list view. Most attributes valid on a form view's fields and buttons are thus accepted by list views although they may not have any meaning if the list view is non-editable
default_order
overrides the ordering of the view, replacing the model's default order. The value is a comma-separated list of fields, postfixed by desc to sort in reverse order:
<tree default_order="sequence,name desc">
create, edit, delete
allows disabling the corresponding action in the view by setting the corresponding attribute to false
on_write
only makes sense on an editable list. Should be the name of a method on the list's model. The method will be called with the id of a record after having created or edited that record (in database).
The method should return a list of ids of other records to load or update.
string
alternative translatable label for the view
Deprecated since version 8.0: not displayed anymore
Note
if the list view is editable, any field attribute from the form view is also valid and will be used when setting up the inline form
view
in the form and tree view you can add create='false' to disable the create button and edit='false' to disable the edit button.Also use editable="top" or editable="bottom" if you dont want the form view to popup. for example
<tree string="Sale Order" create="false" edit="false" editable="bottom">
...
...
...
</tree>

How to change the base fields label in openerp 6.1

researchorial but indeed i have done all the google around what i want o achieve in openerp that how to change those fields label ,i don't wanna play with fields and i know how to create new fields but what about base fields i am not able to edit them they throw some error that you cannot change the base fields from here so objective is clear that those label like Company, SSNID in hr module i want them changed according to them nothing else!!
please do not post links of already same question cause they had not been answered !!
Thank You
You can change the label of a field in two ways.
1. Python code
Inherit the model where that field is defined, then inside _columns add the same field name with new label.
For example, if you want to change SSNID to Employee ID, assume that in the base module the field is defined as 'ssnid' and the field is in hr.employee model.
from osv import osv, fields
class hr_employee(osv.osv):
_inherit = 'hr.employee'
_columns = {'ssnid': fields.integer('Employee ID')
}
hr_employee()
2. XML code(change the view)
Inherit your view and add the attribute for the field 'ssnid'. For example in base module the field view is like <field name="ssnid"/> .To change it inherit its corresponding form and tree view and you can change the field by using position="attribute" and also position="replace". Add the attribute string="Employee ID".
<field name="ssnid" position="replace">
<field name="ssnid" string="Employee ID"/>
</field>
Create New Hr employee Inherited view By this way.
<record model="ir.ui.view" id="updated_hr_form_view">
<field name="name">updated.hr.form</field>
<field name="model">hr.employee</field>
<field name="type">form</field>
<field name="inherit_id" ref="hr.view_employee_form" />
<xpath expr="//form/notebook/page[#string='Personal Information'/group/field[#name='ssnid']]" position="replace">
<field name="ssnid" string="Your New Label"/>
</xpath>
</field>
</record>