[MERGE] forward port branch 11.0 up to bdc62d8031

This commit is contained in:
Christophe Simonis
2019-06-07 13:00:07 +02:00
28 changed files with 326 additions and 66 deletions
+3 -2
View File
@@ -238,6 +238,7 @@ class AccountMove(models.Model):
@api.multi
def _reverse_move(self, date=None, journal_id=None, auto=False):
self.ensure_one()
date = date or fields.Date.today()
with self.env.norecompute():
reversed_move = self.copy(default={
'date': date,
@@ -502,8 +503,8 @@ class AccountMoveLine(models.Model):
is_unaffected_earnings_line = fields.Boolean(string="Is Unaffected Earnings Line", compute="_compute_is_unaffected_earnings_line", help="Tells whether or not this line belongs to an unaffected earnings account")
_sql_constraints = [
('credit_debit1', 'CHECK (credit*debit=0)', 'Wrong credit or debit value in accounting entry !'),
('credit_debit2', 'CHECK (credit+debit>=0)', 'Wrong credit or debit value in accounting entry !'),
('credit_debit1', 'CHECK (credit*debit=0)', 'Wrong credit or debit value in accounting entry! Credit or debit should be zero.'),
('credit_debit2', 'CHECK (credit+debit>=0)', 'Wrong credit or debit value in accounting entry! Credit and debit should be positive.'),
]
@api.model
+2 -7
View File
@@ -500,17 +500,12 @@ class AccountAssetDepreciationLine(models.Model):
@api.multi
def create_move(self, post_move=True):
created_moves = self.env['account.move']
# `line.move_id` was invalidated from the cache at each iteration
# To prevent to refetch `move_id` of all lines at each iteration just to check a UserError,
# we use an intermediar dict which stores the information the UserError check requires.
line_moves = {line: line.move_id for line in self}
if self.mapped('move_id'):
raise UserError(_('This depreciation is already linked to a journal entry! Please post or delete it.'))
for line in self:
if line_moves[line]:
raise UserError(_('This depreciation is already linked to a journal entry! Please post or delete it.'))
move_vals = self._prepare_move(line)
move = self.env['account.move'].create(move_vals)
line.write({'move_id': move.id, 'move_check': True})
line_moves[line] = move
created_moves |= move
if post_move and created_moves:
+3 -3
View File
@@ -162,7 +162,7 @@
<div class="o_row">
<field name="end_type" attrs="{'required': [('recurrency', '=', True)]}"/>
<field name="count" attrs="{'invisible': [('end_type', '!=', 'count')], 'required': [('recurrency', '=', True)]}"/>
<field name="final_date" attrs="{'invisible': [('end_type', '!=', 'end_date')], 'required': [('end_type', '=', 'end_date')]}"/>
<field name="final_date" attrs="{'invisible': [('end_type', '!=', 'end_date')], 'required': [('end_type', '=', 'end_date'), ('recurrency', '=', True)]}"/>
</div>
</group>
<group attrs="{'invisible': [('rrule_type', '!=', 'weekly')]}" name="weekdays">
@@ -182,10 +182,10 @@
attrs="{'required': [('month_by', '=', 'date'), ('rrule_type', '=', 'monthly')],
'invisible': [('month_by', '!=', 'date')]}"/>
<field name="byday" string="The"
attrs="{'required': [('month_by', '=', 'day'), ('rrule_type', '=', 'monthly')],
attrs="{'required': [('recurrency', '=', True), ('month_by', '=', 'day'), ('rrule_type', '=', 'monthly')],
'invisible': [('month_by', '!=', 'day')]}"/>
<field name="week_list" nolabel="1"
attrs="{'required': [('month_by', '=', 'day'), ('rrule_type', '=', 'monthly')],
attrs="{'required': [('recurrency', '=', True), ('month_by', '=', 'day'), ('rrule_type', '=', 'monthly')],
'invisible': [('month_by', '!=', 'day')]}"/>
</div>
</group>
@@ -10,6 +10,7 @@ Adds the possibility to specify the origin country of goods and the partner VAT
'depends': ['l10n_be_intrastat'],
'data': [
'views/account_invoice_line_view.xml',
'views/report_invoice.xml',
],
'auto_install': True,
}
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="report_invoice_document_intrastat_2019" inherit_id="account.report_invoice_document">
<xpath expr="//th[@class='hidden']" position="after">
<th class="text-right">Origin Country</th>
</xpath>
<xpath expr="//td[@class='hidden']" position="after">
<td class="text-right">
<span t-field="l.intrastat_product_origin_country_id"/>
</td>
</xpath>
</template>
<template id="report_intrastatinvoice_document_2019" inherit_id="report_intrastat.report_intrastatinvoice_document">
<xpath expr="//th[4]" position="after">
<th class="text-right">Origin Country</th>
</xpath>
<xpath expr="//td[4]" position="after">
<td class="text-right">
<span t-field="l.intrastat_product_origin_country_id"/>
</td>
</xpath>
</template>
<template id="report_invoice_layouted_intrastat_2019" inherit_id="sale.report_invoice_layouted">
<xpath expr="//t[@groups='sale.group_sale_layout']//th[1]" position="after">
<th class="text-right">Origin Country</th>
</xpath>
<xpath expr="//t[@groups='sale.group_sale_layout']//t[@t-as='l']//td[1]" position="after">
<td class="text-right">
<span t-field="l.intrastat_product_origin_country_id"/>
</td>
</xpath>
</template>
</odoo>
+62 -38
View File
@@ -2077,212 +2077,230 @@
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_04_new' model='account.account.tag'>
<field name='name'>401.04 Ventas y/o servicios gravados realizados en zona fronteriza norte</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_05_new' model='account.account.tag'>
<field name='name'>401.05 Ventas y/o servicios gravados realizados en zona fronteriza norte de contado</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_06_new' model='account.account.tag'>
<field name='name'>401.06 Ventas y/o servicios gravados realizados en zona fronteriza norte a crédito</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_04' model='account.account.tag'>
<field name='name'>401.04 Ventas y/o servicios gravados al 0%</field>
<field name='name'>401.07 Ventas y/o servicios gravados al 0%</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_05' model='account.account.tag'>
<field name='name'>401.05 Ventas y/o servicios gravados al 0% de contado</field>
<field name='name'>401.08 Ventas y/o servicios gravados al 0% de contado</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_06' model='account.account.tag'>
<field name='name'>401.06 Ventas y/o servicios gravados al 0% a crédito</field>
<field name='name'>401.09 Ventas y/o servicios gravados al 0% a crédito</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_07' model='account.account.tag'>
<field name='name'>401.07 Ventas y/o servicios exentos</field>
<field name='name'>401.10 Ventas y/o servicios exentos</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_08' model='account.account.tag'>
<field name='name'>401.08 Ventas y/o servicios exentos de contado</field>
<field name='name'>401.11 Ventas y/o servicios exentos de contado</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_09' model='account.account.tag'>
<field name='name'>401.09 Ventas y/o servicios exentos a crédito</field>
<field name='name'>401.12 Ventas y/o servicios exentos a crédito</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_10' model='account.account.tag'>
<field name='name'>401.10 Ventas y/o servicios gravados a la tasa general nacionales partes relacionadas</field>
<field name='name'>401.13 Ventas y/o servicios gravados a la tasa general nacionales partes relacionadas</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_11' model='account.account.tag'>
<field name='name'>401.11 Ventas y/o servicios gravados a la tasa general extranjeros partes relacionadas</field>
<field name='name'>401.14 Ventas y/o servicios gravados a la tasa general extranjeros partes relacionadas</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_12' model='account.account.tag'>
<field name='name'>401.12 Ventas y/o servicios gravados al 0% nacionales partes relacionadas</field>
<field name='name'>401.15 Ventas y/o servicios gravados al 0% nacionales partes relacionadas</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_13' model='account.account.tag'>
<field name='name'>401.13 Ventas y/o servicios gravados al 0% extranjeros partes relacionadas</field>
<field name='name'>401.16 Ventas y/o servicios gravados al 0% extranjeros partes relacionadas</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_14' model='account.account.tag'>
<field name='name'>401.14 Ventas y/o servicios exentos nacionales partes relacionadas</field>
<field name='name'>401.17 Ventas y/o servicios exentos nacionales partes relacionadas</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_15' model='account.account.tag'>
<field name='name'>401.15 Ventas y/o servicios exentos extranjeros partes relacionadas</field>
<field name='name'>401.18 Ventas y/o servicios exentos extranjeros partes relacionadas</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_16' model='account.account.tag'>
<field name='name'>401.16 Ingresos por servicios administrativos</field>
<field name='name'>401.19 Ingresos por servicios administrativos</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_17' model='account.account.tag'>
<field name='name'>401.17 Ingresos por servicios administrativos nacionales partes relacionadas</field>
<field name='name'>401.20 Ingresos por servicios administrativos nacionales partes relacionadas</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_18' model='account.account.tag'>
<field name='name'>401.18 Ingresos por servicios administrativos extranjeros partes relacionadas</field>
<field name='name'>401.21 Ingresos por servicios administrativos extranjeros partes relacionadas</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_19' model='account.account.tag'>
<field name='name'>401.19 Ingresos por servicios profesionales</field>
<field name='name'>401.22 Ingresos por servicios profesionales</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_20' model='account.account.tag'>
<field name='name'>401.20 Ingresos por servicios profesionales nacionales partes relacionadas</field>
<field name='name'>401.23 Ingresos por servicios profesionales nacionales partes relacionadas</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_21' model='account.account.tag'>
<field name='name'>401.21 Ingresos por servicios profesionales extranjeros partes relacionadas</field>
<field name='name'>401.24 Ingresos por servicios profesionales extranjeros partes relacionadas</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_22' model='account.account.tag'>
<field name='name'>401.22 Ingresos por arrendamiento</field>
<field name='name'>401.25 Ingresos por arrendamiento</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_23' model='account.account.tag'>
<field name='name'>401.23 Ingresos por arrendamiento nacionales partes relacionadas</field>
<field name='name'>401.26 Ingresos por arrendamiento nacionales partes relacionadas</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_24' model='account.account.tag'>
<field name='name'>401.24 Ingresos por arrendamiento extranjeros partes relacionadas</field>
<field name='name'>401.27 Ingresos por arrendamiento extranjeros partes relacionadas</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_25' model='account.account.tag'>
<field name='name'>401.25 Ingresos por exportación</field>
<field name='name'>401.28 Ingresos por exportación</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_26' model='account.account.tag'>
<field name='name'>401.26 Ingresos por comisiones</field>
<field name='name'>401.29 Ingresos por comisiones</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_27' model='account.account.tag'>
<field name='name'>401.27 Ingresos por maquila</field>
<field name='name'>401.30 Ingresos por maquila</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_28' model='account.account.tag'>
<field name='name'>401.28 Ingresos por coordinados</field>
<field name='name'>401.31 Ingresos por coordinados</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_29' model='account.account.tag'>
<field name='name'>401.29 Ingresos por regalías</field>
<field name='name'>401.32 Ingresos por regalías</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_30' model='account.account.tag'>
<field name='name'>401.30 Ingresos por asistencia técnica</field>
<field name='name'>401.33 Ingresos por asistencia técnica</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_31' model='account.account.tag'>
<field name='name'>401.31 Ingresos por donativos</field>
<field name='name'>401.34 Ingresos por donativos</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_32' model='account.account.tag'>
<field name='name'>401.32 Ingresos por intereses (actividad propia)</field>
<field name='name'>401.35 Ingresos por intereses (actividad propia)</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_33' model='account.account.tag'>
<field name='name'>401.33 Ingresos de copropiedad</field>
<field name='name'>401.36 Ingresos de copropiedad</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_34' model='account.account.tag'>
<field name='name'>401.34 Ingresos por fideicomisos</field>
<field name='name'>401.37 Ingresos por fideicomisos</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_35' model='account.account.tag'>
<field name='name'>401.35 Ingresos por factoraje financiero</field>
<field name='name'>401.38 Ingresos por factoraje financiero</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_36' model='account.account.tag'>
<field name='name'>401.36 Ingresos por arrendamiento financiero</field>
<field name='name'>401.39 Ingresos por arrendamiento financiero</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_37' model='account.account.tag'>
<field name='name'>401.37 Ingresos de extranjeros con establecimiento en el país</field>
<field name='name'>401.40 Ingresos de extranjeros con establecimiento en el país</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
</record>
<record id='account_tag_401_38' model='account.account.tag'>
<field name='name'>401.38 Otros ingresos propios</field>
<field name='name'>401.41 Otros ingresos propios</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>A</field>
@@ -2293,20 +2311,26 @@
<field name='applicability'>accounts</field>
<field name='nature'>D</field>
</record>
<record id='account_tag_402_02_new' model='account.account.tag'>
<field name='name'>402.02 Devoluciones, descuentos o bonificaciones sobre ventas y/o servicios en zona fronteriza norte</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>D</field>
</record>
<record id='account_tag_402_02' model='account.account.tag'>
<field name='name'>402.02 Devoluciones, descuentos o bonificaciones sobre ventas y/o servicios al 0%</field>
<field name='name'>402.03 Devoluciones, descuentos o bonificaciones sobre ventas y/o servicios al 0%</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>D</field>
</record>
<record id='account_tag_402_03' model='account.account.tag'>
<field name='name'>402.03 Devoluciones, descuentos o bonificaciones sobre ventas y/o servicios exentos</field>
<field name='name'>402.04 Devoluciones, descuentos o bonificaciones sobre ventas y/o servicios exentos</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>D</field>
</record>
<record id='account_tag_402_04' model='account.account.tag'>
<field name='name'>402.04 Devoluciones, descuentos o bonificaciones de otros ingresos</field>
<field name='name'>402.05 Devoluciones, descuentos o bonificaciones de otros ingresos</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
<field name='nature'>D</field>
+1 -1
View File
@@ -170,7 +170,7 @@ class AcquirerAdyen(models.Model):
'sessionValidity': tmp_date.isoformat('T')[:19] + "Z",
'resURL': urls.url_join(base_url, AdyenController._return_url),
'merchantReturnData': json.dumps({'return_url': '%s' % values.pop('return_url')}) if values.get('return_url', '') else False,
'shopperEmail': values.get('partner_email', ''),
'shopperEmail': values.get('partner_email') or values.get('billing_partner_email') or '',
})
values['merchantSig'] = self._adyen_generate_merchant_sig_sha256('in', values)
+3 -3
View File
@@ -85,9 +85,9 @@ class AccountInvoice(models.Model):
self.currency_id = self.purchase_id.currency_id
vendor_ref = self.purchase_id.partner_ref
if vendor_ref:
self.reference = ", ".join([self.reference, vendor_ref]) if (
self.reference and vendor_ref not in self.reference) else vendor_ref
if vendor_ref and (not self.reference or (
vendor_ref + ", " not in self.reference and not self.reference.endswith(vendor_ref))):
self.reference = ", ".join([self.reference, vendor_ref]) if self.reference else vendor_ref
new_lines = self.env['account.invoice.line']
for line in self.purchase_id.order_line - self.invoice_line_ids.mapped('purchase_line_id'):
+5 -1
View File
@@ -1021,11 +1021,15 @@ class ProcurementRule(models.Model):
if price_unit and seller and line.order_id.currency_id and seller.currency_id != line.order_id.currency_id:
price_unit = seller.currency_id.compute(price_unit, line.order_id.currency_id)
return {
res = {
'product_qty': line.product_qty + procurement_uom_po_qty,
'price_unit': price_unit,
'move_dest_ids': [(4, x.id) for x in values.get('move_dest_ids', [])]
}
orderpoint_id = values.get('orderpoint_id')
if orderpoint_id:
res['orderpoint_id'] = orderpoint_id.id
return res
@api.multi
def _prepare_purchase_order_line(self, product_id, product_qty, product_uom, values, po, partner):
+1 -1
View File
@@ -170,7 +170,7 @@ class Route(models.Model):
@api.onchange('warehouse_selectable')
def _onchange_warehouse_selectable(self):
if not self.warehouse_selectable:
self.warehouse_ids = []
self.warehouse_ids = [(5, 0, 0)]
def write(self, values):
'''when a route is deactivated, deactivate also its pull and push rules'''
@@ -1186,6 +1186,7 @@ var AbstractFieldBinary = AbstractField.extend({
}
},
on_clear: function () {
this.$('.o_input_file').val('');
this.set_filename('');
this._setValue(false);
this._render();
@@ -1718,6 +1718,35 @@ QUnit.module('basic_fields', {
list.destroy();
});
QUnit.test("binary fields input value is empty whean clearing after uploading", function (assert) {
assert.expect(2);
var form = createView({
View: FormView,
model: 'partner',
data: this.data,
arch: '<form string="Partners">' +
'<field name="document" filename="foo"/>' +
'<field name="foo"/>' +
'</form>',
res_id: 1,
});
form.$buttons.find('.btn:contains("Edit")').click();
// // We need to convert the input type since we can't programmatically set the value of a file input
form.$('.o_input_file').attr('type', 'text').val('coucou.txt');
assert.strictEqual(form.$('.o_input_file').val(), 'coucou.txt',
"input value should be changed to \"coucou.txt\"");
form.$('.o_field_binary_file > .o_clear_file_button').click();
assert.strictEqual(form.$('.o_input_file').val(), '',
"input value should be empty");
form.destroy();
});
QUnit.test('field text in editable list view', function (assert) {
assert.expect(1);
@@ -1392,6 +1392,7 @@ var LinkDialog = Dialog.extend({
}
this.data.range = range.create(sc, so, ec, eo);
$(editable).data("range", this.data.range);
this.data.range.select();
} else {
nodes = dom.ancestor(sc, dom.isAnchor).childNodes;
@@ -5,6 +5,7 @@ var FormView = require('web.FormView');
var testUtils = require('web.test_utils');
var core = require('web.core');
var web_editor = require('web_editor.editor');
var LinkDialog = require('web_editor.widget').LinkDialog;
var _t = core._t;
@@ -324,4 +325,64 @@ QUnit.test('html_frame saving in edit mode (editor and content fully loaded)', f
});
QUnit.test('discard on link dialog should select content of link in web_editor', function (assert) {
var done = assert.async();
assert.expect(5);
var form = testUtils.createView({
View: FormView,
model: 'mass.mailing',
data: this.data,
arch: '<form string="Partners">' +
'<field name="body"/>' +
'</form>',
res_id: 1,
});
form.$buttons.find('.o_form_button_edit').click();
assert.strictEqual(form.$('.note-editable').html(), '<div class="field_body">yep</div>',
"should have rendered the field correctly in edit");
var $fieldEdit = form.$('.oe_form_field[name="body"]');
var $editable = $fieldEdit.find('.field_body');
// create range, default startoffset:0, endOffset:length of element
var range = document.createRange();
var selection = window.getSelection();
range.selectNodeContents($editable[0].childNodes[0]);
selection.removeAllRanges();
selection.addRange(range);
var content = selection.getRangeAt(range);
assert.strictEqual(content.startOffset, 0, "selection starts at index 0");
assert.strictEqual(content.endOffset, 3, "selection ends at index 3");
var defLinkDialog = $.Deferred();
testUtils.patch(LinkDialog, {
init: function () {
this._super.apply(this, arguments);
this.opened(defLinkDialog.resolve.bind(defLinkDialog));
}
});
// click on 'link' button
$fieldEdit.find('.note-toolbar button[data-event="showLinkDialog"]').click();
defLinkDialog.then(function () {
$('.modal .modal-footer .btn-default').click(); // click on 'discard'
var content = selection.getRangeAt(range);
assert.strictEqual(content.startOffset, 0,
"selection should remain same after discarding modal, starts at index 0");
assert.strictEqual(content.endOffset, 3,
"selection should remain same after discarding modal, ends at index 3");
testUtils.unpatch(LinkDialog);
form.destroy();
done();
});
});
});
+6 -1
View File
@@ -93,7 +93,7 @@ class Website(Home):
if request.env['res.users'].browse(request.uid).has_group('base.group_user'):
redirect = b'/web?' + request.httprequest.query_string
else:
redirect = '/'
redirect = '/my'
return http.redirect_with_hash(redirect)
return response
@@ -443,3 +443,8 @@ class WebsiteBinary(http.Controller):
if unique:
kw['unique'] = unique
return Binary().content_image(**kw)
@http.route(['/favicon.ico'], type='http', auth='public', website=True)
def favicon(self, **kw):
# when opening a pdf in chrome, chrome tries to open the default favicon url
return self.content_image(model='website', id=str(request.website.id), field='favicon', **kw)
+11
View File
@@ -0,0 +1,11 @@
Mexico, 2018-12-05
I hereby agree to the terms of the Odoo Individual Contributor License
Agreement v1.0.
I declare that I am authorized and able to make this agreement and sign this
declaration.
Signed,
Luis Arturo Íñiguez Hernández luis.iniguezh@gmail.com https://github.com/luisiniguezh
+11
View File
@@ -0,0 +1,11 @@
Italy, 2019-06-04
I hereby agree to the terms of the Odoo Individual Contributor License
Agreement v1.0.
I declare that I am authorized and able to make this agreement and sign this
declaration.
Signed,
Michele Zaccheddu michelezak93@gmail.com https://github.com/MicheleZak
+8
View File
@@ -737,3 +737,11 @@ class IrActionsActClient(models.Model):
for record in self:
params = record.params
record.params_store = repr(params) if isinstance(params, dict) else params
def _get_default_form_view(self):
doc = super(IrActionsActClient, self)._get_default_form_view()
params = doc.find(".//field[@name='params']")
params.getparent().remove(params)
params_store = doc.find(".//field[@name='params_store']")
params_store.getparent().remove(params_store)
return doc
+6 -5
View File
@@ -719,7 +719,7 @@ class IrModelFields(models.Model):
else:
if column_rename:
raise UserError(_('Can only rename one field at a time!'))
column_rename = (obj._table, item.name, vals['name'], item.index)
column_rename = (obj._table, item.name, vals['name'], item.index, item.store)
# We don't check the 'state', because it might come from the context
# (thus be set for multiple fields) and will be ignored anyway.
@@ -737,10 +737,11 @@ class IrModelFields(models.Model):
if column_rename:
# rename column in database, and its corresponding index if present
table, oldname, newname, index = column_rename
self._cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO "%s"' % (table, oldname, newname))
if index:
self._cr.execute('ALTER INDEX "%s_%s_index" RENAME TO "%s_%s_index"' % (table, oldname, table, newname))
table, oldname, newname, index, stored = column_rename
if stored:
self._cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO "%s"' % (table, oldname, newname))
if index:
self._cr.execute('ALTER INDEX "%s_%s_index" RENAME TO "%s_%s_index"' % (table, oldname, table, newname))
if column_rename or patched_models:
# setup models, this will reload all manual fields in registry
+2 -2
View File
@@ -109,7 +109,7 @@
</group>
<group string="Advanced Properties" groups="base.group_no_one">
<field name="related"/>
<field name="depends"/>
<field name="depends" attrs="{'required': [('compute', 'not in', [False, ''])]}"/>
<field name="compute" widget="ace" options="{'mode': 'python'}"/>
</group>
<div groups="base.group_no_one">
@@ -295,7 +295,7 @@
</group>
<group string="Advanced Properties" groups="base.group_no_one">
<field name="related"/>
<field name="depends" attrs="{'required': [('compute', '!=', False)] }"/>
<field name="depends" attrs="{'required': [('compute', 'not in', [False, ''])]}"/>
<field name="compute" widget="ace" options="{'mode': 'python'}"/>
</group>
<div groups="base.group_no_one">
+13
View File
@@ -0,0 +1,13 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, SUPERUSER_ID
# TO REMOVE in master
def uninstall_test_pylint(cr):
env = api.Environment(cr, SUPERUSER_ID, {})
env['ir.module.module'].search([
('name', '=', 'test_pylint'),
('state', '=', 'installed')
]).write({'state': 'uninstalled'})
+12
View File
@@ -0,0 +1,12 @@
# -*- coding: utf-8 -*-
{
'name': 'test-lint',
'version': '0.1',
'category': 'Tests',
'description': """A module to test Odoo code with various linters.""",
'maintainer': 'Odoo SA',
'depends': ['base'],
'installable': True,
'auto_install': False,
'pre_init_hook': 'uninstall_test_pylint'
}
+2
View File
@@ -0,0 +1,2 @@
from . import test_pylint
from . import test_ecmascript
@@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import logging
import os
import re
import subprocess
from unittest import skipIf
from odoo.tests.common import TransactionCase
from odoo import tools
from odoo.modules import get_modules, get_module_path
MAX_ES_VERSION = 'es5'
_logger = logging.getLogger(__name__)
try:
es_check = tools.misc.find_in_path('es-check')
except IOError:
es_check = None
@skipIf(es_check is None, "es-check tool not found on this system")
class TestECMAScriptVersion(TransactionCase):
longMessage = True
def test_ecmascript_version(self):
""" Test that there is no unsupported ecmascript in javascript files """
black_re = re.compile(r'summernote.+(intro\.js|outro.js)$')
mod_paths = [get_module_path(m) for m in get_modules()]
files_to_check = []
for p in mod_paths:
for dp, _, file_names in os.walk(p):
if 'static/test' in dp:
continue
for fn in file_names:
fullpath_name = os.path.join(dp, fn)
if fullpath_name.endswith('.js') and not black_re.search(fullpath_name):
files_to_check.append(fullpath_name)
_logger.info('Testing %s js files', len(files_to_check))
cmd = [es_check, MAX_ES_VERSION] + files_to_check
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = process.communicate()
self.assertEqual(process.returncode, 0, msg=out)
+1 -1
View File
@@ -3,7 +3,7 @@
'name': 'test-eval',
'version': '0.1',
'category': 'Tests',
'description': """A module to test Odoo with pylint.""",
'description': """Deprecated empty module in favor of test-lint.""",
'maintainer': 'Odoo SA',
'depends': ['base'],
'installable': True,
@@ -1 +0,0 @@
from . import test_pylint