[MERGE] Forward-port 10.0 up to 76cd8d2558
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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'])]"/>
|
||||
|
||||
@@ -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 + ")");
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user