How does domain works in openerp as well as xml? - odoo

I am working on domain and I'm not getting how it works exactly , below I have given my code pls tell me how could I use it and how it fits into my code.
class test_cl(osv.osv):
_name = 'test.cl'
_columns ={
'name':fields.char('Name',size=20),
'age':fields.integer('Age',size=10),
'gender':fields.selection([('m','M'),('f','F')],'gender'),
'tel_no':fields.char('Telephone',size=100,),
'emailid':fields.char('Email id',size=20),
'website':fields.char('Web address',size=20),
'company':fields.char(
'Company name',
size=100,
domain=[('choice','=',YES)],
change_default=True,
),
'desg':fields.char('Designation',size=100),
'wght':fields.float('Weight'),
'choice':fields.selection(
[('yes','YES'),('no','NO')],
'Working',
required=True,
),
}
_defaults = {
'age':30,
}
test_cl()

Domain restricts your record to display. It is a condition for your records. For example.
_columns = {
'partner_id': fields.many2one('res.partner', 'Partner', domain=[('name', '=', 'greywind')])
}
So when you click on the partner_id field on the web client. it will run a search method & execute a query like
select id from res_partner where name='greywind';
and you can see only partner with name greywind.
Domains are tuples, the structure is (field, operator, value).
Field is the data in the database, Operator is the comparison, = equal, != not equal, > greater than, < less than, etc. Value is the data you want to compare with the field, it can be another database field, a constant or a calculated value.

Domains limits possible choices for many2one, many2many and one2many fields to use only objects that satisfies . For example in stock.production.lot
'product_id': fields.many2one('product.product', 'Product', required=True, domain=[('type', '<>', 'service')]),
allows to use only products that are not service. In your code there is no fields related to other objects so there is no application for domains.

Related

How to add sql constrain of date only from field datetime odoo 10?

How to add sql constrain of date only from field datetime
date = fields.Datetime('Date', store=True, default=fields.Datetime.now,
)
In this case, you don't need sql restrictions. A better option is to extend the field and change its data type to Date:
class NewClass(models.Model):
_inherit = "original.class"
...
date = fields.Date('Date', store=True, default=fields.Date.today())
If you don't want to do this, use instead the constraints decorator over your field:
#api.constrains('date')
def check_data_type(self):
if not condition:
raise ValidationError("Error!")
In any case, if you still want to add a sql constraints you can use this in your model:
class YourClass(models.Model):
_name = "your.class"
...
_sql_constraints = [('date', 'CHECK (your check)', 'Data no pass the check')]
I hope this helps!

how to get current record id using onchange for one2many in odoo 10?

I have tried below code for onchange function but return some unreadable code
class sales_targets(models.Model):
_name = 'sale.target'
category = fields.Selection([
('normal', 'Product'), ('cloud', 'Cloud EYE'), ('tech', 'Technical Support Group'), ('db', 'Database'),
('odoo', 'Odoo'), ('can', 'CAN'), ('tod', 'TOD'), ('rental', 'Rental'), ('tec', 'TEC'), ('top', 'TOP'),
('tor', 'TOR'), ('tos', 'TOS'),
('aws', 'AWS')], 'Category', default='normal',
help="A category of the view type is a virtual category that can be used as the parent of another category to create a hierarchical structure.")
team_ids=fields.Many2many('crm.team','team_target_rel','target_ids','team_id','Sales Team')
from_date=fields.Date('Budget From Date')
to_date = fields.Date('Budget To Date')
no_call=fields.Float('No of Calls')
target_line=fields.One2many('target.line','target_id','Target Line', copy=True)
#api.multi
#api.onchange('team_ids')
def _onchange_tem_salesperson(self):
print ".....",self.id,self._origin
above code onchange function result is
...... <odoo.models.NewId object at 0x7f72aff2b290> sale.target()
In onchange event odoo create a dummy record for you.
In order to get the id, odoo passes the record in origin property.
self._origin.id. # keep in mind in create id is instance of NewId object Not integer
I'm not sure if it's self. _origin or self.origin but i'm sure that it's in origin because i used it before. Hope it helped you
thanks for you advice and then finally got solution for this page How to pass value with onchange one2many variable in odoo? please up vote my question if my question is worth

get data from table and from relative foreign tables in SQL

Hi have a text search input that looks for matching records in the DB and gets all the data from a table:
let's say like this:
$q = Input::get('items');
$q = "\"" . "($q)" . "\"";
$items = DB::table('my_items')->whereRaw(
'MATCH(item_name) AGAINST(? IN BOOLEAN MODE)',
array($q)
)->get();
So I get all the items in the DB from my textsearch, then I send the result as json to some script that updates my page with the items:
return Response()->json($items);
The relations are:
My_item:
public function brand(){
return $this->hasOne('App\Brand', 'id', 'brand_id');
}
Brand:
public function My_item(){
return $this->belongsToMany('App\My_item');
}
Now the problem here is that in 'my_items' table I have some data as IDs that reference foreign tables.
For example I will have a 'brand_id' that for example references a 'brands' table where I can have information regarding the brand.
So for example I could have brand_id = 3 that means 'Microsoft' in my brands table (id = 3, name = microsoft).
Now what I need to do is not only passing the brand_id to my view but also the actual information (name), in this case Microsoft so that I can put that info in the item description.
But, how can I get that information before sending with that query? Is there some sort of flag I can use in the query like $items = DB::table bla bla with foreign?
this way works, DB:: method is dropped for:
$items = My_item::with('brand')->where('item_name', 'LIKE', "%$q%")->get();
this one doesn't:
DB::table('my_items')::with('brand')->where('item_name', 'LIKE', "%$q%")->get();
First of all, you can simplify your search query to something like this:
My_item::where('item_name', 'LIKE', "%$q%")->get();
Now, assign relations the relation to your other tables in your Models. Then you can get all information using the following syntax:
My_item::with('brand')->where('item_name', 'LIKE', "%$q%")->get();
Read more about relations here: https://laravel.com/docs/5.1/eloquent-relationships

Setting group_by in specialized query

I need to perform data smoothing using averaging, with a non-standard group_by variable that is created on-the-fly. My model consists of two tables:
class WthrStn(models.Model):
name=models.CharField(max_length=64, error_messages=MOD_ERR_MSGS)
owner_email=models.EmailField('Contact email')
location_city=models.CharField(max_length=32, blank=True)
location_state=models.CharField(max_length=32, blank=True)
...
class WthrData(models.Model):
stn=models.ForeignKey(WthrStn)
date=models.DateField()
time=models.TimeField()
temptr_out=models.DecimalField(max_digits=5, decimal_places=2)
temptr_in=models.DecimalField(max_digits=5, decimal_places=2)
class Meta:
ordering = ['-date','-time']
unique_together = (("date", "time", "stn"),)
The data in WthrData table are entered from an xml file in variable time increments, currently 15 or 30 minutes, but that could vary and change over time. There are >20000 records in that table. I want to provide an option to display the data smoothed to variable time units, e.g. 30 minutes, 1, 2 or N hours (60, 120, 180, etc minutes)
I am using SQLIte3 as the DB engine. I tested the following sql, which proved quite adequate to perform the smoothing in 'bins' of N-minutes duration:
select id, date, time, 24*60*julianday(datetime(date || time))/N jsec, avg(temptr_out)
as temptr_out, avg(temptr_in) as temptr_in, avg(barom_mmhg) as barom_mmhg,
avg(wind_mph) as wind_mph, avg(wind_dir) as wind_dir, avg(humid_pct) as humid_pct,
avg(rain_in) as rain_in, avg(rain_rate) as rain_rate,
datetime(avg(julianday(datetime(date || time)))) as avg_date from wthr_wthrdata where
stn_id=19 group by round(jsec,0) order by stn_id,date,time;
Note I create an output variable 'jsec' using the SQLite3 function 'julianday', which returns number of days in the integer part and fraction of day in the decimal part. So, multiplying by 24*60 gives me number of minutes. Dividing by N-minute resolution gives me a nice 'group by' variable, compensating for varying time increments of the raw data.
How can I implement this in Django? I have tried the objects.raw(), but that returns a RawQuerySet, not a QuerySet to the view, so I get error messages from the html template:
</p>
Number of data entries: {{ valid_form|length }}
</p>
I have tried using a standard Query, with code like this:
wthrdta=WthrData.objects.all()
wthrdta.extra(select={'jsec':'24*60*julianday(datetime(date || time))/{}'.format(n)})
wthrdta.extra(select = {'temptr_out':'avg(temptr_out)',
'temptr_in':'avg(temptr_in)',
'barom_mmhg':'avg(barom_mmhg)',
'wind_mph':'avg(wind_mph)',
'wind_dir':'avg(wind_dir)',
'humid_pct':'avg(humid_pct)',
'rain_in':'avg(rain_in)',
'rain_sum_in':'sum(rain_in)',
'rain_rate':'avg(rain_rate)',
'avg_date':'datetime(avg(julianday(datetime(date || time))))'})
Note that here I use the sql-avg functions instead of using the django aggregate() or annotate(). This seems to generate correct sql code, but I cant seem to get the group_by set properly to my jsec data that is created at the top.
Any suggestions for how to approach this? All I really need is to have the QuerySet.raw() method return a QuerySet, or something that can be converted to a QuerySet instead of RawQuerySet. I can not find an easy way to do that.
The answer to this turns out to be really simple, using a hint I found from
[https://gist.github.com/carymrobbins/8477219][1]
though I modified his code slightly. To return a QuerySet from a RawQuerySet, all I did was add to my models.py file, right above the WthrData class definition:
class MyManager(models.Manager):
def raw_as_qs(self, raw_query, params=()):
"""Execute a raw query and return a QuerySet. The first column in the
result set must be the id field for the model.
:type raw_query: str | unicode
:type params: tuple[T] | dict[str | unicode, T]
:rtype: django.db.models.query.QuerySet
"""
cursor = connection.cursor()
try:
cursor.execute(raw_query, params)
return self.filter(id__in=(x[0] for x in cursor))
finally:
cursor.close()
Then in my class definition for WthrData:
class WthrData(models.Model):
objects=MyManager()
......
and later in the WthrData class:
def get_smoothWthrData(stn_id,n):
sqlcode='select id, date, time, 24*60*julianday(datetime(date || time))/%s jsec, avg(temptr_out) as temptr_out, avg(temptr_in) as temptr_in, avg(barom_mmhg) as barom_mmhg, avg(wind_mph) as wind_mph, avg(wind_dir) as wind_dir, avg(humid_pct) as humid_pct, avg(rain_in) as rain_in, avg(rain_rate) as rain_rate, datetime(avg(julianday(datetime(date || time)))) as avg_date from wthr_wthrdata where stn_id=%s group by round(jsec,0) order by stn_id,date,time;'
return WthrData.objects.raw_as_qs(sqlcode,[n,stn_id]);
This allows me to grab results from the highly populated WthrData table smoothed over time increments, and the results come back as a QuerySet instead of RawQuerySet

How to get the Database Id from an XML Id

The osv.osv provides a get_xml_id method to find the XML Id for the provided Database Id.
What is the best way to do the opposite?
Knowing the XML Id (it was defined in the data loading file), how can I get the corresponding Database Id, so that I can refer to it in tour Python code?
The ir.model.data model also has a get_object() method returning a browsable record given a model name and an xml_id.
So, another solution could be:
m = self.pool.get('ir.model.data')
id = m.get_object(cr, uid, 'base', 'user_root').id
The ir_model_data object has a _get_id() method that does what you're looking for. You can see it in use in the res_users._get_admin_id() method:
def _get_admin_id(self, cr):
if self.__admin_ids.get(cr.dbname) is None:
ir_model_data_obj = self.pool.get('ir.model.data')
mdid = ir_model_data_obj._get_id(cr, 1, 'base', 'user_root')
self.__admin_ids[cr.dbname] = ir_model_data_obj.read(cr, 1, [mdid], ['res_id'])[0]['res_id']
return self.__admin_ids[cr.dbname]