diff --git a/addons/account/account_cash_statement.py b/addons/account/account_cash_statement.py index d4c98b7c275..5b1952f44d9 100644 --- a/addons/account/account_cash_statement.py +++ b/addons/account/account_cash_statement.py @@ -23,6 +23,7 @@ import time from openerp.osv import fields, osv +from openerp.tools import float_compare from openerp.tools.translate import _ import openerp.addons.decimal_precision as dp @@ -80,7 +81,8 @@ class account_cash_statement(osv.osv): if (statement.journal_id.type not in ('cash',)): continue if not statement.journal_id.cash_control: - if statement.balance_end_real <> statement.balance_end: + prec = self.pool['decimal.precision'].precision_get(cr, uid, 'Account') + if float_compare(statement.balance_end_real, statement.balance_end, precision_digits=prec): statement.write({'balance_end_real' : statement.balance_end}) continue start = end = 0 diff --git a/addons/account/res_config.py b/addons/account/res_config.py index 4e870b78dfd..c69eeb9646e 100644 --- a/addons/account/res_config.py +++ b/addons/account/res_config.py @@ -241,8 +241,8 @@ class account_config_settings(osv.osv_memory): }) # update taxes ir_values = self.pool.get('ir.values') - taxes_id = ir_values.get_default(cr, uid, 'product.product', 'taxes_id', company_id=company_id) - supplier_taxes_id = ir_values.get_default(cr, uid, 'product.product', 'supplier_taxes_id', company_id=company_id) + taxes_id = ir_values.get_default(cr, uid, 'product.template', 'taxes_id', company_id=company_id) + supplier_taxes_id = ir_values.get_default(cr, uid, 'product.template', 'supplier_taxes_id', company_id=company_id) values.update({ 'default_sale_tax': isinstance(taxes_id, list) and taxes_id[0] or taxes_id, 'default_purchase_tax': isinstance(supplier_taxes_id, list) and supplier_taxes_id[0] or supplier_taxes_id, @@ -311,9 +311,9 @@ class account_config_settings(osv.osv_memory): raise openerp.exceptions.AccessError(_("Only administrators can change the settings")) ir_values = self.pool.get('ir.values') config = self.browse(cr, uid, ids[0], context) - ir_values.set_default(cr, SUPERUSER_ID, 'product.product', 'taxes_id', + ir_values.set_default(cr, SUPERUSER_ID, 'product.template', 'taxes_id', config.default_sale_tax and [config.default_sale_tax.id] or False, company_id=config.company_id.id) - ir_values.set_default(cr, SUPERUSER_ID, 'product.product', 'supplier_taxes_id', + ir_values.set_default(cr, SUPERUSER_ID, 'product.template', 'supplier_taxes_id', config.default_purchase_tax and [config.default_purchase_tax.id] or False, company_id=config.company_id.id) def set_chart_of_accounts(self, cr, uid, ids, context=None): diff --git a/addons/account/static/src/js/account_widgets.js b/addons/account/static/src/js/account_widgets.js index 158805fe55f..04189e36d7f 100644 --- a/addons/account/static/src/js/account_widgets.js +++ b/addons/account/static/src/js/account_widgets.js @@ -41,6 +41,7 @@ openerp.account = function (instance) { this.max_move_lines_displayed = 5; this.animation_speed = 100; // "Blocking" animations this.aestetic_animation_speed = 300; // eye candy + this.map_currency_id_rounding = {}; this.map_tax_id_amount = {}; this.presets = {}; // We'll need to get the code of an account selected in a many2one (whose value is the id) @@ -199,6 +200,13 @@ openerp.account = function (instance) { _.each(data, function(o) { self.map_account_id_code[o.id] = o.code }); }); + // Create a dict currency id -> rounding factor + new instance.web.Model("res.currency") + .query(['id', 'rounding']) + .all().then(function(data) { + _.each(data, function(o) { self.map_currency_id_rounding[o.id] = o.rounding }); + }); + // Create a dict tax id -> amount new instance.web.Model("account.tax") .query(['id', 'amount']) @@ -347,10 +355,12 @@ openerp.account = function (instance) { self.$(".reconciliation_lines_container").fadeIn(self.aestetic_animation_speed); }); }); - } - // Congratulate the user if the work is done - if (self.reconciled_lines === self.st_lines.length) { + } else if (self.reconciled_lines === self.st_lines.length) { + // Congratulate the user if the work is done self.displayDoneMessage(); + } else { + // Some lines weren't persisted because they were't valid + self.$(".reconciliation_lines_container").fadeIn(self.aestetic_animation_speed); } }).fail(function() { self.$(".reconciliation_lines_container").fadeIn(self.aestetic_animation_speed); @@ -386,7 +396,7 @@ openerp.account = function (instance) { // Update children if needed _.each(self.getChildren(), function(child){ - if (child.partner_id === partner_id && child !== source_child) { + if ((child.partner_id === partner_id || child.st_line.has_no_partner) && child !== source_child) { if (contains_lines(child.get("mv_lines_selected"), line_ids)) { child.set("mv_lines_selected", _.filter(child.get("mv_lines_selected"), function(o){ return line_ids.indexOf(o.id) === -1 })); } else if (contains_lines(child.mv_lines_deselected, line_ids)) { @@ -412,6 +422,8 @@ openerp.account = function (instance) { _.each(self.getChildren(), function(child){ if (child.partner_id === partner_id && child !== source_child && (child.get("mode") === "match" || child.$el.hasClass("no_match"))) child.updateMatches(); + if (child.st_line.has_no_partner && child.get("mode") === "match" || child.$el.hasClass("no_match")) + child.updateMatches(); }); }, @@ -639,12 +651,13 @@ openerp.account = function (instance) { this.model_bank_statement_line = new instance.web.Model("account.bank.statement.line"); this.model_res_users = new instance.web.Model("res.users"); this.model_tax = new instance.web.Model("account.tax"); + this.map_currency_id_rounding = this.getParent().map_currency_id_rounding; this.map_account_id_code = this.getParent().map_account_id_code; this.map_tax_id_amount = this.getParent().map_tax_id_amount; this.presets = this.getParent().presets; this.is_valid = true; this.is_consistent = true; // Used to prevent bad server requests - this.total_move_lines_num = undefined; // Used for pagers + this.can_fetch_more_move_lines; // Tell if we can show more move lines this.filter = ""; // In rare cases like when deleting a statement line's partner we don't want the server to // look for a reconciliation proposition (in this particular case it might find a move line @@ -1039,16 +1052,15 @@ openerp.account = function (instance) { pagerControlLeftHandler: function() { var self = this; if (self.$(".pager_control_left").hasClass("disabled")) { return; /* shouldn't happen, anyway*/ } - if (self.total_move_lines_num < 0) { return; } + if (self.get("pager_index") === 0) { return; } self.set("pager_index", self.get("pager_index")-1 ); }, pagerControlRightHandler: function() { var self = this; - var new_index = self.get("pager_index")+1; if (self.$(".pager_control_right").hasClass("disabled")) { return; /* shouldn't happen, anyway*/ } - if ((new_index * self.max_move_lines_displayed) >= self.total_move_lines_num) { return; } - self.set("pager_index", new_index ); + if (! self.can_fetch_more_move_lines) { return; } + self.set("pager_index", self.get("pager_index")+1 ); }, filterHandler: function() { @@ -1222,7 +1234,7 @@ openerp.account = function (instance) { self.$(".pager_control_left").addClass("disabled"); else self.$(".pager_control_left").removeClass("disabled"); - if (self.total_move_lines_num <= ((self.get("pager_index")+1) * self.max_move_lines_displayed)) + if (! self.can_fetch_more_move_lines) self.$(".pager_control_right").addClass("disabled"); else self.$(".pager_control_right").removeClass("disabled"); @@ -1323,12 +1335,12 @@ openerp.account = function (instance) { mvLinesChanged: function() { var self = this; // If pager_index is out of range, set it to display the last page - if (self.get("pager_index") !== 0 && self.total_move_lines_num <= (self.get("pager_index") * self.max_move_lines_displayed)) { - self.set("pager_index", Math.ceil(self.total_move_lines_num/self.max_move_lines_displayed)-1); + if (self.get("pager_index") !== 0 && self.get("mv_lines").length === 0 && ! self.can_fetch_more_move_lines) { + self.set("pager_index", 0); } // If there is no match to display, disable match view and pass in mode inactive - if (self.total_move_lines_num + self.mv_lines_deselected.length === 0 && self.filter === "") { + if (self.get("mv_lines").length + self.mv_lines_deselected.length === 0 && !self.can_fetch_more_move_lines && self.filter === "") { self.$el.addClass("no_match"); if (self.get("mode") === "match") { self.set("mode", "inactive"); @@ -1406,7 +1418,6 @@ openerp.account = function (instance) { } ); } else { - line_created_being_edited[0].amount = amount; line_created_being_edited.length = 1; deferred_tax.resolve(); } @@ -1414,9 +1425,12 @@ openerp.account = function (instance) { $.when(deferred_tax).then(function(){ // Format amounts + var rounding = 1/self.map_currency_id_rounding[self.st_line.currency_id]; $.each(line_created_being_edited, function(index, val) { - if (val.amount) + if (val.amount) { + line_created_being_edited[index].amount = Math.round(val.amount*rounding)/rounding; line_created_being_edited[index].amount_str = self.formatCurrency(Math.abs(val.amount), val.currency_id); + } }); self.set("line_created_being_edited", line_created_being_edited); self.createdLinesChanged(); // TODO For some reason, previous line doesn't trigger change handler @@ -1534,48 +1548,38 @@ openerp.account = function (instance) { updateMatches: function() { var self = this; var deselected_lines_num = self.mv_lines_deselected.length; - var move_lines_num = 0; var offset = self.get("pager_index") * self.max_move_lines_displayed - deselected_lines_num; if (offset < 0) offset = 0; var limit = (self.get("pager_index")+1) * self.max_move_lines_displayed - deselected_lines_num; if (limit > self.max_move_lines_displayed) limit = self.max_move_lines_displayed; - var excluded_ids = self.getParent().excluded_move_lines_ids[self.partner_id]; var excluded_ids = _.collect(self.get("mv_lines_selected").concat(self.mv_lines_deselected), function(o) { return o.id; }); - var globally_excluded_ids = self.getParent().excluded_move_lines_ids[self.partner_id]; + var globally_excluded_ids = []; + if (self.st_line.has_no_partner) + _.each(self.getParent().excluded_move_lines_ids, function(o) { globally_excluded_ids = globally_excluded_ids.concat(o) }); + else + globally_excluded_ids = self.getParent().excluded_move_lines_ids[self.partner_id]; if (globally_excluded_ids !== undefined) for (var i=0; i 0) { - // Load move lines - deferred_move_lines = self.model_bank_statement_line + return self.model_bank_statement_line .call("get_move_lines_for_reconciliation_by_statement_line_id", [self.st_line.id, excluded_ids, self.filter, offset, limit]) .then(function (lines) { - _.each(lines, function(line) { - self.decorateMoveLine(line, self.st_line.currency_id); - move_lines.push(line); - }, self); + _.each(lines, function(line) { self.decorateMoveLine(line, self.st_line.currency_id) }, self); + // If we could fetch 1 more item than what we'll display, that means there are move lines left to be displayed (so we enable the pager) + self.can_fetch_more_move_lines = (lines.length === limit); + self.set("mv_lines", lines.slice(0, limit-1)); }); + } else { + self.set("mv_lines", []); } - - // Fetch the number of move lines corresponding to this statement line and this filter - var deferred_total_move_lines_num = self.model_bank_statement_line - .call("get_move_lines_for_reconciliation_by_statement_line_id", [self.st_line.id, excluded_ids, self.filter, 0, undefined, true]) - .then(function(num){ - move_lines_num = num; - }); - - return $.when(deferred_move_lines, deferred_total_move_lines_num).then(function(){ - self.total_move_lines_num = move_lines_num + deselected_lines_num; - self.set("mv_lines", move_lines); - }); }, // Changes the partner_id of the statement_line in the DB and reloads the widget - changePartner: function(partner_id, callback) { + changePartner: function(partner_id) { var self = this; self.is_consistent = false; return self.model_bank_statement_line @@ -1588,7 +1592,6 @@ openerp.account = function (instance) { self.do_load_reconciliation_proposition = true; self.is_consistent = true; self.set("mode", "match"); - if (callback) callback(); }); }); }, diff --git a/addons/auth_signup/res_users.py b/addons/auth_signup/res_users.py index 97bcea52bc1..620298c72d5 100644 --- a/addons/auth_signup/res_users.py +++ b/addons/auth_signup/res_users.py @@ -64,7 +64,6 @@ class res_partner(osv.Model): # when required, make sure the partner has a valid signup token if context.get('signup_valid') and not partner.user_ids: self.signup_prepare(cr, uid, [partner.id], context=context) - partner.refresh() route = 'login' # the parameters to encode for the query diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 495b8418045..4356ee676ca 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -1612,7 +1612,9 @@ class mail_thread(osv.AbstractModel): # _mail_flat_thread: automatically set free messages to the first posted message if self._mail_flat_thread and model and not parent_id and thread_id: - message_ids = mail_message.search(cr, uid, ['&', ('res_id', '=', thread_id), ('model', '=', model)], context=context, order="id ASC", limit=1) + message_ids = mail_message.search(cr, uid, ['&', ('res_id', '=', thread_id), ('model', '=', model), ('type', '=', 'email')], context=context, order="id ASC", limit=1) + if not message_ids: + message_ids = message_ids = mail_message.search(cr, uid, ['&', ('res_id', '=', thread_id), ('model', '=', model)], context=context, order="id ASC", limit=1) parent_id = message_ids and message_ids[0] or False # we want to set a parent: force to set the parent_id to the oldest ancestor, to avoid having more than 1 level of thread elif parent_id: diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py index 62d433dea21..856b56dbc73 100644 --- a/addons/mrp/mrp.py +++ b/addons/mrp/mrp.py @@ -934,8 +934,8 @@ class mrp_production(osv.osv): new_moves = stock_mov_obj.action_consume(cr, uid, [produce_product.id], (subproduct_factor * production_qty_uom), location_id=produce_product.location_id.id, restrict_lot_id=lot_id, context=context) stock_mov_obj.write(cr, uid, new_moves, {'production_id': production_id}, context=context) - if produce_product.product_id.id == production.product_id.id and new_moves: - main_production_move = new_moves[0] + if produce_product.product_id.id == production.product_id.id: + main_production_move = produce_product.id if production_mode in ['consume', 'consume_produce']: if wiz: @@ -1035,8 +1035,11 @@ class mrp_production(osv.osv): def _make_production_produce_line(self, cr, uid, production, context=None): stock_move = self.pool.get('stock.move') + proc_obj = self.pool.get('procurement.order') source_location_id = production.product_id.property_stock_production.id destination_location_id = production.location_dest_id.id + procs = proc_obj.search(cr, uid, [('production_id', '=', production.id)], context=context) + procurement_id = procs and procs[0] or False data = { 'name': production.name, 'date': production.date_planned, @@ -1048,6 +1051,7 @@ class mrp_production(osv.osv): 'location_id': source_location_id, 'location_dest_id': destination_location_id, 'move_dest_id': production.move_prod_id.id, + 'procurement_id': procurement_id, 'company_id': production.company_id.id, 'production_id': production.id, 'origin': production.name, diff --git a/addons/mrp_byproduct/mrp_byproduct.py b/addons/mrp_byproduct/mrp_byproduct.py index 5649604b57d..fa7c0784052 100644 --- a/addons/mrp_byproduct/mrp_byproduct.py +++ b/addons/mrp_byproduct/mrp_byproduct.py @@ -84,6 +84,7 @@ class mrp_production(osv.osv): """ Confirms production order and calculates quantity based on subproduct_type. @return: Newly generated picking Id. """ + move_obj = self.pool.get('stock.move') picking_id = super(mrp_production,self).action_confirm(cr, uid, ids, context=context) product_uom_obj = self.pool.get('product.uom') for production in self.browse(cr, uid, ids): @@ -113,10 +114,11 @@ class mrp_production(osv.osv): 'location_id': source, 'location_dest_id': production.location_dest_id.id, 'move_dest_id': production.move_prod_id.id, - 'state': 'waiting', 'production_id': production.id } - self.pool.get('stock.move').create(cr, uid, data) + move_id = move_obj.create(cr, uid, data, context=context) + move_obj.action_confirm(cr, uid, [move_id], context=context) + return picking_id def _get_subproduct_factor(self, cr, uid, production_id, move_id=None, context=None): diff --git a/addons/point_of_sale/point_of_sale.py b/addons/point_of_sale/point_of_sale.py index c10a6c42f8e..ae6be542e94 100644 --- a/addons/point_of_sale/point_of_sale.py +++ b/addons/point_of_sale/point_of_sale.py @@ -112,10 +112,21 @@ class pos_config(osv.osv): return False return True + def _check_company_payment(self, cr, uid, ids, context=None): + for config in self.browse(cr, uid, ids, context=context): + journal_ids = [j.id for j in config.journal_ids] + if self.pool['account.journal'].search(cr, uid, [ + ('id', 'in', journal_ids), + ('company_id', '!=', config.company_id.id) + ], count=True, context=context): + return False + return True + _constraints = [ (_check_cash_control, "You cannot have two cash controls in one Point Of Sale !", ['journal_ids']), (_check_company_location, "The company of the stock location is different than the one of point of sale", ['company_id', 'stock_location_id']), (_check_company_journal, "The company of the sale journal is different than the one of point of sale", ['company_id', 'journal_id']), + (_check_company_payment, "The company of a payment method is different than the one of point of sale", ['company_id', 'journal_ids']), ] def name_get(self, cr, uid, ids, context=None): diff --git a/addons/point_of_sale/report/pos_order_report.py b/addons/point_of_sale/report/pos_order_report.py index abdf3845079..aa25052974b 100644 --- a/addons/point_of_sale/report/pos_order_report.py +++ b/addons/point_of_sale/report/pos_order_report.py @@ -58,7 +58,7 @@ class pos_order_report(osv.osv): sum(l.qty * u.factor) as product_qty, sum(l.qty * l.price_unit) as price_total, sum((l.qty * l.price_unit) * (l.discount / 100)) as total_discount, - (sum(l.qty*l.price_unit)/sum(l.qty * u.factor))::decimal(16,2) as average_price, + (sum(l.qty*l.price_unit)/sum(l.qty * u.factor))::decimal as average_price, sum(cast(to_char(date_trunc('day',s.date_order) - date_trunc('day',s.create_date),'DD') as int)) as delay_validation, s.partner_id as partner_id, s.state as state, diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index 0ac9ebe3162..ba5f66f4635 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -331,13 +331,14 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal c.height = height var ctx = c.getContext('2d'); ctx.drawImage(self.company_logo,0,0, width, height); - + self.company_logo_base64 = c.toDataURL(); logo_loaded.resolve(); }; self.company_logo.onerror = function(){ logo_loaded.reject(); }; + self.company_logo.crossOrigin = "anonymous"; self.company_logo.src = '/web/binary/company_logo' +'?_'+Math.random(); return logo_loaded; diff --git a/addons/project/report/project_report.py b/addons/project/report/project_report.py index 63650f9774b..2010a21ea16 100644 --- a/addons/project/report/project_report.py +++ b/addons/project/report/project_report.py @@ -85,7 +85,7 @@ class report_project_task_user(osv.osv): planned_hours as hours_planned, (extract('epoch' from (t.write_date-t.create_date)))/(3600*24) as closing_days, (extract('epoch' from (t.date_start-t.create_date)))/(3600*24) as opening_days, - abs((extract('epoch' from (t.date_deadline-t.write_date)))/(3600*24)) as delay_endings_days + (extract('epoch' from (t.date_deadline-now())))/(3600*24) as delay_endings_days FROM project_task t WHERE t.active = 'true' GROUP BY diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index e17b541f54e..338437a5ecf 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -701,7 +701,7 @@ class purchase_order(osv.osv): product_uom = self.pool.get('product.uom') price_unit = order_line.price_unit if order_line.product_uom.id != order_line.product_id.uom_id.id: - price_unit *= order_line.product_uom.factor + price_unit *= order_line.product_uom.factor / order_line.product_id.uom_id.factor if order.currency_id.id != order.company_id.currency_id.id: #we don't round the price_unit, as we may want to store the standard price with more digits than allowed by the currency price_unit = self.pool.get('res.currency').compute(cr, uid, order.currency_id.id, order.company_id.currency_id.id, price_unit, round=False, context=context) diff --git a/addons/sale/wizard/sale_make_invoice_advance.py b/addons/sale/wizard/sale_make_invoice_advance.py index 12081fae6b6..d18d4ec9b95 100644 --- a/addons/sale/wizard/sale_make_invoice_advance.py +++ b/addons/sale/wizard/sale_make_invoice_advance.py @@ -54,6 +54,9 @@ class sale_advance_payment_inv(osv.osv_memory): 'product_id': _get_advance_product, } + def _translate_advance(self, cr, uid, percentage=False, context=None): + return _("Advance of %s %%") if percentage else _("Advance of %s %s") + def onchange_method(self, cr, uid, ids, advance_payment_method, product_id, context=None): if advance_payment_method == 'percentage': return {'value': {'amount':0, 'product_id':False }} @@ -100,16 +103,17 @@ class sale_advance_payment_inv(osv.osv_memory): if wizard.advance_payment_method == 'percentage': inv_amount = sale.amount_total * wizard.amount / 100 if not res.get('name'): - res['name'] = _("Advance of %s %%") % (wizard.amount) + res['name'] = self._translate_advance(cr, uid, percentage=True, context=dict(context, lang=sale.partner_id.lang)) % (wizard.amount) else: inv_amount = wizard.amount if not res.get('name'): #TODO: should find a way to call formatLang() from rml_parse symbol = sale.pricelist_id.currency_id.symbol if sale.pricelist_id.currency_id.position == 'after': - res['name'] = _("Advance of %s %s") % (inv_amount, symbol) + symbol_order = (inv_amount, symbol) else: - res['name'] = _("Advance of %s %s") % (symbol, inv_amount) + symbol_order = (symbol, inv_amount) + res['name'] = self._translate_advance(cr, uid, context=dict(context, lang=sale.partner_id.lang)) % symbol_order # determine taxes if res.get('invoice_line_tax_id'): @@ -155,7 +159,6 @@ class sale_advance_payment_inv(osv.osv_memory): sale_obj.write(cr, uid, sale_id, {'invoice_ids': [(4, inv_id)]}, context=context) return inv_id - def create_invoices(self, cr, uid, ids, context=None): """ create invoices for the active sales orders """ sale_obj = self.pool.get('sale.order') diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 1bdaa3ed5f7..332151ec56e 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -1210,7 +1210,7 @@ class Binary(http.Controller): '/web/binary/company_logo', '/logo', '/logo.png', - ], type='http', auth="none") + ], type='http', auth="none", cors="*") def company_logo(self, dbname=None, **kw): imgname = 'logo.png' placeholder = functools.partial(get_module_resource, 'web', 'static', 'src', 'img') diff --git a/addons/website/models/ir_qweb.py b/addons/website/models/ir_qweb.py index 7eba7c585be..019eedd3686 100644 --- a/addons/website/models/ir_qweb.py +++ b/addons/website/models/ir_qweb.py @@ -438,6 +438,9 @@ class Contact(orm.AbstractModel): _name = 'website.qweb.field.contact' _inherit = ['ir.qweb.field.contact', 'website.qweb.field.many2one'] + def from_html(self, cr, uid, model, column, element, context=None): + return None + class QwebView(orm.AbstractModel): _name = 'website.qweb.field.qweb' _inherit = ['ir.qweb.field.qweb'] diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js index 4dda0ffbd35..6eb75694d03 100644 --- a/addons/website/static/src/js/website.editor.js +++ b/addons/website/static/src/js/website.editor.js @@ -1484,11 +1484,17 @@ this.changed($(e.target)); }, 'click button.filepicker': function () { - this.$('input[type=file]').click(); + var filepicker = this.$('input[type=file]'); + if (!_.isEmpty(filepicker)){ + filepicker[0].click(); + } }, 'click .js_disable_optimization': function () { this.$('input[name="disable_optimization"]').val('1'); - this.$('button.filepicker').click(); + var filepicker = this.$('button.filepicker'); + if (!_.isEmpty(filepicker)){ + filepicker[0].click(); + } }, 'change input[type=file]': 'file_selection', 'submit form': 'form_submit', diff --git a/addons/website/views/snippets.xml b/addons/website/views/snippets.xml index 20db73d6388..f620a057c41 100644 --- a/addons/website/views/snippets.xml +++ b/addons/website/views/snippets.xml @@ -30,9 +30,9 @@ Contact us

-