Odoo 8 - how to get field values of current active id or current model - odoo

How to access the fields of current form view if it is not yet save or in editing mode?
I tried getting the current active id but I cant get it.
In my .py
#api.one
def _check_butcher(self):
prod_id = self.env.context.get('active_id')
# logging.info("TEST \n TEST %s" % prod_id.can_butcher)
logging.info("TEST \n TEST %s" % prod_id)
return prod_id
In the terminal, it is printed None

I dont work with version 8 so my answer propably won't be most accurate but i think you should look for CRUD in this Documentation https://www.odoo.com/documentation/8.0/ for "default_get()"

Related

How to get the contributors you've coincided editing the most in Wikipedia

I'm doing a gamification web app to help Wikimedia's community health.
I want to find what editors have edited the same pages as 'Jake' the most in the last week or 100 last edits or something like that.
I know my query, but I can't figure out what tables I need because the Wikimedia DB layout is a mess.
So, I want to obtain something like
Username
Occurrences
Pages
Mikey
13
Obama,..
So the query would be something like (I'm accepting suggestions):
Get the pages that the user 'Jake' has edited in the last week.
Get the contributors of that page in last week.
For each of these contributors, get the pages they have edited in the last week and see if they match with the pages 'Jake' has edited and count them.
I've tried doing that something simpler in Pywikibot, but it's very, very slow (20secs for the last 500 contributions of Jake).
I only get the edited pages and get the contributors of that page and just count them and it's very slow.
My pywikibot code is:
site = Site(langcode, 'wikipedia')
user = User(site, username)
contributed_pages = set()
for page, oldid, ts, comment in user.contributions(total=100, namespaces=[0]):
contributed_pages.add(page)
return get_contributor_ocurrences(contributed_pages,site, username)
And the function
def get_contributor_ocurrences(contributed_pages, site,username):
contributors = []
for page in contributed_pages:
for editor in page.contributors():
if APISite.isBot(self= site,username=editor) or editor==username:
continue
contributors.append(editor)
return Counter(contributors)
PS: I have access to DB replicas, which I guess are way faster than Wikimedia API or Pywikibot
You can filter the data to be retrieved with timestamps parameters. This decreases the needed time a lot. Refer the documentation for their usage. Here is a code snippet to get the data with Pywikibot using time stamps:
from collections import Counter
from datetime import timedelta
import pywikibot
from pywikibot.tools import filter_unique
site = pywikibot.Site()
user = pywikibot.User(site, username) # username must be a string
# Setup the Generator for the last 7 days.
# Do not care about the timestamp format if using pywikibot.Timestamp
stamp = pywikibot.Timestamp.now() - timedelta(days=7)
contribs = user.contributions(end=stamp)
contributors= []
# filter_unique is used to remove duplicates.
# The key uses the page title
for page, *_ in filter_unique(contribs, key=lambda x: str(x[0])):
# note: editors is a Counter
editors = page.contributors(endtime=stamp)
print('{:<35}: {}'.format(page.title(), editors))
contributors.extend(editors.elements())
total = Counter(contributors)
This prints a list of pages and for each page it Shows the editors and their contribution counter of the given time range. Finally total should have the same content as your get_contributor_ocurrences functions above.
It requires some additional work to get the table you mentioned above.

Cannot create unbalanced journal entry. Ids: Differences debit - credit Error when trying to create an invoice line

I'm trying to create an invoice line using the Web APIs and XML-RPC (python). I receive this error while creating it.
xmlrpc.client.Fault: <Fault 2: 'Cannot create unbalanced journal entry. Ids: [12083]\nDifferences debit - credit: [-2629.33]'>
I'm creating the invoice line as follows:
inv_line_id = models.execute_kw(
db, uid, password,
'account.move.line',
'create'[
{'move_id':invoice_id,
'product_id':product_id[0]['id'],
'price_unit':product_id[0]['list_price'],
'quantity':sale_line_id[0]['product_uom_qty'],
'account_id':account_id[0]['property_account_income_categ_id'][0]
}
]
)
If i dont add the 'price_unit' the invoice line is being created normally but without a price.
Anyone knows how to fix this ? Thanks in advance
If you are in the same version of me (V13) or if the code is the same in your version. You could pass a value in the context to don't check the balanced.
'check_move_validity' = False
Find in the file account/models/account_move.py . Line 1721 in method write
# Ensure the move is still well balanced.
if 'line_ids' in vals:
if self._context.get('check_move_validity', True):
self._check_balanced()
self.update_lines_tax_exigibility()
During the create or write of an account.move with only invoice_line_ids set and not line_ids, the _move_autocomplete_invoice_lines_create or _move_autocomplete_invoice_lines_write method is called to auto compute accounting lines of the invoice. In that case, accounts will be retrieved and taxes, cash rounding, and payment terms will be computed. In the end, the values will contain all accounting lines in line_ids and the moves should be balanced.
Latest version of Odoo 13 dated December 10, 2021.
Edit file: /path_of_odoo/addons/account/models/account_move.py
Example:
vim /odoo/addons/account/models/account_move.py
Modify function named _check_balanced and comment line 1582 and add new line whit return
Example:
############################### Before ##################################
############################### A F T E R ###############################

Expected singleton odoo 9

After enter 2 and more new row in tree view and click on save get error
raise ValueError("Expected singleton: %s" % self)
ValueError: Expected singleton: my.model(2116, 2117)
My source code:
#api.depends('start', 'finish','stop')
def total_fun(self):
time1 = datetime.strptime(self.start, "%Y-%m-%d %H:%M:%S")
time2 = datetime.strptime(self.finish, "%Y-%m-%d %H:%M:%S")
self.total = round(((time2 - time1).seconds / float(60*60) - self.stop))
Error message says -> expected singleton this means: you are using recordset instead of record.
To fix this use
for rec in self:
in the begining of function, and then use rec instead of self
As you can see in the error message Expected singleton: my.model(2116, 2117)
By default in odoo the self is always a recordSet (means it can contain more then one record.) so when you do self.getSomeField here odoo will be confused wich record you want to get the value from.
if you don't tell odoo that make sure that the self will always contain one record when you acces an attribute if the recordSet contains more than one record this error is raised.
Now how to tell odoo make sure there is always one record is by adding #api.one decorator to the method. but is not recommended because odoo in your case there is two record so he will loop and call the method for each record and pass a recordSet that have only that record. imagine that you execute a search or any communication with database.
so don't use #api.one only if you are sure of what you are doing because you can make 10000 method call and interact with database.
like this example using #api.one:
# every call to this method you will execute a search.
self.env['some.model'].search([('m2o_id' , '=', self.id)]
you can do this before the loop:
# one query for all record with one call to the method
result = self.env['some.model'].search([('m2o_id' , 'in', self.ids)]
for rec in self:
# use result here
# or here ..

One2many field on_change function can't change its own value?

I have these two fields.
'name' : fields.char('Name'),
'addresses' : fields.one2many('res.partner.address', 'partner','Addresses'),
This function:
def addresses_change(self, cr, uid, ids, name, addresses, context=None):
value = {}
new_addresses = []
address_pool = self.pool.get('res.partner.address')
for address in address_pool.browse(cr, uid, addresses[0][2], context=context):
new_addresses.append((1,address.id,{'street':'wall street','zip':'7777','partner': ids[0],'active':True}))
value.update(name='whatever')
value.update(addresses=new_addresses)
return {'value':value}
And these view fields:
<field name="name" on_change="addresses_change(name,addresses)"/>
<field name="addresses" on_change="addresses_change(name,addresses)"/>
Now when I change name, both name and addresses are updated. But when I change addresses its own value isn't updated but the name is updated. So this bizarre behavior affects only one2many fields. Why is this?
And how do I add on_change event to one2many fields that can update its own value?
EDIT: I found out that this is might be a limitation in odoo, have they fixed this issue? Link to the issue
Apply the following patch on the lastest version of models.py (the version commited on Tue Aug 4 15:22:33 2015 +0200):
--- a/openerp/models.py
+++ b/openerp/models.py
## -5897,9 +5897,9 ## class BaseModel(object):
# At the moment, the client does not support updates on a *2many field
# while this one is modified by the user.
- if field_name and not isinstance(field_name, list) and \
- self._fields[field_name].type in ('one2many', 'many2many'):
- result['value'].pop(field_name, None)
+ ## if field_name and not isinstance(field_name, list) and \
+ ## self._fields[field_name].type in ('one2many', 'many2many'):
+ ## result['value'].pop(field_name, None)
return result
In other words, just comment the lines 5900 to 5902 of the openerp/models.py file.
Of course, there is a big disadvantage with this solution - you need to apply the patch every time the models.py file is updated in the Odoo distribution you use.
There is a considerable risk too - they say that the Web client is not dealing well with one2many and many2many fields updated in onchange event. I did not discover any problem with that right now but I'll continue to test my development installation of Odoo...
I created a Pull Request to odoo version 8
https://github.com/odoo/odoo/issues/2693
with the changes mentioned in the issues and here
if field_name and not isinstance(field_name, list) and \
- self._fields[field_name].type in ('one2many', 'many2many'):
+ if field_name and not isinstance(field_name, list):

OpenERP - how to get form field value in python code

I have a field in the XML file, categ_id. I need to access the value of that field in my Python code, in product_template class. I tried vals as a paremeter but it did not work.
If you can give me an example object.field_name as it relates to the case I have described.
Nebojsa - your question is not understandable at all, but I'll try to answer it. You can get the value of categ_id in two or even three ways:
vals.get('categ_id') - this is the way to go when you are creating a new record or updating existing one with change in categ_id field - otherwise you'll get an error or NoneType defined.
template = self.pool.get('product.template).browse(cr, uid, ids) and then template.categ_id.id - to get the value when you do have an id of the record, so you can ask database of value stored or in transaction, if there were any changes.
third opition is the dirtiest one, because it is just cr.execute("SELECT categ_id FROM product_template WHERE id = %s", (ids[0],)) and then category_id = cr.fetchall() - it is not always good option to use that, as it asks for records already existing in database (not counting these in transaction)