[MERGE] forward port of branch 8.0 up to d780014

This commit is contained in:
Christophe Simonis
2015-03-26 18:44:22 +01:00
25 changed files with 64 additions and 34 deletions
+12
View File
@@ -145,6 +145,7 @@
<field name="amount_untaxed" sum="Untaxed Amount"/>
<field name="amount_total" sum="Total Amount"/>
<field name="state"/>
<field name="type" invisible="context.get('type',True)"/>
</tree>
</field>
</record>
@@ -504,6 +505,17 @@
<field name="search_view_id" ref="view_account_invoice_filter"/>
</record>
<record id="action_invoice_refund_out_tree" model="ir.actions.act_window">
<field name="name">Invoices</field>
<field name="res_model">account.invoice</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="view_id" ref="invoice_tree"/>
<field name="domain">[('type','in', ['out_invoice', 'out_refund']), ('state', 'not in', ['draft', 'cancel'])]</field>
<field name="context">{'type':False}</field>
<field name="search_view_id" ref="view_account_invoice_filter"/>
</record>
<record id="action_invoice_tree_pending_invoice" model="ir.actions.act_window">
<field name="name">Pending Invoice</field>
<field name="res_model">account.invoice</field>
+2 -1
View File
@@ -306,7 +306,8 @@ class account_move_line(osv.osv):
if not id:
return []
ml = self.browse(cr, uid, id, context=context)
return map(lambda x: x.id, ml.move_id.line_id)
domain = (context or {}).get('on_write_domain', [])
return self.pool.get('account.move.line').search(cr, uid, domain + [['id', 'in', [l.id for l in ml.move_id.line_id]]], context=context)
def _balance(self, cr, uid, ids, name, arg, context=None):
if context is None:
+1 -1
View File
@@ -242,7 +242,7 @@ class res_partner(osv.osv):
result = {}
account_invoice_report = self.pool.get('account.invoice.report')
for partner in self.browse(cr, uid, ids, context=context):
domain = [('partner_id', 'child_of', partner.id)]
domain = [('partner_id', 'child_of', partner.id), ('state', 'not in', ['draft', 'cancel'])]
invoice_ids = account_invoice_report.search(cr, uid, domain, context=context)
invoices = account_invoice_report.browse(cr, uid, invoice_ids, context=context)
result[partner.id] = sum(inv.user_currency_price_total for inv in invoices)
+1 -1
View File
@@ -77,7 +77,7 @@
class="oe_stat_button"
id="invoice_button"
icon="fa-pencil-square-o"
name="%(account.action_invoice_tree)d"
name="%(account.action_invoice_refund_out_tree)d"
attrs="{'invisible': [('customer', '=', False)]}"
context="{'search_default_partner_id': active_id,'default_partner_id': active_id}">
<div><strong><field name="total_invoiced" widget="monetary"/></strong><br/>Invoiced</div>
@@ -152,6 +152,7 @@
<tr><td>Description</td><td><t t-esc="line.name"/></td></tr>
<tr><td>Amount</td><td><t t-esc="line.amount_str"/><t t-if="line.amount_currency_str"> (<t t-esc="line.amount_currency_str"/>)</t></td></tr>
<tr><td>Account</td><td><t t-esc="line.account_code"/> <t t-esc="line.account_name"/></td></tr>
<tr t-if="line.note"><td>Note</td><td><t t-esc="line.note"/></td></tr>
</table>
</t>
@@ -132,8 +132,8 @@
<field name="bank_id" domain="[('partner_id', '=', partner_id)]"/>
<field name="ml_maturity_date"/>
<field name="date"/>
<field name="amount_currency" string="Amount" groups="base.group_multi_currency"/>
<field name="currency" groups="base.group_multi_currency"/>
<field name="amount_currency" string="Amount"/>
<field name="currency"/>
<field name="name"/>
<field name="amount" sum="Total in Company Currency" invisible="1"/>
</tree>
+1 -1
View File
@@ -157,7 +157,7 @@ class ir_import(orm.TransientModel):
for field in fields:
# FIXME: should match all translations & original
# TODO: use string distance (levenshtein? hamming?)
if header == field['name'] \
if header.lower() == field['name'].lower() \
or header.lower() == field['string'].lower():
return [field]
+2
View File
@@ -20,3 +20,5 @@
##############################################################################
import google_account
import controllers
from .google_account import TIMEOUT # noqa
+3 -2
View File
@@ -15,6 +15,7 @@ import simplejson
import logging
_logger = logging.getLogger(__name__)
TIMEOUT = 20
class google_service(osv.osv_memory):
_name = 'google.service'
@@ -31,7 +32,7 @@ class google_service(osv.osv_memory):
data = werkzeug.url_encode(data)
try:
req = urllib2.Request("https://accounts.google.com/o/oauth2/token", data, headers)
content = urllib2.urlopen(req).read()
content = urllib2.urlopen(req, timeout=TIMEOUT).read()
except urllib2.HTTPError:
error_msg = "Something went wrong during your token generation. Maybe your Authorization Code is invalid or already expired"
raise self.pool.get('res.config.settings').get_config_warning(cr, _(error_msg), context=context)
@@ -148,7 +149,7 @@ class google_service(osv.osv_memory):
raise ('Method not supported [%s] not in [GET, POST, PUT, PATCH or DELETE]!' % (type))
req.get_method = lambda: type.upper()
request = urllib2.urlopen(req)
request = urllib2.urlopen(req, timeout=TIMEOUT)
status = request.getcode()
if int(status) in (204, 404): # Page not found, no response
+7 -6
View File
@@ -20,6 +20,7 @@
import logging
from openerp import SUPERUSER_ID
from openerp.addons.google_account import TIMEOUT
from openerp.osv import fields, osv
from openerp.tools.translate import _
from openerp.exceptions import UserError
@@ -82,7 +83,7 @@ class config(osv.Model):
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept-Encoding": "gzip, deflate"}
try:
req = urllib2.Request('https://accounts.google.com/o/oauth2/token', data, headers)
content = urllib2.urlopen(req).read()
content = urllib2.urlopen(req, timeout=TIMEOUT).read()
except urllib2.HTTPError:
if user_is_admin:
model, action_id = self.pool['ir.model.data'].get_object_reference(cr, uid, 'base_setup', 'action_general_configuration')
@@ -102,7 +103,7 @@ class config(osv.Model):
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept-Encoding": "gzip, deflate"}
try:
req = urllib2.Request(request_url, None, headers)
parents = urllib2.urlopen(req).read()
parents = urllib2.urlopen(req, timeout=TIMEOUT).read()
except urllib2.HTTPError:
raise UserError(_("The Google Template cannot be found. Maybe it has been deleted."))
parents_dict = json.loads(parents)
@@ -114,7 +115,7 @@ class config(osv.Model):
data_json = json.dumps(data)
# resp, content = Http().request(request_url, "POST", data_json, headers)
req = urllib2.Request(request_url, data_json, headers)
content = urllib2.urlopen(req).read()
content = urllib2.urlopen(req, timeout=TIMEOUT).read()
content = json.loads(content)
res = {}
if content.get('alternateLink'):
@@ -129,7 +130,7 @@ class config(osv.Model):
data = {'role': 'writer', 'type': 'anyone', 'value': '', 'withLink': True}
try:
req = urllib2.Request(request_url, json.dumps(data), headers)
urllib2.urlopen(req)
urllib2.urlopen(req, timeout=TIMEOUT)
except urllib2.HTTPError:
raise self.pool.get('res.config.settings').get_config_warning(cr, _("The permission 'reader' for 'anyone with the link' has not been written on the document"), context=context)
user = self.pool['res.users'].browse(cr, uid, uid, context=context)
@@ -137,10 +138,10 @@ class config(osv.Model):
data = {'role': 'writer', 'type': 'user', 'value': user.email}
try:
req = urllib2.Request(request_url, json.dumps(data), headers)
urllib2.urlopen(req)
urllib2.urlopen(req, timeout=TIMEOUT)
except urllib2.HTTPError:
pass
return res
return res
def get_google_drive_config(self, cr, uid, res_model, res_id, context=None):
'''
@@ -27,7 +27,7 @@ import werkzeug.urls
import urllib2
from openerp.osv import osv
from openerp import SUPERUSER_ID
from openerp.addons.google_account import TIMEOUT
_logger = logging.getLogger(__name__)
@@ -92,7 +92,7 @@ class config(osv.osv):
'https://spreadsheets.google.com/feeds/cells/%s/od6/private/full/batch?%s' % (spreadsheet_key, werkzeug.url_encode({'v': 3, 'access_token': access_token})),
data=request,
headers={'content-type': 'application/atom+xml', 'If-Match': '*'})
urllib2.urlopen(req)
urllib2.urlopen(req, timeout=TIMEOUT)
except (urllib2.HTTPError, urllib2.URLError):
_logger.warning("An error occured while writting the formula on the Google Spreadsheet.")
+1
View File
@@ -369,6 +369,7 @@ class mrp_bom(osv.osv):
class mrp_bom_line(osv.osv):
_name = 'mrp.bom.line'
_order = "sequence"
_rec_name = "product_id"
def _get_child_bom_lines(self, cr, uid, ids, field_name, arg, context=None):
"""If the BOM line refers to a BOM, return the ids of the child BOM lines"""
+2 -2
View File
@@ -1008,8 +1008,8 @@ class pos_order(osv.osv):
inv_line['price_unit'] = line.price_unit
inv_line['discount'] = line.discount
inv_line['name'] = inv_name
if line.tax_ids:
inv_line['invoice_line_tax_id'] = [(6, 0, [x.id for x in line.tax_ids])]
if inv_line['invoice_line_tax_id']:
inv_line['invoice_line_tax_id'] = [(6, 0, inv_line['invoice_line_tax_id'])]
inv_line_ref.create(cr, uid, inv_line, context=context)
inv_ref.button_reset_taxes(cr, uid, [inv_id], context=context)
self.signal_workflow(cr, uid, [order.id], 'invoice')
@@ -433,7 +433,8 @@
var self = this;
var on_write_callback = self.fields_view.arch.attrs.on_write;
if (!on_write_callback) { return $.when(); }
return this.dataset.call(on_write_callback, [source_record.get('id')])
var context = new instance.web.CompoundContext(self.dataset.get_context(), {'on_write_domain': self.dataset.domain}).eval();
return this.dataset.call(on_write_callback, [source_record.get('id'), context])
.then(function (ids) {
return $.when.apply(
null, _(ids).map(
+2 -2
View File
@@ -766,12 +766,12 @@ instance.web_kanban.KanbanGroup = instance.web.Widget.extend({
},
do_show_more: function(evt) {
var self = this;
var ids = self.view.dataset.ids.splice(0);
var ids = self.view.dataset.ids.slice(0);
return this.dataset.read_slice(this.view.fields_keys.concat(['__last_update']), {
'limit': self.view.limit,
'offset': self.dataset_offset += self.view.limit
}).then(function(records) {
self.view.dataset.ids = ids.concat(self.dataset.ids);
self.view.dataset.ids = ids.concat(_.difference(self.dataset.ids, ids));
self.do_add_records(records);
self.compute_cards_auto_height();
self.view.postprocess_m2m_tags();
-3
View File
@@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
import datetime
import hashlib
import logging
import os
import re
@@ -170,7 +168,6 @@ class ir_http(orm.AbstractModel):
path += '?' + request.httprequest.query_string
return werkzeug.utils.redirect(path, code=301)
def _handle_exception(self, exception, code=500):
is_website_request = bool(getattr(request, 'website_enabled', False) and request.website)
if not is_website_request:
+2 -2
View File
@@ -309,7 +309,7 @@ class website(osv.osv):
return False
@openerp.tools.ormcache(skiparg=3)
def _get_languages(self, cr, uid, id, context=None):
def _get_languages(self, cr, uid, id):
website = self.browse(cr, uid, id)
return [(lg.code, lg.name) for lg in website.language_ids]
@@ -324,7 +324,7 @@ class website(osv.osv):
return uri
def get_languages(self, cr, uid, ids, context=None):
return self._get_languages(cr, uid, ids[0], context=context)
return self._get_languages(cr, uid, ids[0])
def get_alternate_languages(self, cr, uid, ids, req=None, context=None):
langs = []
@@ -157,7 +157,8 @@
<template id="quotation_toolbar">
<div class="text-center hidden-print" t-if="quotation.state in ('draft', 'sent', 'waiting_date')">
<a class="btn btn-success fa fa-check" data-toggle="modal" data-target="#modalaccept">
<a class="btn btn-success fa fa-check" data-toggle="modal" data-target="#modalaccept"
t-if="days_valid">
Accept
</a>
<a class="btn btn-info fa fa-comment" type="submit" href="#discussion">
+3 -1
View File
@@ -851,7 +851,9 @@ Possible children of the view element are:
an object with all the requested fields as its attributes. Each field has
two attributes ``value`` and ``raw_value``, the former is formatted
according to current user parameters, the latter is the direct value from
a :meth:`~openerp.models.Model.read`
a :meth:`~openerp.models.Model.read` (except for date and datetime fields
that are `formatted according to user's locale
<https://github.com/odoo/odoo/blob/8.0/addons/web_kanban/static/src/js/kanban.js#L900>`_)
``read_only_mode``
self-explanatory
+1 -1
View File
@@ -118,7 +118,7 @@ class ir_attachment(osv.osv):
return self.pool['ir.config_parameter'].get_param(cr, SUPERUSER_ID, 'ir_attachment.location', 'file')
@tools.ormcache(skiparg=3)
def _filestore(self, cr, uid, context=None):
def _filestore(self, cr, uid):
return tools.config.filestore(cr.dbname)
def force_storage(self, cr, uid, context=None):
+1
View File
@@ -58,6 +58,7 @@ class ir_filters(osv.osv):
"""
# available filters: private filters (user_id=uid) and public filters (uid=NULL),
# and filters for the action (action_id=action_id) or global (action_id=NULL)
context = self.pool['res.users'].context_get(cr, uid)
action_domain = self._get_action_domain(cr, uid, action_id)
filter_ids = self.search(cr, uid, action_domain +
[('model_id','=',model),('user_id','in',[uid, False])])
+2
View File
@@ -5,9 +5,11 @@
import datetime
import hashlib
import logging
import mimetypes
import re
import sys
import werkzeug
import werkzeug.exceptions
import werkzeug.routing
import werkzeug.urls
+5 -1
View File
@@ -729,7 +729,11 @@ class ir_model_access(osv.osv):
a.perm_''' + access_mode, (model_name,))
return [('%s/%s' % x) if x[0] else x[1] for x in cr.fetchall()]
@tools.ormcache()
# The context parameter is useful when the method translates error messages.
# But as the method raises an exception in that case, the key 'lang' might
# not be really necessary as a cache key, unless the `ormcache_context`
# decorator catches the exception (it does not at the moment.)
@tools.ormcache_context(accepted_keys=('lang',))
def check(self, cr, uid, model, mode='read', raise_exception=True, context=None):
if uid==1:
# User root have all accesses
+6 -3
View File
@@ -338,7 +338,7 @@ class res_users(osv.osv):
for id in ids:
if id in self._uid_cache[db]:
del self._uid_cache[db][id]
self.context_get.clear_cache(self)
self._context_get.clear_cache(self)
self.has_group.clear_cache(self)
return res
@@ -374,8 +374,8 @@ class res_users(osv.osv):
return super(res_users, self).copy(cr, uid, id, default, context)
@tools.ormcache(skiparg=2)
def context_get(self, cr, uid, context=None):
user = self.browse(cr, SUPERUSER_ID, uid, context)
def _context_get(self, cr, uid):
user = self.browse(cr, SUPERUSER_ID, uid)
result = {}
for k in self._fields:
if k.startswith('context_'):
@@ -391,6 +391,9 @@ class res_users(osv.osv):
result[context_key] = res or False
return result
def context_get(self, cr, uid, context=None):
return self._context_get(cr, uid)
def action_get(self, cr, uid, context=None):
dataobj = self.pool['ir.model.data']
data_id = dataobj._get_id(cr, SUPERUSER_ID, 'base', 'action_res_users_my')
+1 -1
View File
@@ -105,7 +105,7 @@ class ormcache_context(ormcache):
# arguments, and pass them positionally to lookup(). This is why context
# is not passed through kwargs!
if self.context_pos < len(args):
context = args[self.context_pos]
context = args[self.context_pos] or {}
else:
context = kwargs.get('context') or {}
ckey = [(k, context[k]) for k in self.accepted_keys if k in context]