[MERGE] forward port branch 9.0 up to 838beb12de

This commit is contained in:
Christophe Simonis
2017-01-27 16:21:51 +01:00
17 changed files with 56 additions and 22 deletions
+1
View File
@@ -51,6 +51,7 @@
<field name="prefix">A</field>
<field eval="1" name="number_next"/>
<field eval="1" name="number_increment"/>
<field eval="False" name="company_id"/>
</record>
<!--
Invoice requests (deprecated)
+1
View File
@@ -722,6 +722,7 @@ class AccountInvoice(models.Model):
or not."""
return "%s-%s-%s-%s-%s-%s" % (
invoice_line['account_id'],
invoice_line.get('tax_ids', 'False'),
invoice_line.get('tax_line_id', 'False'),
invoice_line.get('product_id', 'False'),
invoice_line.get('analytic_account_id', 'False'),
@@ -61,7 +61,7 @@
<group>
<group>
<field name="product_id"
context="{'partner_id': parent.partner_id}"/>
context="parent and {'partner_id': parent.partner_id}"/>
<label for="quantity"/>
<div>
<field name="quantity" class="oe_inline"/>
+4
View File
@@ -203,6 +203,10 @@ class Employee(models.Model):
@api.multi
def write(self, vals):
if 'address_home_id' in vals:
account_id = vals.get('bank_account_id') or self.bank_account_id.id
if account_id:
self.env['res.partner.bank'].browse(account_id).partner_id = vals['address_home_id']
tools.image_resize_images(vals)
return super(Employee, self).write(vals)
+3 -2
View File
@@ -14,8 +14,9 @@ class Partner(models.Model):
try:
employee_group = self.env.ref('base.group_user')
for user in employee_group.users:
suggestions.append((user.partner_id.id, user.name, user.email))
hr_suggestions = [{'id': user.partner_id.id, 'name': user.name, 'email': user.email}
for user in employee_group.users]
suggestions.append(hr_suggestions)
return suggestions
except AccessError:
return suggestions
+1 -1
View File
@@ -81,7 +81,7 @@
<field name="country_id" options='{"no_open": True, "no_create": True}'/>
<field name="identification_id" groups="base.group_hr_user"/>
<field name="passport_id" groups="base.group_hr_user"/>
<field name="bank_account_id"/>
<field name="bank_account_id" context="{'default_partner_id': address_home_id}"/>
</group>
<group string="Contact Information">
<field name="address_home_id"
+1 -1
View File
@@ -82,7 +82,7 @@ class Usb(Escpos):
def _raw(self, msg):
""" Print any command sent in raw format """
if len(msg) != self.device.write(self.out_ep, msg, self.interface):
if len(msg) != self.device.write(self.out_ep, msg, self.interface, timeout=5000):
self.device.write(self.out_ep, self.errorText, self.interface)
raise TicketNotPrinted()
+3 -2
View File
@@ -24,8 +24,9 @@ class account_invoice(osv.osv):
"""Add BBA Structured Communication Type and change labels from 'reference' into 'communication' """
res = super(account_invoice, self)._get_reference_type(cursor, user,
context=context)
res[[i for i,x in enumerate(res) if x[0] == 'none'][0]] = ('none', 'Free Communication')
res.append(('bba', 'BBA Structured Communication'))
res[[i for i,x in enumerate(res) if x[0] == 'none'][0]] = \
('none', _('Free Communication'))
res.append(('bba', _('BBA Structured Communication')))
#l_logger.warning('reference_type = %s' %res )
return res
+2 -1
View File
@@ -11,7 +11,8 @@ class TestMassMailing(osv.TransientModel):
_columns = {
'email_to': fields.char('Recipients', required=True,
help='Comma-separated list of email addresses.'),
'mass_mailing_id': fields.many2one('mail.mass_mailing', 'Mailing', required=True),
'mass_mailing_id': fields.many2one(
'mail.mass_mailing', 'Mailing', required=True, ondelete='cascade'),
}
_defaults = {
+4 -3
View File
@@ -40,15 +40,15 @@
<table class="o_group o_inner_group o_label_nowrap">
<tr>
<td class="o_td_label"><label for="old_pwd" class="o_form_label">Old Password</label></td>
<td width="100%"><input type="password" class="o_form_field o_form_input" name="old_pwd" minlength="1" autofocus="autofocus"/></td>
<td width="100%"><input type="password" class="o_form_field o_form_input" name="old_pwd" minlength="1" autofocus="autofocus" autocomplete="current-password"/></td>
</tr>
<tr>
<td class="o_td_label"><label for="new_password" class="o_form_label">New Password</label></td>
<td width="100%"><input type="password" class="o_form_field o_form_input" name="new_password" minlength="1"/></td>
<td width="100%"><input type="password" class="o_form_field o_form_input" name="new_password" minlength="1" autocomplete="new-password"/></td>
</tr>
<tr>
<td class="o_td_label"><label for="confirm_pwd" class="o_form_label">Confirm New Password</label></td>
<td width="100%"><input type="password" class="o_form_field o_form_input" name="confirm_pwd" minlength="1"/></td>
<td width="100%"><input type="password" class="o_form_field o_form_input" name="confirm_pwd" minlength="1" autocomplete="new-password"/></td>
</tr>
</table>
@@ -647,6 +647,7 @@
t-att-tabindex="widget.node.attrs.tabindex"
t-att-autofocus="widget.node.attrs.autofocus"
t-att-placeholder="widget.node.attrs.placeholder"
t-att-autocomplete="widget.password ? 'new-password' : widget.node.attrs.autocomplete"
t-att-maxlength="widget.field.size"/>
</t>
<t t-name="FormSelection">
+1 -1
View File
@@ -246,7 +246,7 @@
<div class="form-group field-password">
<label for="password" class="control-label">Password</label>
<input type="password" name="password" id="password" class="form-control" required="required" t-att-autofocus="'autofocus' if login else None" maxlength="4096"/>
<input type="password" name="password" id="password" class="form-control" required="required" autocomplete="current-password" t-att-autofocus="'autofocus' if login else None" maxlength="4096"/>
</div>
<p class="alert alert-danger" t-if="error">
@@ -6,10 +6,6 @@ var website = require('website.website');
var base = require('web_editor.base');
require('website_sale.website_sale');
if(!$('.js_add_cart_variants[data-attribute_value_ids]').length) {
return $.Deferred().reject("DOM doesn't contain '.js_add_cart_variants[data-attribute_value_ids]'");
}
$('.oe_website_sale #add_to_cart, .oe_website_sale #products_grid .a-submit')
.off('click')
.removeClass('a-submit')
@@ -28,9 +24,14 @@ $('.oe_website_sale #add_to_cart, .oe_website_sale #products_grid .a-submit')
$modal.find('img:first').attr("src", "/web/image/product.product/" + product_id + "/image_medium");
// disable opacity on the <form> if currently active (in case the product is
// not published), as it interferes with bs modals
$form.addClass('css_options');
$modal.appendTo($form)
.modal()
.on('hidden.bs.modal', function () {
$form.removeClass('css_options'); // possibly reactivate opacity (see above)
$(this).remove();
});
+9
View File
@@ -686,6 +686,15 @@ class module(osv.osv):
if not self.pool['res.users'].has_group(cr, uid, 'base.group_system'):
raise openerp.exceptions.AccessDenied()
# One-click install is opt-in - cfr Issue #15225
ad_dir = openerp.tools.config.addons_data_dir
if not os.access(ad_dir, os.W_OK):
msg = (_("Automatic install of downloaded Apps is currently disabled.") + "\n\n" +
_("To enable it, make sure this directory exists and is writable on the server:") +
"\n%s" % ad_dir)
_logger.warning(msg)
raise openerp.exceptions.AccessError(msg)
apps_server = urlparse.urlparse(self.get_apps_server(cr, uid, context=context))
OPENERP = openerp.release.product_name.lower()
@@ -80,6 +80,12 @@ class test_inherits(common.TransactionCase):
self.assertIn(daughter, partner_demo.daughter_ids)
# search the partner from the daughter record
partners = self.env['res.partner'].search([('daughter_ids', 'like', 'not existing daugther')])
self.assertFalse(partners)
partners = self.env['res.partner'].search([('daughter_ids', 'not like', 'not existing daugther')])
self.assertIn(partner_demo, partners)
partners = self.env['res.partner'].search([('daughter_ids', '!=', False)])
self.assertIn(partner_demo, partners)
partners = self.env['res.partner'].search([('daughter_ids', 'in', daughter.ids)])
self.assertIn(partner_demo, partners)
+1 -1
View File
@@ -130,7 +130,7 @@ def initialize_sys_path():
global hooked
dd = tools.config.addons_data_dir
if dd not in ad_paths:
if os.access(dd, os.R_OK) and dd not in ad_paths:
ad_paths.append(dd)
for ad in tools.config['addons_path'].split(','):
+8 -1
View File
@@ -999,7 +999,14 @@ class expression(object):
if call_null:
o2m_op = 'in' if operator in NEGATIVE_TERM_OPERATORS else 'not in'
push(create_substitution_leaf(leaf, ('id', o2m_op, select_distinct_from_where_not_null(cr, column._fields_id, comodel._table)), model))
# determine ids from column._fields_id
if comodel._fields[column._fields_id].store:
ids1 = select_distinct_from_where_not_null(cr, column._fields_id, comodel._table)
else:
ids2 = comodel.search(cr, uid, [(column._fields_id, '!=', False)], context=context)
recs = comodel.browse(cr, SUPERUSER_ID, ids2, {'prefetch_fields': False})
ids1 = recs.mapped(column._fields_id).ids
push(create_substitution_leaf(leaf, ('id', o2m_op, ids1), model))
elif column._type == 'many2many':
rel_table, rel_id1, rel_id2 = column._sql_names(model)
+5 -4
View File
@@ -570,10 +570,11 @@ class configmanager(object):
def addons_data_dir(self):
d = os.path.join(self['data_dir'], 'addons', release.series)
if not os.path.exists(d):
os.makedirs(d, 0700)
else:
assert os.access(d, os.W_OK), \
"%s: directory is not writable" % d
try:
# try to make +rx placeholder dir, will need manual +w to activate it
os.makedirs(d, 0500)
except OSError:
logging.getLogger(__name__).debug('Failed to create addons data dir %s', d)
return d
@property