[FIX] lunch: adapt the code to new views
We also adapt the code to comply to the new guidelines and we have added some tests.
This commit is contained in:
@@ -99,9 +99,7 @@ class LunchOrder(models.Model):
|
||||
'supplier': line.supplier.name,
|
||||
'note': line.note,
|
||||
'price': line.price,
|
||||
'currency': line.currency_id.symbol,
|
||||
'digits': [69, line.currency_id.decimal_places],
|
||||
'position': line.currency_id.position,
|
||||
'currency_id': line.currency_id.id,
|
||||
}
|
||||
self.previous_order_widget = json.dumps(lunch_data)
|
||||
|
||||
|
||||
@@ -1,81 +1,94 @@
|
||||
odoo.define('lunch.previous_orders', function (require) {
|
||||
"use strict";
|
||||
|
||||
var AbstractField = require('web.AbstractField');
|
||||
var core = require('web.core');
|
||||
var field_utils = require('web.field_utils');
|
||||
var field_registry = require('web.field_registry');
|
||||
var relational_fields = require('web.relational_fields');
|
||||
var field_utils = require('web.field_utils');
|
||||
|
||||
var QWeb = core.qweb;
|
||||
|
||||
var FieldMany2Many = relational_fields.FieldMany2Many;
|
||||
|
||||
var LunchPreviousOrdersWidget = FieldMany2Many.extend({
|
||||
className: 'row o_lunch_last_orders',
|
||||
var LunchPreviousOrdersWidget = AbstractField.extend({
|
||||
events: {
|
||||
'click .o_add_button': 'set_order_line',
|
||||
'click .o_add_button': '_onAddOrder',
|
||||
},
|
||||
supported_field_types: [],
|
||||
init: function() {
|
||||
supportedFieldTypes: ['one2many'],
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
init: function () {
|
||||
this._super.apply(this, arguments);
|
||||
this.lunch_data = {};
|
||||
this.fields_to_read = ['product_id', 'supplier', 'note', 'price', 'category_id', 'currency_id'];
|
||||
this.format_value = function (value) {
|
||||
var options = _.extend({}, this.nodeOptions, { data: this.recordData });
|
||||
return field_utils.format.monetary(value, this.field, options);
|
||||
this.lunchData = JSON.parse(this.value);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Used by the widget to render the previous order price like a monetary.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} order
|
||||
* @returns {string} the monetary formatting of order price
|
||||
*/
|
||||
_formatValue: function (order) {
|
||||
var options = _.extend({}, this.nodeOptions, order);
|
||||
return field_utils.format.monetary(order.price, this.field, options);
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @override
|
||||
*/
|
||||
_render: function () {
|
||||
if (this.lunchData !== false) {
|
||||
// group data by supplier for display
|
||||
var categories = _.groupBy(this.lunchData, 'supplier');
|
||||
this.$el.html(QWeb.render('LunchPreviousOrdersWidgetList', {
|
||||
formatValue: this._formatValue.bind(this),
|
||||
categories: categories,
|
||||
}));
|
||||
} else {
|
||||
return this.$el.html(QWeb.render('LunchPreviousOrdersWidgetNoOrder'));
|
||||
}
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {MouseEvent} event
|
||||
*/
|
||||
_onAddOrder: function (event) {
|
||||
// Get order details from line
|
||||
var lineID = parseInt($(event.currentTarget).data('id'));
|
||||
if (!lineID) {
|
||||
return;
|
||||
}
|
||||
var values = {
|
||||
product_id: {
|
||||
id: this.lunchData[lineID].product_id,
|
||||
display_name: this.lunchData[lineID].product_name,
|
||||
},
|
||||
note: this.lunchData[lineID].note,
|
||||
price: this.lunchData[lineID].price,
|
||||
};
|
||||
},
|
||||
get_line_value: function(id) {
|
||||
var data = _.clone(this.lunch_data[id]);
|
||||
if (typeof this.lunch_data[id].product_id[0] !== 'undefined'){
|
||||
data.product_id = this.lunch_data[id].product_id[0];
|
||||
}
|
||||
if (typeof this.lunch_data[id].supplier[0] !== 'undefined'){
|
||||
data.supplier = this.lunch_data[id].supplier[0];
|
||||
}
|
||||
if (typeof this.lunch_data[id].category_id[0] !== 'undefined'){
|
||||
data.category_id = this.lunch_data[id].category_id[0];
|
||||
}
|
||||
return data;
|
||||
},
|
||||
set_order_line: function() {
|
||||
// FIXME: This is the true functionality of this widget in edit mode
|
||||
// var data = this.get_line_value(parseInt($(event.currentTarget).data('id')));
|
||||
// var order_line_ids = this.field_manager.fields.order_line_ids;
|
||||
// order_line_ids.data_create(data);
|
||||
// order_line_ids.reload_current_view();
|
||||
},
|
||||
render: function() {
|
||||
var self = this;
|
||||
// Fetch values
|
||||
// FIXME: this might be replaced when we implement a way for widgets
|
||||
// to declare which fields they need from the relational data
|
||||
this.trigger_up('perform_model_rpc', {
|
||||
model: 'lunch.order.line',
|
||||
method: 'read',
|
||||
args: [
|
||||
this.value,
|
||||
this.fields_to_read
|
||||
],
|
||||
on_success: function (orders) {
|
||||
if (_.isEmpty(orders)) {
|
||||
self.$el.html(QWeb.render("LunchPreviousOrdersWidgetNoOrder"));
|
||||
} else {
|
||||
_.each(orders, function(order) {
|
||||
self.lunch_data[order.id] = order;
|
||||
});
|
||||
var categories = _.groupBy(orders, function(o){ return o.supplier[1]; });
|
||||
return self.$el.html(QWeb.render("LunchPreviousOrdersWidgetList", {'widget': self, 'categories': categories}));
|
||||
}
|
||||
}
|
||||
|
||||
// create a new order line
|
||||
this.trigger_up('field_changed', {
|
||||
dataPointID: this.dataPointID,
|
||||
changes: {
|
||||
order_line_ids: {
|
||||
operation: 'CREATE',
|
||||
data: values,
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
has_no_value: function() {
|
||||
return false;
|
||||
},
|
||||
});
|
||||
|
||||
field_registry.add('previous_order', LunchPreviousOrdersWidget);
|
||||
|
||||
return LunchPreviousOrdersWidget;
|
||||
|
||||
});
|
||||
|
||||
@@ -7,20 +7,22 @@
|
||||
<p class="text-muted">Don't forget the alerts displayed in the reddish area</p>
|
||||
</div>
|
||||
<t t-name="LunchPreviousOrdersWidgetList">
|
||||
<div t-foreach="categories" t-as="product_category" class="col-sm-4">
|
||||
<h3><t t-esc="product_category"/></h3>
|
||||
<div t-foreach='categories[product_category]' t-as='product' class="o_lunch_vignette">
|
||||
<button type="button" class="pull-right o_add_button oe_edit_only oe_link" t-att-data-id="product.id">
|
||||
<div t-foreach="categories" t-as="supplier" class="col-md-4">
|
||||
<h3><t t-esc="supplier"/></h3>
|
||||
<div t-foreach='categories[supplier]' t-as='order' class="o_lunch_vignette">
|
||||
<button type="button" class="pull-right o_add_button oe_edit_only oe_link" t-att-data-id="order.line_id">
|
||||
<span class="fa fa-plus-square"></span>
|
||||
<span>Add</span>
|
||||
</button>
|
||||
<div class="o_lunch_text">
|
||||
<div class="badge pull-right">
|
||||
<t t-esc="widget.format_value(product.price)"/> <t t-esc="product.currency_id[1]"/>
|
||||
</div>
|
||||
<t t-esc="product.product_id[1]"/>
|
||||
<div>
|
||||
<t t-esc="order.product_name"/>
|
||||
<span class="badge pull-right">
|
||||
<span class="o_lunch_price" t-raw="formatValue(order)"/>
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-muted">
|
||||
<t t-if="order.note != false" t-esc="order.note"/>
|
||||
</div>
|
||||
<div class="text-muted"><t t-if="product.note != false" t-esc="product.note"/></div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
odoo.define('lunch.tests', function (require) {
|
||||
"use strict";
|
||||
|
||||
var FormView = require('web.FormView');
|
||||
var testUtils = require('web.test_utils');
|
||||
|
||||
var createView = testUtils.createView;
|
||||
|
||||
QUnit.module('lunch', {
|
||||
beforeEach: function () {
|
||||
this.data = {
|
||||
order: {
|
||||
fields: {
|
||||
previous_order_widget: {type: 'text'},
|
||||
order_line_ids: {type: 'many2many', relation: 'order_line'}
|
||||
},
|
||||
records: [{
|
||||
id: 1,
|
||||
name: 'coucou',
|
||||
}, {
|
||||
id: 2,
|
||||
name: 'coucou',
|
||||
}, {
|
||||
id: 11,
|
||||
}],
|
||||
},
|
||||
order_line: {
|
||||
fields: {
|
||||
product_id: {type: 'many2one', relation: 'product'},
|
||||
note: {type: 'text'},
|
||||
price: {type: 'float'},
|
||||
},
|
||||
},
|
||||
supplier: {
|
||||
fields: {},
|
||||
records: [{
|
||||
id: 1,
|
||||
display_name: "Coin Gourmant",
|
||||
}, {
|
||||
id: 2,
|
||||
display_name: "Pizza Inn",
|
||||
}]
|
||||
},
|
||||
product: {
|
||||
fields: {},
|
||||
records: [{
|
||||
id: 1,
|
||||
name: 'Pizza Margherita',
|
||||
}],
|
||||
}
|
||||
};
|
||||
},
|
||||
}, function () {
|
||||
|
||||
QUnit.test("empty previous_order widget", function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
var form = createView({
|
||||
View: FormView,
|
||||
arch: '<form>' +
|
||||
'<sheet>' +
|
||||
'<field name="previous_order_widget" widget="previous_order"/>' +
|
||||
'<field name="order_line_ids"/>' +
|
||||
'</sheet>' +
|
||||
'</form>',
|
||||
data: this.data,
|
||||
model: 'order',
|
||||
archs: {
|
||||
"order_line,false,list": '<tree string="Orders">' +
|
||||
'<field name="product_id"/>' +
|
||||
'<field name="note"/>' +
|
||||
'<field name="price"/>' +
|
||||
'</tree>',
|
||||
},
|
||||
});
|
||||
|
||||
var widgetText = form.$('.o_form_field[name="previous_order_widget"]').text();
|
||||
assert.ok(widgetText.indexOf('This is the first time you order a meal') !== -1,
|
||||
"the widget should display its no content text");
|
||||
assert.strictEqual(form.$('.o_lunch_vignette').length, 0,
|
||||
"there should be no vignette");
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test("add an order line with previous_order widget", function (assert) {
|
||||
assert.expect(4);
|
||||
|
||||
var form = createView({
|
||||
View: FormView,
|
||||
arch: '<form>' +
|
||||
'<sheet>' +
|
||||
'<field name="previous_order_widget" widget="previous_order"/>' +
|
||||
'<field name="order_line_ids"/>' +
|
||||
'</sheet>' +
|
||||
'</form>',
|
||||
data: this.data,
|
||||
model: 'order',
|
||||
mockRPC: function (route, args) {
|
||||
if (args.method === 'default_get') {
|
||||
return $.when({
|
||||
previous_order_widget: '{' +
|
||||
'"8": {' +
|
||||
'"note": "coucou",' +
|
||||
'"line_id": 8,' +
|
||||
'"digits": [69, 2],' +
|
||||
'"product_id": 1,' +
|
||||
'"currency": "$",' +
|
||||
'"supplier": "Pizza Inn",' +
|
||||
'"position": "before",' +
|
||||
'"price": 6.9,' +
|
||||
'"product_name": "Pizza Margherita"' +
|
||||
'}' +
|
||||
'}'
|
||||
});
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
archs: {
|
||||
"order_line,false,list": '<tree string="Orders">' +
|
||||
'<field name="product_id"/>' +
|
||||
'<field name="note"/>' +
|
||||
'<field name="price"/>' +
|
||||
'</tree>',
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(form.$('.o_list_view tr.o_data_row').length, 0,
|
||||
"there should be no row in the one2many list");
|
||||
|
||||
assert.strictEqual(form.$('.o_lunch_vignette').length, 1,
|
||||
"there should be a vignette");
|
||||
|
||||
// add an order
|
||||
form.$('.o_lunch_vignette .o_add_button').click();
|
||||
|
||||
assert.strictEqual(form.$('.o_list_view tr.o_data_row').length, 1,
|
||||
"there should be one new row in the one2many list");
|
||||
assert.strictEqual(form.$('.o_list_view tr.o_data_row').text(), "Pizza Margheritacoucou6.90",
|
||||
"the line should contain the correct data");
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -6,4 +6,10 @@
|
||||
<script type="text/javascript" src="/lunch/static/src/js/lunch.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="qunit_suite" name="lunch tests" inherit_id="web.qunit_suite">
|
||||
<xpath expr="//t[@t-set='head']" position="inside">
|
||||
<script type="text/javascript" src="/lunch/static/tests/lunch_tests.js"/>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
||||
|
||||
Reference in New Issue
Block a user