Odoo 8 - How to update a Many2one field value? - python-2.7

I'm trying to make module that gives employees visa balance.
What I'm trying to do is that when a visa number is assigned to an employee it changes the counter used_visa to be increased by 1.
so my question is how to update the counter which is in 'visa.balance.line' model when a visa number is selected in 'hr.employee' model
Here's my code:
class hr_visa_balance(models.Model):
_name = "hr.visa.balance"
_rec_name = "visa_no"
visa_no = fields.Char("Visa Number")
approval_date = fields.Date('Approval Date')
visa_line_ids = fields.One2many('visa.balance.line', 'visa_line_id', 'Visa Balance Details')
class visa_balance_line(models.Model):
_name = 'visa.balance.line'
_rec_name = "visa_line_id"
profession = fields.Char()
gender = fields.Selection([('m','Male'),('f','Female')], 'Gender')
country_id = fields.Many2one('res.country', 'Nationality')
available_visa = fields.Integer('Available')
used_visa = fields.Integer('Used')
visa_line_id = fields.Many2one('hr.visa.balance', 'Visa Balance Details')
class hr_employee(models.Model):
_inherit = 'hr.employee',
visa_line = fields.Many2one('visa.balance.line', 'Visa Balance Details')
#api.onchange('visa_line')
def onchange_visa_no(self):
~ code here ~

First of all i am not getting your structure,
i think in employee you have to choose many2one of "hr.visa.balance" object,
and you are choosing "visa.balance.line"
now what you have to do:
give one many2one of hr.visa.balance" in hr.employee and on on_change of visa_no you have to write logic,
Note: you directly can count visa balance in "hr.visa.balance" this object.
no need to take this field in visa.balance.line.

Related

Django Update Multiple Object error

i found some problem when i try to update multiple object in my models. here is my models:
class NumberSequence(models.Model):
code = models.CharField(max_length=12)
name = models.CharField(max_length=60)
prefix = models.CharField(max_length=3)
length = models.IntegerField()
last = models.IntegerField(verbose_name='Last Number Used')
def getNumberSequence():
ns = NumberSequence.objects.filter(code='REQ')
letter = ns[0].prefix
lastNumber = ns[0].last+1
l = '{0}-{1:0'+str(ns[0].length)+'d}'
for num in ns:
num.last = lastNumber
num.save()
return l.format(letter,lastNumber+1)
class Requisitions(models.Model):
number = models.CharField(max_length=20, default=getNumberSequence())
transDate = models.DateField(verbose_name='Date')
businessUnit = models.ForeignKey(BusinessUnit, verbose_name='Unit')
division = models.ForeignKey(Division, verbose_name='Division')
remarks = models.TextField
status = models.IntegerField(verbose_name='Status')
when i create new record in Requisition, the table Number Sequence does not update. but if i restart the service, the number sequence table updated automatically.
what's happened with my code?
any suggestion, please..
You should not call the default function in your field definition, but pass the callable only without parentheses.
number = models.CharField(max_length=20, default=getNumberSequence)

Computed fields Odoo9

I'm creating a module for student management in "Odoo9", in a part of that module I want to compute the average mark that a student get in a subject like "maths".I'm tryingto achieve that using this code, but I have a problem computing the "Avg-Maths" immediately after filling "Maths-1" and "Maths-2", it can only be computed after saving the student profile.Can someone help me please realizing the issue here? and how can I fix this?
#student class
class student_student(models.Model):
'
'
'
result_ids = fields.One2many("schoolresults.detail", "student_id", "School Results")
'
'
'
class schoolresults_detail(models.Model):
_name = "schoolresults.detail"
_description = "Student's results."
student_id = fields.Many2one("student.student", "Student", ondelete="cascade")
subject_id = fields.Many2one("schoolresults.subject", "Subject")
result_manual = fields.Float("Result")
result = fields.Float(compute='_compute_value',store=True)
manual = fields.Boolean(compute='_is_manual', default=False)
#api.one
#api.depends('manual')
def _is_manual(self):
self.manual = self.subject_id.my_id
#api.one
#api.depends('result_manual','subject_id','subject_id.my_id')
def _compute_value(self):
self.ensure_one()
results = self.env['schoolresults.detail'].search([])
total = 0
for data in results:
total += data.result_manual
for data in results:
#if the subject is the average of others
if data.subject_id.my_id:
data.result = total
class schoolresults_subject(models.Model):
_name = "schoolresults.subject"
_description = "Student's subjects."
my_id = fields.Integer(default=0)
name = fields.Char("Subject")
Add student_id.result_ids.result_manual to your depends list on _compute_value. That should trigger a recomputation.
i think after calculating the value you should assign it to your result field
#api.one
def _compute_method(self):
# compute average for this record
self.result = calclated_value
but i don't see that you assign the value to the result field ?!! sot try to assign it that should do it

Building up subqueries of derived django fields

I have a few transformations I need to perform on my table before I aggregate.
I need to multiply transaction_type (which is either 1 or -1) by amount to yield a signed_amount. Then I need to sum all signed_amounts by primary_category (which is a foreign key to secondary category which is a foreign key of my table).
DEBIT = -1
CREDIT = 1
TRANSACTION_TYPE_CHOICES = (
(DEBIT, 'debit'),
(CREDIT, 'credit'),
)
class Transaction(models.Model):
amount = models.DecimalField(max_digits=7, decimal_places=2)
transaction_type = models.IntegerField(choices=TRANSACTION_TYPE_CHOICES)
secondary_category = models.ForeignKey(Secondary_Category)
class Primary_Category(models.Model):
name = models.CharField("Category Name", max_length=30)
category = models.ForeignKey(Primary_Category_Bucket)
class Secondary_Category(models.Model):
name = models.CharField("Category Name", max_length=30)
primary_category = models.ForeignKey(Primary_Category)
I'm stuck on the first bit though.
from django.db.models import Sum, Count, F
original_transactions = Transaction.objects.all()
original_transactions.signed_amount = F('transaction_type') * F('amount')
for transaction in original_transactions:
print transaction.signed_amount
When I try to sanity check that signed_amount is being calculated, I get an error that 'Transaction' object has no attribute 'signed_amount'. I don't want to save signed_amount to the database. I just want to generate it as derived field so I can calculate my totals.
How do I calculate this derived field and subsequently aggregate by primary_category.name?
User python decorator property on a method for class Transaction:
class Transaction(models.Model):
amount = models.DecimalField(max_digits=7, decimal_places=2)
transaction_type = models.IntegerField(choices=TRANSACTION_TYPE_CHOICES)
secondary_category = models.ForeignKey(Secondary_Category)
#property
def signed_amount(self):
return self.amount * self.transaction_type
Then for each Transaction object you can do transaction.signed_amount.
I'm not sure if the aggregation part could be done using queries, but if you don't have that many PrimaryCategory, then python would be good enough to achieve it.
Or you can do this.
all_transactions = Transaction.objects.all().order_by('secondary_category__primary_category_id')
sum = 0
if all_transactions:
primary_category_id = all_transactions[0].secondary_category.primary_category_id
for transaction in all_transactions:
if primary_category_id == transaction.secondary_category.primary_category_id:
sum += (transaction.amount * transaction_type)
else:
sum = (transaction.amount * transaction_type)
print sum

How can I check that two records contain the same information in 3 specific fields?

What I'm trying to do is put people in random groups, but I dont want anyone with the same first and last name in a group twice as that person can very well be in the database twice (they'd have a different partner)
so I have this code:
(I'll be using this in djnago admin as an action)
Model:
class people(models.Model)
fname = models.CharField()
lname = models.CharField()
group = models.IntegerField()
partner = model.CharField()
View:
N = 4
Num = randint(0, N-1)
for x in queryset:
x.group = Num
(if group == group & fname == fname & lname == lname:)<--Thats the part I am confused about, how can I check to see if these fields are the same, if they are, I want to change the group number field)
x.group = (Num + 1) % N
Consider using Unique Together. Change Your Model as below
class people(models.Model)
fname = models.CharField()
lname = models.CharField()
group = models.IntegerField()
partner = model.CharField()
class Meta:
unique_together = ('fname', 'lname', 'group',)

Using Django Forms: How can i use the chosen value of a forms.ModelChoiceField within a userdef validation

I got the following model:
class currency(models.Model):
currency = models.CharField(max_length=50)
dollaramount = models.DecimalField(max_digits=10, decimal_places=2)
def __unicode__(self):
return self.currency
This Model contains 2 entrys with currency-value "$" and "€"
The currency-model is related with a ModelChoiceField within the following form, which has a userdefined validation "clean_amount" for checking the amount, depending which currency is actual choosen in the currencyfield from the from itself.
How can i do the compare inside the userdef-validation "clean_amount", if the value from the selected object is "$" or "€"?
from django import forms
from currencies.models import currency
class createform(forms.Form):
currency = forms.ModelChoiceField(queryset = currency.objects.all())
amount = forms.DecimalField(initial = 0)
def clean_amount(self):
currencyfield = self.cleaned_data['currency']
amount = self.cleaned_data['amount']
if amount < 0:
raise forms.ValidationError("Amount must be at least 0.")
#HERE I WANT TO CHECK
choosencurrency = currencyfield.??????
if choosencurrency == "$" :
#check $amount
if choosencurrency == "€" :
#check €amount
return amount
You should do this in clean(), not clean_amount(). From clean you can access self.cleaned_data['amount'] and self.cleaned_data['currency'].