Odoo 10 - Search method - python

I don't understand why here it works :
# Fonction qui récupère la valeur du champs booléen inscription de l'année précédente
#api.depends('half_pension')
def _retrieve_halfpension_previous(self):
records = self.env['ecole.partner.school'].search([])
for record in records:
record.half_pension_previous = record.half_pension
And here, i have a error expected singleton:
# Fonction qui récupère la valeur du champs booléen inscription de l'année précédente
#api.depends('half_pension')
def _retrieve_halfpension_previous(self):
records = self.env['ecole.partner.school'].search([('id', '<', self.id)])
for record in records:
record.half_pension_previous = record.half_pension
Why ?
Thanks You

The error is because you are using self.id where self is a recordset containing more than one value. Normally to solve it you need to iterate the recordset in self to access every record field like this:
#api.depends('half_pension')
def _retrieve_halfpension_previous(self):
for rec in self:
records = self.env['ecole.partner.school'].search([('id', '<', rec.id)])
for record in records:
record.half_pension_previous = record.half_pension
But in this case it will be ok to find the max id of the records in self to use it in just one search, like:
#api.depends('half_pension')
def _retrieve_halfpension_previous(self):
max_id = max([rec.id for rec in self])
records = self.env['ecole.partner.school'].search([('id', '<', max_id)])
for record in records:
record.half_pension_previous = record.half_pension

Related

Odoo, Many2One field domain not working when editing a record

In my odoo module I have a internal_division model and a cover model. Every internal divisiom has a cover (Many2One field) and a cover can be a forest ('is_forest' boolean field) . Internal division also has a with_forest_cover boolean field. Every time the 'with_forest_cover' changes to True, the cover_id field must change its domain to those having 'is_forest'=True, and the other way around. I was trying to do it using:
cover_id = fields.Many2one('cusaf.cover', string='Cobertura',domain="[('is_forest', '=', with_forest_cover)]")
But for some reson this is only working when creating a new internal_division. When I edit an existing internal division and select / deselect the 'with_forest_cover' check box, the cover_id field is not changing its domain. This is only happening when editing an existed internal division. Why is this happening. I am working with odoo v14
Here is my code
class InternalDivision(models.Model):
_name = 'cusaf.internal_division'
_description = 'División interna'
_inherit = ['mail.thread', 'mail.activity.mixin']
name = fields.Char(string='Identificador externo', required=True)
_sql_constraints = [
('name_uniq', 'unique (name)',
"Error: Ya existe una división interna con el mismo identificador externo") ]
with_forest_cover = fields.Boolean(string='Área con cobertura de bosques naturales', default=False)
cover_id = fields.Many2one('cusaf.cover', string='Cobertura',domain="[('is_forest', '=', with_forest_cover)]")
cover_other = fields.Char(string='Otra cobertura')
cover_name = fields.Char(string='', related="cover_id.name")
#api.onchange('with_forest_cover')
def _with_forest_cover_onchange(self):
self.cover_id=None
class Cover(models.Model):
_name = 'cusaf.cover'
_description = 'Tipo de cobertura'
name = fields.Char(string='Nombre', required=True)
_sql_constraints = [
('name_uniq', 'unique (name)',
"Error: Ya existe un tipo de cobertura con el mismo nombre")
]
description = fields.Text(string='Descripción')
is_forest = fields.Boolean(string='Es bosque')
You won't be able to access to the with_forest_cover value inside cover_id domain, 'cause your class is instantiated before the client, in that time there aren't values. You have 1 easy, 1 intermediate and 1 elevated(not worth the effort) solutions:
Important: Delete domain for cover_id in .py
Easy: Domain in XML. Be sure with_forest_cover is declared in the XML.
<field name="cover_id" domain="[('is_forest', '=', with_forest_cover)]"/>
Intermediate: take advantage of your with_forest_cover onchange to retrieve a domain for cover_id dynamically
#api.onchange('with_forest_cover')
def _with_forest_cover_onchange(self):
return {
'value': {'cover_id': False},
'domain': {'cover_id': [('is_forest', '=', self.with_forest_cover)]}
}
I hope this could be helpful for you.

Delete a string phrase from a data frame column and replace it python

So, I have two dataframes. the first dataframe is dataset conatians several columns, what i will use in this dataframe is the dataset['text_msg'], this columns contains text data.
The second Dataframe sentences_to_exclude contains the data which type is text type.
The column that i will use in this dataframe is sentences_to_exclude['sentences'].
What i need to do is to verify if there are sentences from sentences_to_exclude['sentences'] in the first dataframe and remove the whole sentence.
I have tried a function but it didn't work for me: Here is the function i've used ==>
def remove_words(data):
words_to_remove = sentences_to_exclude['sentences'].lower().split(" ")
text_body = dataset['text_msg']
for word in words_to_remove:
text_body = text_body.replace(word,'' )
return text_body
Here's an exemple of sentences_to_exclude['sentences']
pour un traitement optimal de votre demande, veuillez indiquer les informations ci-dessous
and for the fisrt data frame here's an example of the dataset['text_msg']:
pour un traitement optimal de votre incident, nous vous prions de renseigner les informations ci-dessous : - code transaction : - numero de facture / commande client : - criteres dexecution et message derreur (a attacher en pj) description detaillee de votre demande
Hope that my request is clear
Thank you for help in advance
Example Data
sentences = ['code transaction', 'Pour un traitement efficace']
text = [ ' i should delete code transaction ', ' i am trying to delete Pour un traitement efficace only from this sentence ' ]
df1 = pd.DataFrame({'Sentences ': sentences })
df2 = pd.DataFrame({'Text': text})
Still don't understand your question correctly, I will try to help you, but please next time you have to include example data.
To answer your question I will give example dataset and explain how to remove words or sentences from other text:
# This is our example data
sentences = ['code transaction', 'Pour un traitement efficace']
text = [ ' i should delete code transaction ', ' i am trying to delete Pour un traitement efficace only from this sentence ' ]
df1 = pd.DataFrame({'Sentences': sentences})
df2 = pd.DataFrame({'Text': text})
# df1
Sentences
0 code transaction
1 Pour un traitement efficace
# df2
Text
0 i should delete code transaction
1 i am trying to delete Pour un traitement effi...
Next we want to harmonize our data so we wont have mismatches, so we convert to uppercase:
df1['Sentences'] = df1.Sentences.str.upper()
df2['Text'] = df2.Text.str.upper()
Sentences
0 CODE TRANSACTION
1 POUR UN TRAITEMENT EFFICACE
Text
0 I SHOULD DELETE CODE TRANSACTION
1 I AM TRYING TO DELETE POUR UN TRAITEMENT EFFI...
Now our data is in the right format, we can remove the text from one dataset to another
df2['Text_cleaned'] = df2.Text.str.replace('|'.join(df1.Words), '')
Text Text_cleaned
0 I SHOULD DELETE CODE TRANSACTION I SHOULD DELETE
1 I AM TRYING TO DELETE POUR UN TRAITEMENT EFFI... I AM TRYING TO DELETE ONLY FROM THIS SENTENCE
What does '|'.join(df1.Sentences) do?
It returns a string delimited by |
'|'.join(df1.Words)
'CODE TRANSACTION|POUR UN TRAITEMENT EFFICACE'
Hope this helps you and answers your question.
You can now apply this logic to your own data.

Odoo V10 - Active records

I want to retrieve the active records in a function.
Here is my code:
def no_duplicate_school_dates(self):
if self.school_registration or self.school_end_date:
print "Je commence ma fonction"
# Récupérer les enregistrement actifs
records = self.env['ecole.partner.school'].search([])
for rec in records:
if rec.school_registration and rec.school_end_date:
if (self.school_registration >= rec.school_registration and self.school_registration <= rec.school_end_date)\
or (self.school_end_date >= rec.school_registration and self.school_end_date <= rec.school_end_date) :
print "doublon trouvé"
# raise ValidationError("Erreur : La plage de date en chevauche une autre")
else:
print "Pas de doublon trouvé"
What should I put on this line?
records = self.env['ecole.partner.school'].search([])
Thanks you
EDIT : In my model "ecole.partner.school", I have a relation fields.
class ResPartner(models.Model):
_inherit = 'res.partner'
scholarship_ids = fields.One2many(string='School card', comodel_name='ecole.partner.school',
inverse_name='partner_id')
I would like the records to be linked to the same partner. A partner can be registered several times in a school at different dates. And I'm trying to recover only the records of the same partner. I will put more information in my question

Error while validating constraint odoo

I get this error and I don't know how to solve it:
My code:
#api.constrains('num_dossier')
def identify_same_num(self):
for record in self:
obj = self.search([('num_dossier','=',record.num_dossier),('arrondissement_id','=',record.arrondissement_id.id)])
if obj:
raise except_orm('Erreur')
For the database :
_sql_constraints = [
('number_uniq', 'unique(number, company_id, journal_id, type)','Numéro de facture doit etre unique par company!'),
('num_dossier_uniq', 'unique(num_dossier,arrondissement_id)', 'Numéro de dossier doit etre unique par Arrondissement')
]

Search value in model object and if exists

I having a lot of problem with something I'm sure is pretty easy, but not for me.
I have 2 Models:
VipPassesModel
ProfileModel
Then I've this view, wich purpose is perform the following task (in this order):
Search if the "VIP Code" exists in the "VipPassesModel"
If "VIP Code" exists check if as some User (Profile Model - Foreing Key) asigned to it
If there's no user asigned to that VIP Code, then SAVE the current User logued (Id - Foreign Key) in that VIP Code (this will make this Vip Code no longer available)
My VipPassesModel:
class VipPassesModel(models.Model):
"""
VIP Passes Code Model.
"""
code = models.CharField(max_length = 15)
is_used = models.BooleanField(default=False)
user_asigned = models.ForeignKey(ProfileModel, related_name='profile_name', verbose_name="User Full Name", blank=True, null=True,)
My View.py
def vipcodevalidation(request):
"""
Funcion que recibe el CODE VIP y si es valido, lo asigna al usuario actual
"""
if request.method == 'POST':
form = VipPassesForm(data=request.POST)
if form.is_valid():
vipcode = form.cleaned_data['code']
user_to_asign = request.user
if VipPassesModel.objects.filter(code = vipcode).exists():
# Tomar el objeto y grabarle en "user_asigned" el id del usuario de django logueado actualmente (user_to_asign)
else:
#nada que hacer aqui
else:
form = VipPassesForm()
return render(request,'vipcode.html',{'form':form},context_instance=RequestContext(request))
I'll apreciate any help from you guys. Just to be clear, I'm not getting error messages, just I don't know how to deal with this.
Your view should be:
if VipPassesModel.objects.filter(code = vipcode): #If there is object with that code
vipObject = VipPassesModel.objects.filter(code = vipcode)[0] # Get the object
if not vipObject.user_assigned: #If object doesn't have user
vipObject.user_assigned = request.user.id # Assign actual user
vipObject.save() # Save object
else:
#nada que hacer aqui
When you do if VipPassesModel.objects.filter(code = vipcode): if there is no objects, you get [](empty list) so, if you do if [] it returns false, because the list is empty, if there is one model with tat code, it returns the object like [VipPassesModel] so to access to it you need to do VipPassesModel.objects.filter(code = vipcode)[0]
(la documentación de Django oficial sobre este tipo de querys está bastante bien, te recomiendo que le eches un ojo a Django Queries )
THANK YOU SO MUCH GUYS!... You're the best... I need more friends like you.
This is the final View Code:
def vipcodevalidation(request):
"""
Funcion que recibe el CODE VIP y si es valido, lo asigna al usuario actual
"""
if request.method == 'POST':
form = VipPassesForm(data=request.POST)
if form.is_valid():
vipcode = form.cleaned_data['code']
user_to_asign = request.user.id
if VipPassesModel.objects.filter(code = vipcode):
vipObject = VipPassesModel.objects.filter(code = vipcode)[0] # Get the object
if not vipObject.user_asigned: #If object doesn't have user
vipObject.user_asigned = ProfileModel.objects.get(pk = user_to_asign) # Assign actual user
vipObject.save() # Save object
# VIP Code encontrado y User Asignado.
else:
# VIP Code encontrado pero ya tiene un User Asignado.
else:
#VIP Code no encontrado o ya tiene un User Asignado
else:
form = VipPassesForm()
return render(request,'vipcode.html',{'form':form},context_instance=RequestContext(request))
Simplistically this is what you can do
try:
vipobj = VipPassesModel.objects.filter(code = vipcode, user_asigned = NULL)[0]
except IndexError:
#no vip code free to assign bail out
vipobj.user_assigned = user_to_asign
vipobj.save()
In real production level code, you should make these in a transaction sol that 2 requests from different user does not clash. 2nd request may override assignment by 1st request.

Categories

Resources