Use a model's field as an identifier - orm

I have the following model in OpenERP 7. How to indicate that the isbn field should be the primary key.
from osv import osv, fields
class Book(osv.Model):
""" A book """
_name = 'helloworld.book'
_columns = {
'isbn' : fields.char('ISBN', size=9, requried=True),
'title' : fields.char('Title', size=100, required=True),
'genre' : fields.char('Genre', size=20, required=True),
}

A primary key is a special relational database table column (or combination of columns) designated to uniquely identify all table records.
A primary key’s main features are:
It must contain a unique value for each row of data.
It cannot contain null values.
A primary key is either an existing table column or a column that is specifically generated by the database according to a defined sequence.
OpenERP Supports it by Keeping unique sql constraint on field.
_sql_constraints = [
('my_key_value', 'unique(key_value1,key_value2)', 'key value has to be unique !')
]
In your case, As you have chosen Char type of Field, Set sql constraint like this.Add this to your class. and restart the server and check again. You will find primary key's functionality on 'isbn' field.
_sql_constraints = [
('isbn_uniq', 'unique(isbn)', 'ISBN must be unique!'),
]
For case insensitive constraints,
def _check_unique_insesitive(self, cr, uid, ids, context=None):
sr_ids = self.search(cr, uid ,[], context=context)
lst = [x.ibsn.lower() for x in self.browse(cr, uid, sr_ids, context=context) if x.ibsn]
for self_obj in self.browse(cr, uid, ids, context=context):
if self_obj.ibsn and self_obj.ibsn.lower() in lst:
return False
return True
_constraints = [(_check_unique_insesitive, 'Error: ISBN must be unique!', ['ibsn'])]
Hope this will help you. :)

Related

How to add custom field value in Odoo Invoice sequence in Odoo 9

I was trying to add custom field into Invoice number sequence.
So the field I added was a many2one field or selection field whose value needs to be appended to the Invoice sequence.
The field is in account.invoice class
seq_pat = fields.Many2one('account.sequence.new','Sequence Pattern')
Other way I was trying is by overriding ir.sequence class method which creates the legends in sequences.
class ir_sequence(osv.osv):
_inherit = 'ir.sequence'
def _interpolation_dict_context(self, context=None):
if context is None:
context = {}
test1 = self.pool.get('account.invoice').browse()
test = test1.seq_pat.name
t = datetime.now(pytz.timezone(context.get('tz') or 'UTC'))
sequences = {
'year': '%Y', 'month': '%m', 'day': '%d', 'y': '%y', 'doy': '%j', 'woy': '%W',
'weekday': '%w', 'h24': '%H', 'h12': '%I', 'min': '%M', 'sec': '%S',
'pattern': '%P'
}
return {key: t.strftime(sequence) for key, sequence in sequences.iteritems()}
which succeeded in making it to the legends section of Odoo.
But I am stuck with how to get my field recognised by ir.sequence.
Anyone with any other idea to achieve this would be really helpful.

Custom field default value - populate with other entries from same field

I have created a custom module with extra fields on the product screen. I am trying to have the default value be a drop down with all of the entries already submitted to that field or the option to create a new entry (same as the default value when adding a product to a BOM).
class product_part_detail(osv.osv):
_inherit = 'product.template'
_columns = {
'x_mfrname1': fields.char('P/N'),
}
_defaults ={
'x_mfrname1': get_default_name,
}
def get_default_name(self):
return "test"
I tried creating a many2one field that refers to a field in a different table but I keep getting an error when trying to install the module. Below is the updated code that I am having issues with. Thanks in advance!
class product_part_detail(osv.osv):
_inherit = 'product.template'
_name = 'product.part.detail'
_columns = {
'x_mfrname1': fields.many2one('product.part.detail.fill', 'x_mfrname1id'),
'x_mfrname2': fields.many2one('product.part.detail.fill', 'x_mfrname1id'),
}
class product_part_detail_fill(osv.osv):
_name = 'product.part.detail.fill'
def _sel_func(self, cr, uid, context=None):
obj = self.pool.get('product.part.detail')
ids = obj.search(cr, uid, [])
res = obj.read(cr, uid, ids, ['x_mfrname1', 'x_mfrname2'], context)
res = [(r['x_mfrname1'], r['x_mfrname2']) for r in res]
return res
_columns = {
'x_mfrname1id': fields.one2many('product.part.detail', 'x_mfrname1', 'x_mfrname2', selection=_sel_func),
}
A couple of things. The idea of a drop down of the values they have previously entered requires a many2one field. You would create another model and then make x_mfrname1 a many2one to that table. As long as the user has create access on that table they will get a create option on the drop down to key new values.
One other item, as you are using the pre-8 API, the method signature of your default method should be:
def get_default_name(self, cr, uid, context=None):

Openerp get partner category tags

I have 2 fields in my custom module:
'originator_id' : fields.many2one("res.partner",string="Originator", required=True),
'originator_category_ids' : fields.many2many('res.partner.category',
'module_category_rel',
'module_id',
'category_id',
'Categories'),
I want to set the domain for the many2many field "originator_category_ids" according to the selected "originator_id" which is a partner_id. I wrote an onchange method to define the domain dynamically:
def get_domain_originator_category_ids(self,cr,uid,ids,originator_id,context=None):
if originator_id:
obj = self.pool.get('res.partner').browse(cr, uid, originator_id)
return {'domain':{'originator_category_ids':[('id','in',obj.category_id)]}}
But above doesn't work.
Your support will be much appreciated.
This is worked for me, but it is a temporary solution until I find a better one. The solution consist on looping on categories and compare with the selected partner in the partner_ids field:
def get_domain_originator_category_ids(self,cr,uid,ids,originator_id,context=None):
category_obj = self.pool.get('res.partner.category')
category_ids = category_obj.search(cr, uid,[], context=context)
res=[]
for cateory in category_obj.browse(cr, uid, category_ids, context=context):
for partner_id in cateory.partner_ids:
if partner_id.id == originator_id:
res.append(cateory.id)
return {'domain':{'originator_category_ids':[('id','in',res)]}}
If you get a better solution please post it.

One module field use to other module in openerp

I created a field name "link to opportunities" :-
module :- hr.applicant
field type:- many2many
object relation:- crm.lead
and i used in crm.lead module .
Now i want to use this field in "hr.recruitment" .
but i have tried many ways but not success. please tell me. how can use this field in other module like as crm.lead to hr.recruitment
thank you for your timing.
this code i used:-
'sale_o_ids' : fields.related('job_id', 'x_link_to_jobposition',
readonly=True,
relation='crm.lead',
string='Opportunity Name'),
Here is the example:
of many2many
class hr_job(osv.osv):
_inherit = 'hr.job'
_columns = {
'sale_ids': fields.many2many('sale.order', 'hr_job_sale_order_rel', 'job_id', 'sale_id', 'Sale order'),
}
hr_job()
Here created a many2many field of sale.order
Now i want to used the hr.job field in hr.employee.
class hr_employee(osv.osv):
_inherit = "hr.employee"
def _get_sale_order(self, cr, uid, ids, field_name, arg, context=None):
if context is None:
context = {}
result = {}
list_o = []
for order in self.browse(cr, uid, ids, context=context):
for i in order.job_id.sale_ids:
list_o.append(i.id)
result[order.id] = list_o
return result
_columns = {
'sale_order_ids': fields.function(_get_sale_order, type='many2many', relation="sale.order", string="Sale Orders"),
}
hr_employee()
So when you update in the hr.job many2many field then its updated value show in hr.employee object when in job select this job
Another method you can use related
'sale_o_ids' : fields.related('job_id', 'sale_ids',
type='many2many',
readonly=True,
relation='sale.order',
string='Available Sale Order'),
Hope this thing clear to you

django-grappelli Autocomplete Lookups with multiple foreign key fields

I have a model with two fields that are foreign keys to other models.
class Homepage(models.Model):
featured_user = models.ForeignKey('auth.user')
featured_story = models.ForeignKey('site_stories.story')
#staticmethod
def autocomplete_search_fields():
return ("featured_user__icontains", "featured_story__icontains",) # Is this right?
class HomepageAdmin(admin.ModelAdmin):
raw_id_fields = ('featured_user', 'featured_story',)
autocomplete_lookup_fields = {
'fk': ['featured_user'],
'fk': ['featured_story'] # <====== What should this be???
}
admin.site.register(Homepage, HomepageAdmin)
After reading the admin docs and trying a few things, it became clear that you literally need to use the label "fk" for grappelli to apply the autocomplete lookup formatting to a field. So... how can I do this with this model, where there are multiple foreign key fields?
class HomepageAdmin(admin.ModelAdmin):
raw_id_fields = ('featured_user', 'featured_story',)
autocomplete_lookup_fields = {
'fk': ['featured_user','featured_story'],
}