How to make a constraint on a fields - odoo

I want to put a control check on a field (TIN) so that everytime I create a new customer, the TIN should be unique. If another customer has that TIN, an error message must show up.
I tried this syntax:
_sql_constraints=[('uniq_vat', 'UNIQUE(self.env.vat)',
'It already exists another company with the same TIN!')]
I'm using odoo 10.

Constrains can be of two types.
Application Constraints
Database Constraints
Database Constraints
Database constraints will add validation at database level while you upgrade that module. Database constraints is list of tuples, in which tuple contains three arguments.
_sql_constraints = [
('constrain name', 'unique(field1, field2)', 'error message which you want to raise on constrains violation'),
('constrain name', 'constrains defination', 'error message which you want to raise on constrains violation'),
]
Constraints name
Constraints, like unique, check
unique constraints can be applied to many columns.
Error message
Example:
_sql_constraints = [
('uniq_vat', 'unique(vat)', 'It already exists another company with the same TIN!'),
]
Multiple database constraints can be added together.
Application Constraints
Application constraints is used to fire custom validation at the time of record add, update and delete. In short your custom method will be called if any changes happen with record.
How to define constrains in code.
#api.constrains('field1','field2'....)
Constrains can be applied to multiple fields together, you can also define it separately.
#api.constrains('vat')
def check_vatnumber(self):
for record in self:
obj = self.search([('vat','=',record.vat),('id','!=',record.id)])
if obj:
raise Warning("Warning", "It already exists another company with the same TIN!")

_sql_constraints = [('unique_tin_no', 'unique(field_name)', 'It already exists another company with the same TIN!')]

Small change is in your line and your constrain work correctly
_sql_constraints=[('uniq_vat', 'unique(vat)', 'It already exists another company with the same TIN!')]
you just need to put "vat" in place of "self.env.vat" sql_constrains just needs field name which is going to apply on DB table underneath.

Related

odoo inherit a model and "key error [my_database]"

I want to try to learn Odoo _inherit. But I have this error right now. And I couldn't solve the problem.
my module name is stock.info and I want the inherit product.template model.
but this error came.
TypeError: Many2many fields stock.info.taxes_id and product.template.taxes_id use the same table and columns
I added product.template to my depends in manifest too. Any advice?
Reminder for future questions: You should provide code for your Problem and not only an error message.
Like the error says you have 2 many2many fields which refers to the same table and columns.
You have to know that many2many fields in Odoo generate a mapping table in the database with two columns which are foreign keys to tables of the referenced models. The name of the mapping table and the column names are automatically generated by default. So if the automatic generation for your field creates the same name for table/columns which are already in use, you will get this error.
To solve this, you can assign additional attributes when defining your field.
So your field could like like this:
taxes_ids = fields.Many2many(relation='stock_info_account_tax_rel', column1='product_id', column2='tax_id')
(remember that many2many fields should be named with suffix _ids and not _id)
Take a look at the documentation for further informations: odoo.fields.Many2many
Parameters:
comodel_name – name of the target model (string) mandatory
except in the case of related or extended fields
relation (str) – optional name of the table that stores the relation
in the database
column1 (str) – optional name of the column referring to “these”
records in the table relation
column2 (str) – optional name of the column referring to “those”
records in the table relation
The attributes relation, column1 and column2 are optional. If not
given, names are automatically generated from model names, provided
model_name and comodel_name are different!
Note that having several fields with implicit relation parameters on a
given model with the same comodel is not accepted by the ORM, since
those field would use the same table. The ORM prevents two many2many
fields to use the same relation parameters, except if
both fields use the same model, comodel, and relation parameters are
explicit; or
at least one field belongs to a model with _auto = False.

Ms Access SQL Limit control by previous field value

In a recipe database I have two tables. One has the ingredients of every recipe [Recipe_ingr] and the other the available measures and weight for every ingredient [Weight2].
When I input a new ingredient for a recipe, I would like to be able to choose the available units for only that specific food.
I have tried with this expression in the control field but it prompts me to choose first, and then the options remain the same for all the records, not changing dinamically according to the record ingredient code.
SELECT [Weight2].[Msre_Desc], [Weight2].[Gm_Wgt] FROM Weight2 WHERE Weight2.NDB_No Like Recipe_Ingr.NDB_No ORDER BY [Msre_Desc], [Gm_Wgt];
Picture of my tables
Update:
I tried the syntax change suggested by June9 but still the control doesn't update automatically with every record as you can see in this picture: Table
Suggest you name controls different from fields they are bound to, like tbxNDB. The SQL needs to reference a field or control that is on the form. Also, LIKE operator without wildcard accomplishes nothing that an = sign wouldn't. Also recommend not using exactly same name for fields in multiple tables.
If you use that SQL statement in combobox RowSource, try:
SELECT Msre_Desc, Gm_Wgt FROM Weight2 WHERE NDB_No = [tbxNDB] ORDER BY Msre_Desc, Gm_Wgt;
You want to save Msre_Desc as foreign key, not a record id generated by autonumber?

Ondelete cascade odoo 8

I need to delete partner who have login in res.users table. when i try to delete that partner i getting an error:
except_orm: ('Integrity Error', 'The operation cannot be completed, probably due to the following:\n- deletion: you may be trying to delete a record while other records still reference it\n- creation/update: a mandatory field is not correctly set\n\n[object with reference: Res users - res.users]').
So i have changed attribute value of ondelete from restrict to cascadeof field partner_id in res.users table. Similarly in change_password. Now its works fine. But is there will be any problem occur due to this change in odoo behavior, like invoice?.

Integrity error where try to save a supplier invoices

I build a module who increase stock on supplier invoices. Work fine on devel server but when I pun on work server I have this error. How can I corret this error?
Integrity Error
The operation cannot be completed, probably due to the following: - deletion: you may be trying to delete a record while other records still reference it - creation/update: a mandatory field is not correctly set
[object with reference: Purchase Order Line - purchase.order.line]
Integrity Error on OpenERP occur because of two possibility (mentioned on the description of error):
When you create or update a record, a mandatory field is not correctly set or is not filled. What field? One of field in your object (mentioned). In your case: purchase.order.line.
When you delete a record, the record you want to delete is used by another record and set as a mandatory field (required) from the python code.
My guess, if you get the error when you create/update a record (Purchase Order), maybe you create/update the order lines, but one of mandatory field in order lines is empty.

In a datacontext are inserted values not available within the datacontext until after submitchanges?

I'm going through an XML file of articles and the journalist(s) that wrote them. As we are adding the articles into _Data our datacontext we may come across a journalist that needs adding so we do this:
newJourno = New journalist With {.name = strJournalist}
_Data.journalists.InsertOnSubmit(newJourno)
.articles_journalists.Add(New articles_journalist With {.id_journalist = newJourno.id, .id_article = .id})
However subsequently we may come across this same journalist again and nothing is returned when we do this:
Dim journo = _Data.journalists.Where(Function(s) s.name = strJournalist).SingleOrDefault
So it uses the code above again to insert the same journalist again.
Once all of our inserts are done we do a submitchanges. At this point it has a head fit:
INSERT statement conflicted with COLUMN FOREIGN KEY constraint 'FK_articles_journalists_journalists'. The conflict occurred in database 'blah', table 'journalists', column 'id'. The statement has been terminated.
From looking through the sql generated in sql profiler you can see that it is trying to add some journalists more than once, this will fail as the name must be distinct. The subsequent records that are trying to be inserted with these journalists are failing as the journalist wasn't updated.
Surely if I have a collection of journalists, add some to it and then look in my collection I should see all of them and not just the original ones. I can fudge it I guess by doing a submitchanges but that seems a bit silly.
Thanks in advance,
Dave.
If you want to add two child-parent rows to the database, you must assign the entity, instead of the Id column, the Id will be autogenerated and will be available only after the submit changes.
You have to do a articles_journalist object, and then assign the newJourno entity to this:
articles_journalist.journalist = newJourno;
CMS is right about needing to assign the object, not the id.
However this doesn't seem to get around the problem of the datacontext not realising that it has had new stuff added to it until you submitchanges. I can only presume this is by design and therefore I am now calling submitchanges as and when the code inserts objects that we later search for.
"the name must be distinct."
This is a serious design flaw. Person names are never unique.