I need to change the state of a invoice using it's payment method.
def _payment_type_get(self, cr, uid, ids, field_name, arg, context={}):
result = {}
invoice_obj = self.pool.get('account.move.line')
for rec in self.browse(cr, uid, ids, context):
result[rec.id] = (0, 0)
invoice_id = invoice_obj.search(cr, uid, [(
'move_id', '=', rec.move_id.id)], context=context)
if invoice_id:
inv = invoice_obj.browse(cr, uid, invoice_id[0], context)
if inv.payment_type:
result[rec.id] = (inv.payment_type.id, self.pool.get(
'payment.type').browse(cr, uid, inv.payment_type.id, context).name)
else:
result[rec.id] = (0, 0)
return result
if result != '1':
return self.write(cr, uid, ids, {'state_cheque': 'usado'})
else:
return self.write(cr, uid, ids, {'state_cheque': 'caixa'})
I need to get the payment type at the creation of the "cheque", during the invoice closing, so I can set it to Caixa, if it's a Cheque or to Usado if it is not. I don't know if all the names are correct, since I copied it from a guy here who said it would(Shame on me if I let it pass).
The Cheque, like any payment is saved at a journal, cheque is saved at an specific journal with it's name(ChequeJournal), if I can use that to create the default state, It would be better.
Every single way I tried to do it, failed. Recently I've found that the payment type is saved as a int and not as a char or string, but changing it still give no results.
I could not use a self.write , since I'm editing the account_move_line.py, OpenERP can't find what I'm trying to add the state to. So, I need to get the invoice ID in order to change that state. A new problem arises?
Once a return statement is called, the function immediately exits, so your last 4 lines aren't being executed. (Or maybe that's a formatting error?)
Related
Please help me to solve this problem,
I have a function which used to check validation terms of the input and I wants to call it inside the "create"function as a nested function. Once I call it in normal way it keeps giving me parameter mismatching error. Please help me.
Inside the create function I call it like this
def create(self, cr, uid, values, context=None):
#There are 219 lines in side the create function but I just showing you the invoke for this particular fucntion.
date_from = values['date_from']
date_to=values['date_to']
sub_nominee= values['sub_nominee']
self.onchange_sub_nominee(self, cr, uid, date_to, date_from,sub_nominee)
return super(hr_holidays, self).create(cr, uid, values, context=context)
Function is like this,
def onchange_sub_nominee(self, cr, uid,ids, date_to, date_from,sub_nominee):
#Employees data
DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S"
from_dt = datetime.datetime.strptime(date_from, DATETIME_FORMAT).date()
to_dt=datetime.datetime.strptime(date_to, DATETIME_FORMAT).date()
sub_name=self.pool.get('hr.employee').browse(cr, uid, sub_nominee).name
hol_obj=self.pool.get('hr.holidays')
#if date_from==date_to:
hol_objs=hol_obj.search(cr, uid, [('employee_id','=',sub_nominee),('type','=','remove'),('state','not in',['draft','refuse'])])
#nominees data
if hol_objs:
for a in hol_obj.browse(cr, uid, hol_objs):
sub_from_dt = a.date_to
sub_to_dt=a.date_from
no_days=a.number_of_days_temp
sub_half_day=a.half_day
sub_half_day_sts=a.half_day_status
f_dt = datetime.datetime.strptime(sub_from_dt, DATETIME_FORMAT).date()
t_dt=datetime.datetime.strptime(sub_to_dt, DATETIME_FORMAT).date()
if ((from_dt==to_dt)and(to_dt==f_dt==t_dt)):
raise osv.except_osv(_('Warning!'),_(' %s already on leave on %s . Please nominate another person 111')%(sub_name,from_dt))
if ((from_dt!=to_dt)) and(no_days<=2):
while from_dt <= to_dt :
new_con=self.search(cr, uid, [('date_from', '<=', date_to), ('date_to', '>=', date_from), ('employee_id', '=', sub_nominee)])
if new_con:
raise osv.except_osv(_('Warning!'),_(' %s has/have already on leave(s) on that period . 55555Please nominate another person')%(sub_name))
from_dt = from_dt + datetime.timedelta(days=1)
if ((f_dt!=t_dt)):
while t_dt <= f_dt:
if (from_dt==t_dt)or(to_dt==t_dt):
raise osv.except_osv(_('Warning!'),_(' %s has/have already on leave(s) on that period . Please nominate another person 2222')%(sub_name))
t_dt=t_dt+datetime.timedelta(days=1)
return True
The error is self explanatory. There is a mismatch in the invoking parameters.
onchange_sub_nominee method accepts parameters
cr, uid, ids, date_to, date_from,sub_nominee
but was invoked as,
self.onchange_sub_nominee(self, cr, uid, date_to, date_from,sub_nominee)
You need to add the value of the parameter id after uid when calling it or remove that parameter from onchange_sub_nominee definition.
How to make functional field editable in Openerp?
When we create
'capname': fields.function(
_convert_capital, string='Display Name', type='char', store=True
),
This will be displayed has read-only and we can't able to edit the text.
How we make this field has editable?
A computed field has a function that automatically calculates it's value on some source data.
It is possible to add it the inverse operation, updating the source data based on a value manually set on it, thus making it editable.
From the documentation:
to allow setting values on a computed field, use the inverse parameter. It is the name of a function reversing the computation and setting the relevant fields:
Example code:
document = fields.Char(compute='_get_document', inverse='_set_document')
def _get_document(self):
for record in self:
with open(record.get_document_path) as f:
record.document = f.read()
def _set_document(self):
for record in self:
if not record.document: continue
with open(record.get_document_path()) as f:
f.write(record.document)
You must add a inverse function to make the field editable. This parameter is called fnct_inv in OpenERP v7. An example:
def _get_test(self, cr, uid, ids, name, args=None, context=None):
result = dict.fromkeys(ids, False)
for line in self.browse(cr, uid, ids, context=context):
if line.test:
result[line.id] = line.test
return result
def _set_test(self, cr, uid, id, field_name, field_value, args=None, context=None):
obj = self.browse(cr, uid, id)
for record in obj:
if record.test != field_value:
# The record already exists
...
cr.execute(
'UPDATE your_table '
'SET test=%s '
'WHERE id=%s', (field_value, id)
)
else:
# It is a new record
# (or the value of the field was not modified)
return True
_columns = {
'test': fields.function(
string='String for testing',
fnct=_get_test,
fnct_inv=_set_test,
type='char',
size=50,
store=True,
),
}
I've been trying to copy over certain fields from the hr_expenses form into my custom module, purchase_orders.
The below method was written for me to do this in the extended hr_expenses.py file:
def po_generator(self, cr, uid, ids, arg, context=None):
res = {}
for expense in self.browse(cr, uid, ids, context=context):
expense_line = self.pool.get('hr.expense.line')
purchase_orders = self.pool.get('purchase.orders')
for line in expense.line_ids:
expense_line_record = expense_line.search(cr, uid, [('id', '=', line.id)], context=context)
# pdb.set_trace()
purchase_orders.create(cr, uid,
{
'submitted_employee_name':expense.employee_id,
'dateofexpense':expense_line.date_value,
'project_id_expense':expense_line.project_id,
'Description':expense_line.name,
'netamount':expense_line.product_exc_VAT,
'raised_employee_name':expense.employee_id,
'project_id_account_type':expense_line.project_id_account_type,
},
context
)
return res
However, when I tru to execute this piece of code, OpenERP gives me an 'AttributeError' with the traceback:
File
"/opt/openerp/custom_modules/legacy_expense_po/legacy_expense.py",
line 121, in po_generator
'dateofexpense':expense_line.date_value, AttributeError: 'hr.expense.line' object has no attribute 'date_value'
I'm presuming this has something to do with the line_ids field in the Expenses form. I'm trying to get each row in the line_ids and enter these as new records in the purchase_orders table.
Thanks.
#Sagar Mohan
You are doing vary basic mistake here.
You are already looping on browse record by saying statement
for line in expense.line_ids:
When you say expense.line_ids this will already pull all related o2m record you don't need to search again by writing statement expense_line_record = expense_line.search(cr, uid, [('id', '=', line.id)], context=context) and you must know that search in v7 return then only integer id of the matching ids not recordset or browse record.
Correct code is :
def po_generator(self, cr, uid, ids, arg, context=None):
res = {}
purchase_orders = self.pool.get('purchase.orders')
for expense in self.browse(cr, uid, ids, context=context):
expense_line = self.pool.get('hr.expense.line')
purchase_orders = self.pool.get('purchase.orders')
for line in expense.line_ids:
purchase_orders.create(cr, uid,
{
'submitted_employee_name':line.employee_id.name,
'dateofexpense': line.date_value,
'project_id_expense': line.project_id.id,
'Description': line.name,
'netamount': line.product_exc_VAT,
'raised_employee_name': expense.employee_id.name,
'project_id_account_type': line.project_id_account_type,
},
context
)
return res
This code might need correction based on your need but you see that line is direct browse variable so you just need to . and access the field.
and one more note here that you never use self.pool.get inside loop that make your code heavy.
Thanks
I am trying to create a function field which will get the current membership type of a member and store it in a new field in res.partner. However this code is not getting called whenever I am creating or editing membership of a member. But if I remove the store attribute the functional field works just as expected. Note that I am reusing the membership module of openerp and using odoo8 now. I am attaching the code, please let me know where am I going wrong. I need this method to be called atleast when I am using the store attribute. Am I using the store attribute incorrectly:
from openerp.osv import osv, fields
class partner_member(osv.Model):
'''Partner'''
_inherit = 'res.partner'
def _get_membership_type(self,cr,uid,ids,context=None):
member_line_obj = self.pool.get('membership.membership_line')
partner_list = []
for line in member_line_obj.browse(cr, uid, ids, context=context):
if line.state == 'paid':
partner_list.append(line.partner.id)
return partner_list
def _current_membership(self, cr, uid, ids, field_name= None, arg=False, context=None):
res_obj = self.pool.get('res.partner')
res_data_obj = res_obj.browse(cr, uid, ids, context=context)
res=dict()
for member in res_data_obj:
if member.member_lines:
for lines in member.member_lines:
if (lines.state == 'paid'):
res[member.id] = lines.membership_id.name_template
break
else:
res[member.id] = 'None'
else:
res[member.id] = 'None'
return res
_columns = {
'current_membership':
fields.function(_current_membership,type='char',
string='Current Membership Type',
store = {
'membership.membership_line':
(_get_membership_type, ['state'], 10)
},
help="Shows the current membership of a user"),
}
You made a mistake on the _get_membership_type() method. Indeed, you return only the list of res.partner that are in a line with state == 'paid'.
I think you must return all the partner that are in lines no matter the state of the line.
def _get_membership_type(self,cr,uid,ids,context=None):
member_line_obj = self.pool.get('membership.membership_line')
partner_list = []
for line in member_line_obj.browse(cr, uid, ids, context=context):
partner_list.append(line.partner.id)
return partner_list
If you want your function _current_membership to be a method of your class (as you did) you need to add the method=True parameter to your field definition:
_columns = {
'current_membership':
fields.function(_current_membership,type='char',
string='Current Membership Type',
store = {
'membership.membership_line':
(_get_membership_type, ['state'], 10)
},
help="Shows the current membership of a user",
method=True),
}
That should resolve your problem.
Certainly you can simply use store=True to have your field recalculated on every change in whatever field of your object.
I have a module that has, a creation date (of course, the day it was created) and a deadline date.
The thing is that I want to be able to set a default value to this deadline date according to the date it was created.
But I want to be able to configurate this dynamically from (lets say) res_config.
e.g.
If I configured the default values in res_config to 5 days, I want the default value for the deadline date to be populated with a date 5 days ahead of the creation date.
Is this possible?
Thank you
I managed to do this using the model ir.configure_parameter.
In res_config.py:
class my_configuration(osv.osv_memory):
_inherit = ['res.confi.settings']
_columns = {
'default_deadline' : fields.integer('Days per default', help="""Help field"""),
}
...
def set_default_deadline(self, cr, uid, ids, context=None):
config = self.browse(cr, uid, ids)
config = config and config[0]
val = '%s' %(config.default_deadline) or '10'
self.pool.geet('ir.config_parameter').set_param(cr,uid, 'key_value', val)
return True
Whit this we have created a system parameter. It is actually created as a mapping from 'key_value' to val that is a string, so we will have to cast it to the desired type when necessary.
In my case, y created a function to get the deadline date in my module:
def _get_deadline_date(self, cr, uid, context=None):
val = self.pool.get('ir.config_parameter').get_param(cr, uid, 'key_value')
try:
val = int(val)
except:
# Just in case...
val = 30
return (datetime.now() + timedelta(days=val)).strftime('%Y,%m,%d')
_defaults = {
'deadline_date': lambda s, cr, uid, c: s._get_deadline_date(self, cr, uid, context=c),
}
Thank you, hope it helps!