[MERGE] Forward-port 10.0 up to 76cd8d2558

This commit is contained in:
Olivier Dony
2017-06-03 01:24:21 +02:00
13 changed files with 54 additions and 43 deletions
+1
View File
@@ -10,5 +10,6 @@ class CalendarBusController(BusController):
# --------------------------
def _poll(self, dbname, channels, last, options):
if request.session.uid:
channels = list(channels)
channels.append((request.db, 'calendar.alarm', request.env.user.partner_id.id))
return super(CalendarBusController, self)._poll(dbname, channels, last, options)
@@ -139,7 +139,11 @@ class GoogleService(models.TransientModel):
if error.code == 400: # invalid grant
with registry(request.session.db).cursor() as cur:
self.env(cur)['res.users'].browse(self.env.uid).write({'google_%s_rtoken' % service: False})
error_key = json.loads(error.read()).get("error", "nc")
try:
error_file = error.read()
error_key = json.loads(error_file).get("error", "nc")
except:
error_key = error
_logger.exception("Bad google request : %s !", error_key)
error_msg = _("Something went wrong during your token generation. Maybe your Authorization Code is invalid or already expired [%s]") % error_key
raise self.env['res.config.settings'].get_config_warning(error_msg)
+1 -1
View File
@@ -112,7 +112,7 @@
<field name="arch" type="xml">
<search string="Product">
<field name="name" string="Product" filter_domain="['|','|',('default_code','ilike',self),('name','ilike',self),('barcode','ilike',self)]"/>
<field name="categ_id" domain="[('categ_id', 'child_of', self)]"/>
<field name="categ_id" filter_domain="[('categ_id', 'child_of', self)]"/>
<separator/>
<filter string="Services" name="services" domain="[('type','=','service')]"/>
<filter string="Products" name="consumable" domain="[('type', 'in', ['consu', 'product'])]"/>
+2 -4
View File
@@ -35,7 +35,6 @@ class ProductProduct(models.Model):
def _calc_price(self, bom):
price = 0.0
workcenter_cost = 0.0
result, result2 = bom.explode(self, 1)
for sbom, sbom_data in result2:
if not sbom.attribute_value_ids:
@@ -44,9 +43,8 @@ class ProductProduct(models.Model):
if bom.routing_id:
total_cost = 0.0
for order in bom.routing_id.operation_ids:
total_cost += (order.time_cycle_manual/60) * order.workcenter_id.costs_hour
workcenter_cost = total_cost / len(bom.routing_id.operation_ids)
price += bom.product_uom_id._compute_price(workcenter_cost, bom.product_id.uom_id)
total_cost += (order.time_cycle/60) * order.workcenter_id.costs_hour
price += bom.product_uom_id._compute_price(total_cost, bom.product_id.uom_id)
# Convert on product UoM quantities
if price > 0:
price = bom.product_uom_id._compute_price(price / bom.product_qty, self.uom_id)
@@ -1118,7 +1118,7 @@ data.Editor = Class.extend({
}).bind(this));
// Activate the overlay
$style_button.toggleClass("hidden", $ul.children(":not(.divider):not(.hidden)").length === 0);
$style_button.toggleClass("hidden", $ul.children(":not(.o_main_header):not(.divider):not(.hidden)").length === 0);
this.$overlay.toggleClass("oe_active", !!focus);
function _do_action_focus(style, $dest) {
@@ -576,15 +576,18 @@ odoo.define('web_editor.snippets.options', function (require) {
registry.background = SnippetOption.extend({
start: function () {
var res = this._super.apply(this, arguments);
this.$target.off(".background-option")
.on("background-color-event.background-option", (function (e, type) {
e.stopPropagation();
if (e.currentTarget !== e.target) return;
this.$el.find("li:first > a").trigger(type);
}).bind(this));
this.bind_bg_events();
return res;
},
bind_bg_events: function () {
this.$target.off(".background-option")
.on("background-color-event.background-option", (function (e, type) {
e.stopPropagation();
if (e.currentTarget !== e.target) return;
this.$el.find("li:first > a").trigger(type);
}).bind(this));
},
background: function (type, value, $li) {
if (value && value.length) {
this.$target.css("background-image", "url(" + value + ")");
+6
View File
@@ -238,3 +238,9 @@
}
}
}
@media print {
.o_tooltip {
display: none;
}
}
@@ -228,6 +228,9 @@ options.registry.carousel = options.registry.slider.extend({
s_option.$target = self.$target.find(".item.active");
s_option.set_active();
s_option.$target.trigger("snippet-option-change", [s_option]);
if (opt_name === 'background') {
s_option.bind_bg_events();
}
});
});
this.$target.trigger('slid.bs.carousel');
+1 -1
View File
@@ -152,7 +152,7 @@ class WebsiteForum(http.Controller):
question_ids = Post.search(domain, limit=self._post_per_page, offset=pager['offset'], order=sorting)
values = self._prepare_forum_values(forum=forum, searches=post)
values = self._prepare_forum_values(forum=forum, searches=post, header={'ask_hide': not forum.active})
values.update({
'main_object': tag or forum,
'question_ids': question_ids,
@@ -150,9 +150,12 @@ class website_account(website_account):
order.check_access_rule('read')
except AccessError:
return request.render("website.403")
order_invoice_lines = {il.product_id.id: il.invoice_id for il in order.invoice_ids.mapped('invoice_line_ids')}
order_sudo = order.sudo()
order_invoice_lines = {il.product_id.id: il.invoice_id for il in order_sudo.invoice_ids.mapped('invoice_line_ids')}
return request.render("website_portal_sale.orders_followup", {
'order': order.sudo(),
'order': order_sudo,
'order_invoice_lines': order_invoice_lines,
})
+3 -1
View File
@@ -235,7 +235,9 @@ class WebsiteSale(http.Controller):
ProductAttribute = request.env['product.attribute']
if products:
attributes = ProductAttribute.search([('attribute_line_ids.product_tmpl_id', 'in', products.ids)])
# get all products without limit
selected_products = Product.search(domain, limit=False)
attributes = ProductAttribute.search([('attribute_line_ids.product_tmpl_id', 'in', selected_products.ids)])
else:
attributes = ProductAttribute.browse(attributes_ids)
+7 -25
View File
@@ -57,10 +57,15 @@ def check(f):
elif isinstance(kwargs, dict):
if 'context' in kwargs:
ctx = kwargs['context']
elif 'kwargs' in kwargs:
elif 'kwargs' in kwargs and kwargs['kwargs'].get('context'):
# http entry points such as call_kw()
ctx = kwargs['kwargs'].get('context')
else:
try:
from odoo.http import request
ctx = request.env.context
except Exception:
pass
uid = 1
if args and isinstance(args[0], (long, int)):
@@ -74,29 +79,6 @@ def check(f):
# queries (as in IntegrityError) will invalidate the current one.
cr = False
if hasattr(src, '__call__'):
# callable. We need to find the right parameters to call
# the orm._sql_message(self, cr, uid, ids, context) function,
# or we skip..
# our signature is f(registry, dbname [,uid, obj, method, args])
try:
if args and len(args) > 1:
# TODO self doesn't exist, but was already wrong before (it was not a registry but just the object_service.
obj = self.get(args[1])
if len(args) > 3 and isinstance(args[3], (long, int, list)):
ids = args[3]
else:
ids = []
cr = odoo.sql_db.db_connect(dbname).cursor()
return src(obj, cr, uid, ids, context=(ctx or {}))
except Exception:
pass
finally:
if cr: cr.close()
return False # so that the original SQL error will
# be returned, it is the best we have.
try:
cr = odoo.sql_db.db_connect(dbname).cursor()
res = translate(cr, name=False, source_type=ttype,
+10 -1
View File
@@ -196,7 +196,16 @@ def file_open(name, mode="r", subdir='addons', pathinfo=False):
def _fileopen(path, mode, basedir, pathinfo, basename=None):
name = os.path.normpath(os.path.join(basedir, path))
name = os.path.normpath(os.path.normcase(os.path.join(basedir, path)))
import odoo.modules as addons
paths = addons.module.ad_paths + [config['root_path']]
for addons_path in paths:
addons_path = os.path.normpath(os.path.normcase(addons_path)) + os.sep
if name.startswith(addons_path):
break
else:
raise ValueError("Unknown path: %s" % name)
if basename is None:
basename = name