Skip to content

Commit

Permalink
[MERGE] forward port branch 11.0 up to b29b545
Browse files Browse the repository at this point in the history
  • Loading branch information
KangOl committed Oct 16, 2018
2 parents a9f11fb + b29b545 commit 41bf8ce
Show file tree
Hide file tree
Showing 27 changed files with 329 additions and 68 deletions.
2 changes: 1 addition & 1 deletion addons/account/models/account_move.py
Expand Up @@ -947,7 +947,7 @@ def create(self, vals):
'credit': tax_vals['amount'] < 0 and -tax_vals['amount'] or 0.0,
'analytic_account_id': vals.get('analytic_account_id') if tax.analytic else False,
}
bank = self.env["account.bank.statement"].browse(vals.get('statement_id'))
bank = self.env["account.bank.statement.line"].browse(vals.get('statement_line_id')).statement_id
if bank.currency_id != bank.company_id.currency_id:
ctx = {}
if 'date' in vals:
Expand Down
5 changes: 3 additions & 2 deletions addons/account/views/account_view.xml
Expand Up @@ -412,8 +412,9 @@
</div>
<group>
<group>
<field name="bank_acc_number"/>
<field name="bank_id"/>
<field name="bank_account_id"/>
<field name="bank_acc_number" attrs="{'readonly': [('bank_account_id', '!=', False)]}"/>
<field name="bank_id" attrs="{'readonly': [('bank_account_id', '!=', False)]}"/>
</group>
<group>
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
Expand Down
2 changes: 2 additions & 0 deletions addons/board/static/src/js/board_view.js
Expand Up @@ -247,6 +247,8 @@ var BoardRenderer = FormRenderer.extend({
// the action does not exist anymore
return $.when();
}
// tz and lang are saved in the custom view
// override the language to take the current one
var rawContext = new Context(params.context, action.context, {lang: session.user_context.lang});
var context = pyUtils.eval('context', rawContext);
var domain = params.domain || pyUtils.eval('domain', action.domain || '[]', action.context);
Expand Down
45 changes: 45 additions & 0 deletions addons/board/static/tests/dashboard_tests.js
Expand Up @@ -783,4 +783,49 @@ QUnit.test("Views should be loaded in the user's language", function (assert) {
form.destroy();
});

QUnit.test("Views should be loaded in the user's language", function (assert) {
assert.expect(2);

var form = createView({
View: FormView,
model: 'board',
data: this.data,
session: {user_context: {lang: 'fr_FR'}},
arch: '<form string="My Dashboard">' +
'<board style="2-1">' +
'<column>' +
'<action context="{\'lang\': \'en_US\'}" view_mode="list" string="ABC" name="51" domain="[]"></action>' +
'</column>' +
'</board>' +
'</form>',
mockRPC: function (route, args) {
if (route === "/web/dataset/search_read") {
assert.deepEqual(args.context, {lang: 'fr_FR'},
'The data should be loaded with the correct context');
}

if (route === '/web/action/load') {
return $.when({
res_model: 'partner',
views: [[4, 'list']],
});
}
return this._super.apply(this, arguments);
},
archs: {
'partner,4,list':
'<list string="Partner"><field name="foo"/></list>',
},

interceptsPropagate: {
load_views: function (ev) {
assert.deepEqual(ev.data.context.eval(), {lang: 'fr_FR'},
'The views should be loaded with the correct context');
}
},
});

form.destroy();
});

});
4 changes: 3 additions & 1 deletion addons/mrp/models/mrp_workorder.py
Expand Up @@ -323,8 +323,10 @@ def record_production(self):
if self.product_id.tracking != 'none':
qty_to_add = float_round(self.qty_producing * move.unit_factor, precision_rounding=rounding)
move._generate_consumed_move_line(qty_to_add, self.final_lot_id)
else:
elif len(move._get_move_lines()) < 2:
move.quantity_done += float_round(self.qty_producing * move.unit_factor, precision_rounding=rounding)
else:
move._set_quantity_done(move.quantity_done + float_round(self.qty_producing * move.unit_factor, precision_rounding=rounding))

# Transfer quantities from temporary to final move lots or make them final
for move_line in self.active_move_line_ids:
Expand Down
8 changes: 8 additions & 0 deletions addons/point_of_sale/static/src/js/screens.js
Expand Up @@ -34,6 +34,7 @@ var core = require('web.core');
var rpc = require('web.rpc');
var utils = require('web.utils');
var field_utils = require('web.field_utils');
var BarcodeEvents = require('barcodes.BarcodeEvents').BarcodeEvents;

var QWeb = core.qweb;
var _t = core._t;
Expand Down Expand Up @@ -1678,6 +1679,13 @@ var PaymentScreenWidget = ScreenWidget.extend({
// also called explicitly to handle some keydown events that
// do not generate keypress events.
this.keyboard_handler = function(event){
// On mobile Chrome BarcodeEvents relies on an invisible
// input being filled by a barcode device. Let events go
// through when this input is focused.
if (BarcodeEvents.$barcodeInput && BarcodeEvents.$barcodeInput.is(":focus")) {
return;
}

var key = '';

if (event.type === "keypress") {
Expand Down
2 changes: 1 addition & 1 deletion addons/product_margin/models/product_product.py
Expand Up @@ -107,7 +107,7 @@ def _compute_product_margin_fields_values(self, field_names=None):
select
sum(l.price_unit * l.quantity)/nullif(sum(l.quantity),0) as avg_unit_price,
sum(l.quantity) as num_qty,
sum(l.quantity * (l.price_subtotal/(nullif(l.quantity,0)))) as total,
sum(l.quantity * (l.price_subtotal_signed/(nullif(l.quantity,0)))) as total,
sum(l.quantity * pt.list_price) as sale_expected
from account_invoice_line l
left join account_invoice i on (l.invoice_id = i.id)
Expand Down
2 changes: 1 addition & 1 deletion addons/purchase/models/purchase.py
Expand Up @@ -603,7 +603,7 @@ def _compute_tax_id(self):
taxes = line.product_id.supplier_taxes_id.filtered(lambda r: not line.company_id or r.company_id == line.company_id)
line.taxes_id = fpos.map_tax(taxes, line.product_id, line.order_id.partner_id) if fpos else taxes

@api.depends('invoice_lines.invoice_id.state', 'invoice_lines.quantity')
@api.depends('invoice_lines.invoice_id.state', 'invoice_lines.quantity', 'invoice_lines.uom_id')
def _compute_qty_invoiced(self):
for line in self:
qty = 0.0
Expand Down
4 changes: 2 additions & 2 deletions addons/purchase_requisition/models/purchase_requisition.py
Expand Up @@ -44,8 +44,8 @@ class PurchaseRequisition(models.Model):

def _get_picking_in(self):
pick_in = self.env.ref('stock.picking_type_in')
if not pick_in:
company = self.env['res.company']._company_default_get('purchase.requisition')
company = self.env['res.company']._company_default_get('purchase.requisition')
if not pick_in or pick_in.sudo().warehouse_id.company_id.id != company.id:
pick_in = self.env['stock.picking.type'].search(
[('warehouse_id.company_id', '=', company.id), ('code', '=', 'incoming')],
limit=1,
Expand Down
4 changes: 2 additions & 2 deletions addons/sale/static/src/js/sale.js
Expand Up @@ -21,8 +21,8 @@ KanbanRecord.include({
ev.preventDefault();

this.$target_input = $('<input>');
this.$('.o_kanban_primary_bottom').html(this.$target_input);
this.$('.o_kanban_primary_bottom').prepend(_t("Set an invoicing target: "));
this.$('.o_kanban_primary_bottom:last').html(this.$target_input);
this.$('.o_kanban_primary_bottom:last').prepend(_t("Set an invoicing target: "));
this.$target_input.focus();

var self = this;
Expand Down
2 changes: 1 addition & 1 deletion addons/sale_stock/models/sale_order.py
Expand Up @@ -164,7 +164,7 @@ def _compute_qty_delivered(self):
qty = 0.0
for move in line.move_ids.filtered(lambda r: r.state == 'done' and not r.scrapped):
if move.location_dest_id.usage == "customer":
if not move.origin_returned_move_id:
if not move.origin_returned_move_id or (move.origin_returned_move_id and move.to_refund):
qty += move.product_uom._compute_quantity(move.product_uom_qty, line.product_uom)
elif move.location_dest_id.usage != "customer" and move.to_refund:
qty -= move.product_uom._compute_quantity(move.product_uom_qty, line.product_uom)
Expand Down
2 changes: 1 addition & 1 deletion addons/sale_timesheet/views/hr_timesheet_templates.xml
Expand Up @@ -155,7 +155,7 @@
<td>
<div t-if="repartition_employee_max" class="progress" t-att-style="'width: ' + str(repartition_employee[employee_id]['total'] / repartition_employee_max * 100) +'%'">

<t t-set="total" t-value="repartition_employee[employee_id]['total']" />
<t t-set="total" t-value="repartition_employee[employee_id]['total'] or 1.0" />
<t t-set="billable_fixed" t-value="repartition_employee[employee_id]['billable_fixed']" />
<t t-set="billable_time" t-value="repartition_employee[employee_id]['billable_time']" />
<t t-set="non_billable" t-value="repartition_employee[employee_id]['non_billable']" />
Expand Down
38 changes: 36 additions & 2 deletions addons/web/static/src/js/fields/basic_fields.js
Expand Up @@ -948,6 +948,9 @@ var HandleWidget = AbstractField.extend({

var FieldEmail = InputField.extend({
className: 'o_field_email',
events: _.extend({}, InputField.prototype.events, {
'click': '_onClick',
}),
prefix: 'mailto',
supportedFieldTypes: ['char'],

Expand Down Expand Up @@ -988,7 +991,21 @@ var FieldEmail = InputField.extend({
this.$el.text(this.value)
.addClass('o_form_uri o_text_overflow')
.attr('href', this.prefix + ':' + this.value);
}
},

//--------------------------------------------------------------------------
// Handlers
//--------------------------------------------------------------------------

/**
* Prevent the URL click from opening the record (when used on a list).
*
* @private
* @param {MouseEvent} ev
*/
_onClick: function (ev) {
ev.stopPropagation();
},
});

var FieldPhone = FieldEmail.extend({
Expand All @@ -1015,6 +1032,9 @@ var FieldPhone = FieldEmail.extend({

var UrlWidget = InputField.extend({
className: 'o_field_url',
events: _.extend({}, InputField.prototype.events, {
'click': '_onClick',
}),
supportedFieldTypes: ['char'],

/**
Expand Down Expand Up @@ -1056,7 +1076,21 @@ var UrlWidget = InputField.extend({
.addClass('o_form_uri o_text_overflow')
.attr('target', '_blank')
.attr('href', this.value);
}
},

//--------------------------------------------------------------------------
// Handlers
//--------------------------------------------------------------------------

/**
* Prevent the URL click from opening the record (when used on a list).
*
* @private
* @param {MouseEvent} ev
*/
_onClick: function (ev) {
ev.stopPropagation();
},
});

var AbstractFieldBinary = AbstractField.extend({
Expand Down
4 changes: 3 additions & 1 deletion addons/web/static/src/js/fields/relational_fields.js
Expand Up @@ -2306,10 +2306,12 @@ var FieldRadio = FieldSelection.extend({
* a FieldMany2one for its value.
* Its intern representation is similar to the many2one (a datapoint with a
* `name_get` as data).
* Note that there is some logic to support char field because of one use in our
* codebase, but this use should be removed along with this note.
*/
var FieldReference = FieldMany2One.extend({
specialData: "_fetchSpecialReference",
supportedFieldTypes: ['char', 'reference'],
supportedFieldTypes: ['reference'],
template: 'FieldReference',
events: _.extend({}, FieldMany2One.prototype.events, {
'change select': '_onSelectionChange',
Expand Down
64 changes: 44 additions & 20 deletions addons/web/static/src/js/views/basic/basic_model.js
Expand Up @@ -904,27 +904,51 @@ var BasicModel = AbstractModel.extend({
route: '/web/dataset/resequence',
params: params,
})
.then(function () {
var offset = options.offset ? options.offset : 0;
var old_data = data.data.slice();
data.data = _.sortBy(data.data, function (d) {
if (_.contains(resIDs, self.localData[d].res_id)) {
return _.indexOf(resIDs, self.localData[d].res_id) + offset;
} else {
return _.indexOf(old_data, d);
}
});
data.res_ids = [];
_.each(data.data, function (d) {
var dataPoint = self.localData[d];
if (dataPoint.type === 'record') {
data.res_ids.push(dataPoint.res_id);
} else {
data.res_ids = data.res_ids.concat(dataPoint.res_ids);
.then(function (wasResequenced) {
if (!wasResequenced) {
// the field on which the resequence was triggered does not
// exist, so no resequence happened server-side
return $.when();
}
var field = params.field ? params.field : 'sequence';

return self._rpc({
model: modelName,
method: 'read',
args: [resIDs, [field]],
}).then(function (records) {
if (data.data.length) {
var dataType = self.localData[data.data[0]].type;
if (dataType === 'record') {
_.each(data.data, function (dataPoint) {
var recordData = self.localData[dataPoint].data;
var inRecords = _.findWhere(records, {id: recordData.id});
if (inRecords) {
recordData[field] = inRecords[field];
}
});
data.data = _.sortBy(data.data, function (d) {
return self.localData[d].data[field];
});
}
if (dataType === 'list') {
data.data = _.sortBy(data.data, function (d) {
return _.indexOf(resIDs, self.localData[d].res_id)
});
}
}
});
self._updateParentResIDs(data);
return parentID;
data.res_ids = [];
_.each(data.data, function (d) {
var dataPoint = self.localData[d];
if (dataPoint.type === 'record') {
data.res_ids.push(dataPoint.res_id);
} else {
data.res_ids = data.res_ids.concat(dataPoint.res_ids);
}
});
self._updateParentResIDs(data);
return parentID;
})
});
},
/**
Expand Down
Expand Up @@ -77,7 +77,7 @@ var SidebarFilter = Widget.extend(FieldManagerMixin, {
self.model.get(recordID),
{
mode: 'edit',
can_create: false,
attrs: {can_create: false},
});
});
defs.push(def);
Expand Down
6 changes: 4 additions & 2 deletions addons/web/static/src/js/views/kanban/kanban_record.js
Expand Up @@ -450,10 +450,12 @@ var KanbanRecord = Widget.extend({
ischild = false;
}
var test_event = events && events.click && (events.click.length > 1 || events.click[0].namespace !== "tooltip");
var testLinkWithHref = elem.nodeName.toLowerCase() === 'a' && elem.href;
if (ischild) {
children.push(elem);
if (test_event) {
// do not trigger global click if one child has a click event registered
if (test_event || testLinkWithHref) {
// Do not trigger global click if one child has a click
// event registered (or it is a link with href)
trigger = false;
}
}
Expand Down
31 changes: 31 additions & 0 deletions addons/web/static/tests/fields/relational_fields_tests.js
Expand Up @@ -9788,6 +9788,37 @@ QUnit.module('relational_fields', {
form.destroy();
});

QUnit.test('click on URL should not open the record', function (assert) {
assert.expect(2);

this.data.partner.records[0].turtles = [1];

var form = createView({
View: FormView,
model: 'partner',
data: this.data,
arch:'<form string="Partners">' +
'<field name="turtles">' +
'<tree>' +
'<field name="display_name" widget="email"/>' +
'<field name="turtle_foo" widget="url"/>' +
'</tree>' +
'<form></form>' +
'</field>' +
'</form>',
res_id: 1,
});

form.$('.o_email_cell a').click();
assert.strictEqual($('.modal .o_form_view').length, 0,
'click should not open the modal');

form.$('.o_url_cell a').click();
assert.strictEqual($('.modal .o_form_view').length, 0,
'click should not open the modal');
form.destroy();
});

QUnit.module('FieldMany2Many');

QUnit.test('many2many kanban: edition', function (assert) {
Expand Down

0 comments on commit 41bf8ce

Please sign in to comment.