Check count before insert data odoo 9 - odoo

How in custom module odoo 9 before insert new record in database, check is record exists?
For example:
If in table project.task we have name "PARIS" and date_deadline "2017-01-01" in code below I need warning before execute...
vals = {'name': 'PARIS','date_deadline': '2017-01-01']}
create_new_task = http.request.env['project.task'].create(vals)
Or maybe try get count from project.task where name='PARIS' and date_deadline='2017-01-01' before click on button save!
Any simple solution?
#api.one
#api.constrains('date','time') #Time is Many2one
def _check_existing(self):
count = self.env['test.module'].search_count([('date','=',self.date),('time','=',self.time.id)])
print(self.date) #2017-01-01
print(self.time.id) #1
if(count >= 1):
raise ValidationError(_('DUPLICATE!'))
After try insert new record in database where is date = 2017-02-02 and time = 1 get this message:
duplicate key value violates unique constraint "test_module_time_uniq"
DETAIL: Key (time)=(1) already exists.
Time exist but date is different! I need constrains for 2 value! In databse I have only one row where is date = 2017-01-01 and time = 1

if you want to prevent duplicated record use sql_constrains
class ModelClass(models.Model):
_name = 'model.name'
# your fields ...
# add unique constraints
sql_constraints = [
('name_task_uniq', 'UNIQUE (name,date_deadline)', 'all ready got a task with this name and this date')
]
# or use api.constrains if you constrains cannot be don in postgreSQL
#api.constrains('name', 'date_deadline')
def _check_existing(self):
# add you logic to check you constrain
duplicate key value violates unique constraint "test_module_time_uniq"
DETAIL: Key (time)=(1) already exists.
This error is thrown by the postgres not odoo you all ready have a unique constrain for time only you need to drop it first
NB: Who added the constrains unique is it you when you where testing you code or is someone else? Answer this by comment ^^
ALTER TABLE project_task DROP CONSTRAINT test_module_time_uniq;

You can use something along those lines:
#api.constrains('name', 'date_deadline')
def _check_existing(self):
# Search for entry with these params, and if found:
# raise ValidationError('Item already exists')

Related

MVC update the database based on a non primary key value

I have a database table that looks like this:
My goal is to update my "unavail" table based on the ID of either the component, part, or item depending on which one is relevant in my situation.
For example, if the partID = 43 I want to add to the 'unavail' column
I first started working on this by trying this
db.OffSiteItemDetails.Find(sod.PartID).unavail += sod.comp_returned;
(Where sod.PartId = 43)
But I quickly realized it was just checking for where the "ID" was equal to 43 which isn't what I want. After some investigation I saw people suggesting using
db.Where(x => x.non-pk == value)
So I created this
db.OffSiteItemDetails.Where(x => x.componentID == sod.ComponentID);
But from here I don't know how to change my unavail table values.
This was a tough question to type so if you need more clarity just ask
foreach(var item in db.OffSiteItemDetails.Where(x => x.componentID == sod.ComponentID))
{
// item.unavail = [new value]
// db.Update(item);
// ...I don't know how you update the data in your database
}
Something like that?

Using an _sql_constraints in Odoo 12 date

Hi I created the following model:
class PrescriptionsPrescriptions(models.Model):
_name = 'prescriptions.prescriptions'
name = fields.Many2one('res.users','Name', default=lambda self: self.env.user, readonly=True)
Date_entered = fields.Date(string='Date', default=fields.Date.today())
paper_prescriptions = fields.Selection([('yes', 'Yes'), ('no', 'No')], string='Paper Prescriptions?')
However I cannot get the _sql_constraints to work:
_sql_constraints = [('log_unique','unique(name,Date_entered)','You have already logged data for that date.')]
I'm trying to get it so that each person can log only one prescription per Date_entered. Would greatly appreciate any help. :)
Odoo will not be able to add the constraint because of a psycopg2.ProgrammingError
column "date_entered" named in key does not exist
You just need to rename it to date_entered and update the module.
First you can’t have capital letters as starting of your variable.
Second the only reason constraints don’t work after updating is when there is already data violating the constraints

Get the inserted primary key ids using bulk_save_objects

How can I get the inserted Ids (primary key generated) after using session.bulk_save_objects?
I tried this:
for x in y:
obj = Post(...)
obj_list.append(obj)
session.bulk_save_objects(obj_list)
session.commit()
for i in obj_list:
print(i.id)
The ids are None. The rows are successfully inserted.
you need to add return_defaults = True in bulk_save_object method like below to get primary key of records
for x in y:
obj = Post(...)
obj_list.append(obj)
session.bulk_save_objects(obj_list,return_defaults = True)
session.commit()
for i in obj_list:
print(i.id)
A more performant way to do this rather than using bulk_save_objects which emits an insert statement per value is to use sqlalchemy.dialects.postgresql.insert with a returning clause.
insert_stmt = insert(Table).values(dictionary_mappings).returning(Table.id)
ids = db.session.execute(insert_stmt).fetchall()

two many2many fields with different partner

i have two fields that should be related to res.partner
in partner_ids i want to choose partner and in recipients_ids i want to choose another partner that will get a copy of the document. the problem that in form view if i change partner_ids or recipient_ids both fields became the same. how can i do that i can choose different partners in those fields?
partners_ids = fields.Many2many('res.partner', string='Companys Names')
recipients_ids = fields.Many2many('res.partner', string='Copys for')
You are getting the error because the two field work on the same table in postgres
because odoo create a table for that name like this:
current_model_name_co_model_name_rel
in your case
your_model_res_partner_rel
so you need to tell odoo that every field has it's own relation
partners_ids = fields.Many2many('res.partner', # co_model
'your_model_partners_rel', # relation name change your_model to much your model name
string='Companys Names')
recipients_ids = fields.Many2many('res.partner',
'your_model_recipients_rel',
string='Copys for')
when you create m2m field it's better to specify this value by keyarguement
_name = 'my.model'
# exmple
user_ids = fields.Many2many(comodel_name='res.users', # name of the model
relation='my_model_users_rel', # name of relation in postgres
column1='session_id', # id reference to current mode
column2='user_id', # id reference to co_model
string='Allowed users')

Sort by associated table's column

I'm trying to get a specific order from an associated table. Here's my setup:
I have a trip which has triplocations added to it. The Triplocation table has a column which defines the order of the locations with a column named location_order. Now i'd like to order on this column when i collect my single trip in the show method.
I've tried #trip = Trip.find(params[:id], :order=> 'triplocations.location_order') but got the following error:
PG::Error: ERROR: missing FROM-clause entry for table "triplocations" LINE 1: ....* FROM "trips" WHERE "trips"."id" = $1 ORDER BY triplocati...
Any ideas how to get my location_order ordered?
Thanks in advance!
It sounds like you want the triplocations association to be ordered, i.e. that #trip.trip_locations is ordered by the location order.
I'd suggest adding a default scope to TripLocation:
default_scope :order => 'location_order DESC'
First, find is only going to give you one record, so you either want to use where or find all.
Second, if you want to return TripLocations, and not trips, you need to start your query with that
Try this:
TripLocations.where(:trip_id => params[:id]).order(:location_order)
If you want to order the locations on a trip that you have, you can do that through the associations in your model as well
# load the trip
#trip = Trip.find(params[:id])
# order the locations
#locations = #trip.triplocations.order(:location_order)