summaryrefslogtreecommitdiff
path: root/addons/lunch/static/src/js
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/lunch/static/src/js
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/lunch/static/src/js')
-rw-r--r--addons/lunch/static/src/js/lunch_controller_common.js218
-rw-r--r--addons/lunch/static/src/js/lunch_kanban_controller.js18
-rw-r--r--addons/lunch/static/src/js/lunch_kanban_record.js36
-rw-r--r--addons/lunch/static/src/js/lunch_kanban_renderer.js29
-rw-r--r--addons/lunch/static/src/js/lunch_kanban_view.js33
-rw-r--r--addons/lunch/static/src/js/lunch_list_controller.js18
-rw-r--r--addons/lunch/static/src/js/lunch_list_renderer.js56
-rw-r--r--addons/lunch/static/src/js/lunch_list_view.js38
-rw-r--r--addons/lunch/static/src/js/lunch_mobile.js78
-rw-r--r--addons/lunch/static/src/js/lunch_model.js130
-rw-r--r--addons/lunch/static/src/js/lunch_model_extension.js100
-rw-r--r--addons/lunch/static/src/js/lunch_payment_dialog.js20
-rw-r--r--addons/lunch/static/src/js/lunch_widget.js168
13 files changed, 942 insertions, 0 deletions
diff --git a/addons/lunch/static/src/js/lunch_controller_common.js b/addons/lunch/static/src/js/lunch_controller_common.js
new file mode 100644
index 00000000..8cd09316
--- /dev/null
+++ b/addons/lunch/static/src/js/lunch_controller_common.js
@@ -0,0 +1,218 @@
+odoo.define('lunch.LunchControllerCommon', function (require) {
+"use strict";
+
+/**
+ * This file defines the common events and functions used by Controllers for the Lunch view.
+ */
+
+var session = require('web.session');
+var core = require('web.core');
+var LunchWidget = require('lunch.LunchWidget');
+var LunchPaymentDialog = require('lunch.LunchPaymentDialog');
+
+var _t = core._t;
+
+var LunchControllerCommon = {
+ custom_events: {
+ add_product: '_onAddProduct',
+ change_location: '_onLocationChanged',
+ change_user: '_onUserChanged',
+ open_wizard: '_onOpenWizard',
+ order_now: '_onOrderNow',
+ remove_product: '_onRemoveProduct',
+ unlink_order: '_onUnlinkOrder',
+ },
+ /**
+ * @override
+ */
+ init: function () {
+ this._super.apply(this, arguments);
+ this.editMode = false;
+ this.updated = false;
+ this.widgetData = null;
+ this.context = session.user_context;
+ this.archiveEnabled = false;
+ },
+ /**
+ * @override
+ */
+ start: function () {
+ // create a div inside o_content that will be used to wrap the lunch
+ // banner and renderer (this is required to get the desired
+ // layout with the searchPanel to the left)
+ var self = this;
+ this.$('.o_content').append($('<div>').addClass('o_lunch_content'));
+ return this._super.apply(this, arguments).then(function () {
+ self.$('.o_lunch_content').append(self.$('.o_lunch_view'));
+ });
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ _fetchPaymentInfo: function () {
+ return this._rpc({
+ route: '/lunch/payment_message',
+ params: {
+ context: this.context,
+ },
+ });
+ },
+ _fetchWidgetData: async function () {
+ this.widgetData = await this._rpc({
+ route: '/lunch/infos',
+ params: {
+ user_id: this.searchModel.get('userId'),
+ context: this.context,
+ },
+ });
+ },
+ /**
+ * Renders and appends the lunch banner widget.
+ *
+ * @private
+ */
+ _renderLunchWidget: function () {
+ var self = this;
+ var oldWidget = this.widget;
+ this.widgetData.wallet = parseFloat(this.widgetData.wallet).toFixed(2);
+ this.widget = new LunchWidget(this, _.extend(this.widgetData, {edit: this.editMode}));
+ return this.widget.appendTo(document.createDocumentFragment()).then(function () {
+ self.$('.o_lunch_content').prepend(self.widget.$el);
+ if (oldWidget) {
+ oldWidget.destroy();
+ }
+ });
+ },
+ _showPaymentDialog: function (title) {
+ var self = this;
+
+ title = title || '';
+
+ this._fetchPaymentInfo().then(function (data) {
+ var paymentDialog = new LunchPaymentDialog(self, _.extend(data, {title: title}));
+ paymentDialog.open();
+ });
+ },
+ /**
+ * Override to fetch and display the lunch data. Because of the presence of
+ * the searchPanel, also wrap the lunch widget and the renderer into
+ * a div, to get the desired layout.
+ *
+ * @override
+ * @private
+ */
+ _update: function () {
+ var def = this._fetchWidgetData().then(this._renderLunchWidget.bind(this));
+ return Promise.all([def, this._super.apply(this, arguments)]);
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ _onAddProduct: function (ev) {
+ var self = this;
+ ev.stopPropagation();
+
+ this._rpc({
+ model: 'lunch.order',
+ method: 'update_quantity',
+ args: [[ev.data.lineId], 1],
+ }).then(function () {
+ self.reload();
+ });
+ },
+ _onLocationChanged: function (ev) {
+ ev.stopPropagation();
+ this.searchModel.dispatch('setLocationId', ev.data.locationId);
+ },
+ _onOpenWizard: function (ev) {
+ var self = this;
+ ev.stopPropagation();
+
+ var ctx = this.searchModel.get('userId') ? {default_user_id: this.searchModel.get('userId')} : {};
+
+ var options = {
+ on_close: function () {
+ self.reload();
+ },
+ };
+
+ // YTI TODO Maybe don't always pass the default_product_id
+ var action = {
+ res_model: 'lunch.order',
+ name: _t('Configure Your Order'),
+ type: 'ir.actions.act_window',
+ views: [[false, 'form']],
+ target: 'new',
+ context: _.extend(ctx, {default_product_id: ev.data.productId}),
+ };
+
+ if (ev.data.lineId) {
+ action = _.extend(action, {
+ res_id: ev.data.lineId,
+ context: _.extend(action.context, {
+ active_id: ev.data.lineId,
+ }),
+ });
+ }
+
+ this.do_action(action, options);
+ },
+ _onOrderNow: function (ev) {
+ var self = this;
+ ev.stopPropagation();
+
+ this._rpc({
+ route: '/lunch/pay',
+ params: {
+ user_id: this.searchModel.get('userId'),
+ context: this.context,
+ },
+ }).then(function (isPaid) {
+ if (isPaid) {
+ // TODO: feedback?
+ self.reload();
+ } else {
+ self._showPaymentDialog(_t("Not enough money in your wallet"));
+ self.reload();
+ }
+ });
+ },
+ _onRemoveProduct: function (ev) {
+ var self = this;
+ ev.stopPropagation();
+
+ this._rpc({
+ model: 'lunch.order',
+ method: 'update_quantity',
+ args: [[ev.data.lineId], -1],
+ }).then(function () {
+ self.reload();
+ });
+ },
+ _onUserChanged: function (ev) {
+ ev.stopPropagation();
+ this.searchModel.dispatch('updateUserId', ev.data.userId);
+ },
+ _onUnlinkOrder: function (ev) {
+ var self = this;
+ ev.stopPropagation();
+
+ this._rpc({
+ route: '/lunch/trash',
+ params: {
+ user_id: this.searchModel.get('userId'),
+ context: this.context,
+ },
+ }).then(function () {
+ self.reload();
+ });
+ },
+};
+
+return LunchControllerCommon;
+
+});
diff --git a/addons/lunch/static/src/js/lunch_kanban_controller.js b/addons/lunch/static/src/js/lunch_kanban_controller.js
new file mode 100644
index 00000000..dc370a46
--- /dev/null
+++ b/addons/lunch/static/src/js/lunch_kanban_controller.js
@@ -0,0 +1,18 @@
+odoo.define('lunch.LunchKanbanController', function (require) {
+"use strict";
+
+/**
+ * This file defines the Controller for the Lunch Kanban view, which is an
+ * override of the KanbanController.
+ */
+
+var KanbanController = require('web.KanbanController');
+var LunchControllerCommon = require('lunch.LunchControllerCommon');
+
+var LunchKanbanController = KanbanController.extend(LunchControllerCommon , {
+ custom_events: _.extend({}, KanbanController.prototype.custom_events, LunchControllerCommon.custom_events),
+});
+
+return LunchKanbanController;
+
+});
diff --git a/addons/lunch/static/src/js/lunch_kanban_record.js b/addons/lunch/static/src/js/lunch_kanban_record.js
new file mode 100644
index 00000000..9031192a
--- /dev/null
+++ b/addons/lunch/static/src/js/lunch_kanban_record.js
@@ -0,0 +1,36 @@
+odoo.define('lunch.LunchKanbanRecord', function (require) {
+ "use strict";
+
+ /**
+ * This file defines the KanbanRecord for the Lunch Kanban view.
+ */
+
+ var KanbanRecord = require('web.KanbanRecord');
+
+ var LunchKanbanRecord = KanbanRecord.extend({
+ events: _.extend({}, KanbanRecord.prototype.events, {
+ 'click': '_onSelectRecord',
+ }),
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * Open the add product wizard
+ *
+ * @private
+ * @param {MouseEvent} ev Click event
+ */
+ _onSelectRecord: function (ev) {
+ ev.preventDefault();
+ // ignore clicks on oe_kanban_action elements
+ if (!$(ev.target).hasClass('oe_kanban_action')) {
+ this.trigger_up('open_wizard', {productId: this.recordData.product_id ? this.recordData.product_id.res_id: this.recordData.id});
+ }
+ },
+ });
+
+ return LunchKanbanRecord;
+
+ });
diff --git a/addons/lunch/static/src/js/lunch_kanban_renderer.js b/addons/lunch/static/src/js/lunch_kanban_renderer.js
new file mode 100644
index 00000000..bea87992
--- /dev/null
+++ b/addons/lunch/static/src/js/lunch_kanban_renderer.js
@@ -0,0 +1,29 @@
+odoo.define('lunch.LunchKanbanRenderer', function (require) {
+"use strict";
+
+/**
+ * This file defines the Renderer for the Lunch Kanban view, which is an
+ * override of the KanbanRenderer.
+ */
+
+var LunchKanbanRecord = require('lunch.LunchKanbanRecord');
+
+var KanbanRenderer = require('web.KanbanRenderer');
+
+var LunchKanbanRenderer = KanbanRenderer.extend({
+ config: _.extend({}, KanbanRenderer.prototype.config, {
+ KanbanRecord: LunchKanbanRecord,
+ }),
+
+ /**
+ * @override
+ */
+ start: function () {
+ this.$el.addClass('o_lunch_view o_lunch_kanban_view position-relative align-content-start flex-grow-1 flex-shrink-1');
+ return this._super.apply(this, arguments);
+ },
+});
+
+return LunchKanbanRenderer;
+
+});
diff --git a/addons/lunch/static/src/js/lunch_kanban_view.js b/addons/lunch/static/src/js/lunch_kanban_view.js
new file mode 100644
index 00000000..50d347de
--- /dev/null
+++ b/addons/lunch/static/src/js/lunch_kanban_view.js
@@ -0,0 +1,33 @@
+odoo.define('lunch.LunchKanbanView', function (require) {
+"use strict";
+
+var LunchKanbanController = require('lunch.LunchKanbanController');
+var LunchKanbanRenderer = require('lunch.LunchKanbanRenderer');
+
+var core = require('web.core');
+var KanbanView = require('web.KanbanView');
+var view_registry = require('web.view_registry');
+
+var _lt = core._lt;
+
+var LunchKanbanView = KanbanView.extend({
+ config: _.extend({}, KanbanView.prototype.config, {
+ Controller: LunchKanbanController,
+ Renderer: LunchKanbanRenderer,
+ }),
+ display_name: _lt('Lunch Kanban'),
+
+ /**
+ * @override
+ */
+ _createSearchModel(params, extraExtensions = {}) {
+ Object.assign(extraExtensions, { Lunch: {} });
+ return this._super(params, extraExtensions);
+ },
+});
+
+view_registry.add('lunch_kanban', LunchKanbanView);
+
+return LunchKanbanView;
+
+});
diff --git a/addons/lunch/static/src/js/lunch_list_controller.js b/addons/lunch/static/src/js/lunch_list_controller.js
new file mode 100644
index 00000000..bdfbab6b
--- /dev/null
+++ b/addons/lunch/static/src/js/lunch_list_controller.js
@@ -0,0 +1,18 @@
+odoo.define('lunch.LunchListController', function (require) {
+"use strict";
+
+/**
+ * This file defines the Controller for the Lunch List view, which is an
+ * override of the ListController.
+ */
+
+var ListController = require('web.ListController');
+var LunchControllerCommon = require('lunch.LunchControllerCommon');
+
+var LunchListController = ListController.extend(LunchControllerCommon, {
+ custom_events: _.extend({}, ListController.prototype.custom_events, LunchControllerCommon.custom_events),
+});
+
+return LunchListController;
+
+});
diff --git a/addons/lunch/static/src/js/lunch_list_renderer.js b/addons/lunch/static/src/js/lunch_list_renderer.js
new file mode 100644
index 00000000..0ab0b5c9
--- /dev/null
+++ b/addons/lunch/static/src/js/lunch_list_renderer.js
@@ -0,0 +1,56 @@
+odoo.define('lunch.LunchListRenderer', function (require) {
+"use strict";
+
+/**
+ * This file defines the Renderer for the Lunch List view, which is an
+ * override of the ListRenderer.
+ */
+
+var ListRenderer = require('web.ListRenderer');
+
+var LunchListRenderer = ListRenderer.extend({
+ events: _.extend({}, ListRenderer.prototype.events, {
+ 'click .o_data_row': '_onClickListRow',
+ }),
+
+ /**
+ * @override
+ */
+ start: function () {
+ this.$el.addClass('o_lunch_view o_lunch_list_view');
+ return this._super.apply(this, arguments);
+ },
+ /**
+ * Override to add id of product_id in dataset.
+ *
+ * @override
+ */
+ _renderRow: function (record) {
+ var tr = this._super.apply(this, arguments);
+ tr.attr('data-product-id', record.data.id);
+ return tr;
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * Open the add product wizard
+ *
+ * @private
+ * @param {MouseEvent} ev Click event
+ */
+ _onClickListRow: function (ev) {
+ ev.preventDefault();
+ var productId = ev.currentTarget.dataset && ev.currentTarget.dataset.productId ? parseInt(ev.currentTarget.dataset.productId) : null;
+
+ if (productId) {
+ this.trigger_up('open_wizard', {productId: productId});
+ }
+ },
+});
+
+return LunchListRenderer;
+
+});
diff --git a/addons/lunch/static/src/js/lunch_list_view.js b/addons/lunch/static/src/js/lunch_list_view.js
new file mode 100644
index 00000000..00e8efa5
--- /dev/null
+++ b/addons/lunch/static/src/js/lunch_list_view.js
@@ -0,0 +1,38 @@
+odoo.define('lunch.LunchListView', function (require) {
+"use strict";
+
+var LunchListController = require('lunch.LunchListController');
+var LunchListRenderer = require('lunch.LunchListRenderer');
+
+var core = require('web.core');
+var ListView = require('web.ListView');
+var view_registry = require('web.view_registry');
+
+var _lt = core._lt;
+
+var LunchListView = ListView.extend({
+ config: _.extend({}, ListView.prototype.config, {
+ Controller: LunchListController,
+ Renderer: LunchListRenderer,
+ }),
+ display_name: _lt('Lunch List'),
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ */
+ _createSearchModel(params, extraExtensions = {}) {
+ Object.assign(extraExtensions, { Lunch: {} });
+ return this._super(params, extraExtensions);
+ },
+
+});
+
+view_registry.add('lunch_list', LunchListView);
+
+return LunchListView;
+
+});
diff --git a/addons/lunch/static/src/js/lunch_mobile.js b/addons/lunch/static/src/js/lunch_mobile.js
new file mode 100644
index 00000000..f6ad1e92
--- /dev/null
+++ b/addons/lunch/static/src/js/lunch_mobile.js
@@ -0,0 +1,78 @@
+odoo.define('lunch.LunchMobile', function (require) {
+"use strict";
+
+var config = require('web.config');
+var LunchWidget = require('lunch.LunchWidget');
+var LunchKanbanController = require('lunch.LunchKanbanController');
+var LunchListController = require('lunch.LunchListController');
+
+if (!config.device.isMobile) {
+ return;
+}
+
+LunchWidget.include({
+ template: "LunchWidgetMobile",
+
+ /**
+ * Override to set the toggle state allowing initially open it.
+ *
+ * @override
+ */
+ init: function (parent, params) {
+ this._super.apply(this, arguments);
+ this.keepOpen = params.keepOpen || undefined;
+ },
+});
+
+var mobileFunctions = {
+ /**
+ * @override
+ */
+ init: function () {
+ this._super.apply(this, arguments);
+ this.openWidget = false;
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * Override to add the widget's toggle state to its data.
+ *
+ * @override
+ * @private
+ */
+ _renderLunchWidget: function () {
+ this.widgetData.keepOpen = this.openWidget;
+ this.openWidget = false;
+ return this._super.apply(this, arguments);
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ * @private
+ */
+ _onAddProduct: function () {
+ this.openWidget = true;
+ this._super.apply(this, arguments);
+ },
+
+ /**
+ * @override
+ * @private
+ */
+ _onRemoveProduct: function () {
+ this.openWidget = true;
+ this._super.apply(this, arguments);
+ },
+};
+
+LunchKanbanController.include(mobileFunctions);
+LunchListController.include(mobileFunctions);
+
+});
diff --git a/addons/lunch/static/src/js/lunch_model.js b/addons/lunch/static/src/js/lunch_model.js
new file mode 100644
index 00000000..720b4356
--- /dev/null
+++ b/addons/lunch/static/src/js/lunch_model.js
@@ -0,0 +1,130 @@
+odoo.define('lunch.LunchModel', function (require) {
+"use strict";
+
+/**
+ * This file defines the Model for the Lunch Kanban view, which is an
+ * override of the KanbanModel.
+ */
+
+var session = require('web.session');
+var BasicModel = require('web.BasicModel');
+
+var LunchModel = BasicModel.extend({
+ init: function () {
+ this.locationId = false;
+ this.userId = false;
+ this._promInitLocation = null;
+
+ this._super.apply(this, arguments);
+ },
+
+ //--------------------------------------------------------------------------
+ // Public
+ //--------------------------------------------------------------------------
+
+ /**
+ * @return {Promise} resolved with the location domain
+ */
+ getLocationDomain: function () {
+ var self = this;
+ return this._initUserLocation().then(function () {
+ return self._buildLocationDomainLeaf() ? [self._buildLocationDomainLeaf()]: [];
+ });
+ },
+ __load: function () {
+ var self = this;
+ var args = arguments;
+ var _super = this._super;
+
+ return this._initUserLocation().then(function () {
+ var params = args[0];
+ self._addOrUpdate(params.domain, self._buildLocationDomainLeaf());
+
+ return _super.apply(self, args);
+ });
+ },
+ __reload: function (id, options) {
+ var domain = options && options.domain || this.localData[id].domain;
+
+ this._addOrUpdate(domain, this._buildLocationDomainLeaf());
+ options = _.extend(options, {domain: domain});
+
+ return this._super.apply(this, arguments);
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ _addOrUpdate: function (domain, subDomain) {
+ if (subDomain && subDomain.length) {
+ var key = subDomain[0];
+ var index = _.findIndex(domain, function (val) {
+ return val[0] === key;
+ });
+
+ if (index < 0) {
+ domain.push(subDomain);
+ } else {
+ domain[index] = subDomain;
+ }
+
+ return domain;
+ }
+
+ return domain;
+ },
+ /**
+ * Builds the domain leaf corresponding to the current user's location
+ *
+ * @private
+ * @return {(Array[])|undefined}
+ */
+ _buildLocationDomainLeaf: function () {
+ if (this.locationId) {
+ return ['is_available_at', 'in', [this.locationId]];
+ }
+ },
+ _getUserLocation: function () {
+ return this._rpc({
+ route: '/lunch/user_location_get',
+ params: {
+ context: session.user_context,
+ user_id: this.userId,
+ },
+ });
+ },
+ /**
+ * Gets the user location once.
+ * Can be triggered from anywhere
+ * Useful to inject the location domain in the search panel
+ *
+ * @private
+ * @return {Promise}
+ */
+ _initUserLocation: function () {
+ var self = this;
+ if (!this._promInitLocation) {
+ this._promInitLocation = new Promise(function (resolve) {
+ self._getUserLocation().then(function (locationId) {
+ self.locationId = locationId;
+ resolve();
+ });
+ });
+ }
+ return this._promInitLocation;
+ },
+ _updateLocation: function (locationId) {
+ this.locationId = locationId;
+ return Promise.resolve();
+ },
+ _updateUser: function (userId) {
+ this.userId = userId;
+ this._promInitLocation = null;
+ return this._initUserLocation();
+ }
+});
+
+return LunchModel;
+
+});
diff --git a/addons/lunch/static/src/js/lunch_model_extension.js b/addons/lunch/static/src/js/lunch_model_extension.js
new file mode 100644
index 00000000..aec64b97
--- /dev/null
+++ b/addons/lunch/static/src/js/lunch_model_extension.js
@@ -0,0 +1,100 @@
+odoo.define("lunch/static/src/js/lunch_model_extension.js", function (require) {
+ "use strict";
+
+ const ActionModel = require("web/static/src/js/views/action_model.js");
+
+ class LunchModelExtension extends ActionModel.Extension {
+
+ //---------------------------------------------------------------------
+ // Public
+ //---------------------------------------------------------------------
+
+ /**
+ * @override
+ * @returns {any}
+ */
+ get(property) {
+ switch (property) {
+ case "domain": return this.getDomain();
+ case "userId": return this.state.userId;
+ }
+ }
+
+ /**
+ * @override
+ */
+ async load() {
+ await this._updateLocationId();
+ }
+
+ /**
+ * @override
+ */
+ prepareState() {
+ Object.assign(this.state, {
+ locationId: null,
+ userId: null,
+ });
+ }
+
+ //---------------------------------------------------------------------
+ // Actions / Getters
+ //---------------------------------------------------------------------
+
+ /**
+ * @returns {Array[] | null}
+ */
+ getDomain() {
+ if (this.state.locationId) {
+ return [["is_available_at", "in", [this.state.locationId]]];
+ }
+ return null;
+ }
+
+ /**
+ * @param {number} locationId
+ * @returns {Promise}
+ */
+ setLocationId(locationId) {
+ this.state.locationId = locationId;
+ this.env.services.rpc({
+ route: "/lunch/user_location_set",
+ params: {
+ context: this.env.session.user_context,
+ location_id: this.state.locationId,
+ user_id: this.state.userId,
+ },
+ });
+ }
+
+ /**
+ * @param {number} userId
+ * @returns {Promise}
+ */
+ updateUserId(userId) {
+ this.state.userId = userId;
+ this.shouldLoad = true;
+ }
+
+ //---------------------------------------------------------------------
+ // Private
+ //---------------------------------------------------------------------
+
+ /**
+ * @returns {Promise}
+ */
+ async _updateLocationId() {
+ this.state.locationId = await this.env.services.rpc({
+ route: "/lunch/user_location_get",
+ params: {
+ context: this.env.session.user_context,
+ user_id: this.state.userId,
+ },
+ });
+ }
+ }
+
+ ActionModel.registry.add("Lunch", LunchModelExtension, 20);
+
+ return LunchModelExtension;
+});
diff --git a/addons/lunch/static/src/js/lunch_payment_dialog.js b/addons/lunch/static/src/js/lunch_payment_dialog.js
new file mode 100644
index 00000000..ae624403
--- /dev/null
+++ b/addons/lunch/static/src/js/lunch_payment_dialog.js
@@ -0,0 +1,20 @@
+odoo.define('lunch.LunchPaymentDialog', function (require) {
+"use strict";
+
+var Dialog = require('web.Dialog');
+
+var LunchPaymentDialog = Dialog.extend({
+ template: 'lunch.LunchPaymentDialog',
+
+ init: function (parent, options) {
+ this._super.apply(this, arguments);
+
+ options = options || {};
+
+ this.message = options.message || '';
+ },
+});
+
+return LunchPaymentDialog;
+
+});
diff --git a/addons/lunch/static/src/js/lunch_widget.js b/addons/lunch/static/src/js/lunch_widget.js
new file mode 100644
index 00000000..ca0c497c
--- /dev/null
+++ b/addons/lunch/static/src/js/lunch_widget.js
@@ -0,0 +1,168 @@
+odoo.define('lunch.LunchWidget', function (require) {
+"use strict";
+
+var core = require('web.core');
+var relationalFields = require('web.relational_fields');
+var session = require('web.session');
+var Widget = require('web.Widget');
+
+var _t = core._t;
+var FieldMany2One = relationalFields.FieldMany2One;
+
+
+var LunchMany2One = FieldMany2One.extend({
+ start: function () {
+ this.$el.addClass('w-100');
+ return this._super.apply(this, arguments);
+ }
+});
+
+var LunchWidget = Widget.extend({
+ template: 'LunchWidget',
+ custom_events: {
+ field_changed: '_onFieldChanged',
+ },
+ events: {
+ 'click .o_add_product': '_onAddProduct',
+ 'click .o_lunch_widget_order_button': '_onOrderNow',
+ 'click .o_remove_product': '_onRemoveProduct',
+ 'click .o_lunch_widget_unlink': '_onUnlinkOrder',
+ 'click .o_lunch_open_wizard': '_onLunchOpenWizard',
+ },
+
+ init: function (parent, params) {
+ this._super.apply(this, arguments);
+
+ this.is_manager = params.is_manager || false;
+ this.userimage = params.userimage || '';
+ this.username = params.username || '';
+
+ this.lunchUserField = null;
+
+ this.group_portal_id = undefined;
+
+ this.locations = params.locations || [];
+ this.userLocation = params.user_location[1] || '';
+
+ this.lunchLocationField = this._createMany2One('locations', 'lunch.location', this.userLocation);
+
+ this.wallet = params.wallet || 0;
+ this.raw_state = params.raw_state || 'new';
+ this.state = params.state || _t('To Order');
+ this.lines = params.lines || [];
+ this.total = params.total || 0;
+
+ this.alerts = params.alerts || [];
+
+ this.currency = params.currency || session.get_currency(session.company_currency_id);
+ },
+ willStart: function () {
+ var self = this;
+ var superDef = this._super.apply(this, arguments);
+
+ var def = this._rpc({
+ model: 'ir.model.data',
+ method: 'xmlid_to_res_id',
+ kwargs: {xmlid: 'base.group_portal'},
+ }).then(function (id) {
+ self.group_portal_id = id;
+
+ if (self.is_manager) {
+ self.lunchUserField = self._createMany2One('users', 'res.users', self.username, function () {
+ return [['groups_id', 'not in', [self.group_portal_id]]];
+ });
+ }
+ });
+ return Promise.all([superDef, def]);
+ },
+ renderElement: function () {
+ this._super.apply(this, arguments);
+ if (this.lunchUserField) {
+ this.lunchUserField.appendTo(this.$('.o_lunch_user_field'));
+ } else {
+ this.$('.o_lunch_user_field').text(this.username);
+ }
+ this.lunchLocationField.appendTo(this.$('.o_lunch_location_field'));
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ _createMany2One: function (name, model, value, domain, context) {
+ var fields = {};
+ fields[name] = {type: 'many2one', relation: model, string: name};
+ var data = {};
+ data[name] = {data: {display_name: value}};
+
+ var record = {
+ id: name,
+ res_id: 1,
+ model: 'dummy',
+ fields: fields,
+ fieldsInfo: {
+ default: fields,
+ },
+ data: data,
+ getDomain: domain || function () { return []; },
+ getContext: context || function () { return {}; },
+ };
+ var options = {
+ mode: 'edit',
+ noOpen: true,
+ attrs: {
+ can_create: false,
+ can_write: false,
+ }
+ };
+ return new LunchMany2One(this, name, record, options);
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ _onAddProduct: function (ev) {
+ ev.preventDefault();
+ ev.stopPropagation();
+ this.trigger_up('add_product', {lineId: $(ev.currentTarget).data('id')});
+ },
+ _onOrderNow: function (ev) {
+ ev.preventDefault();
+ ev.stopPropagation();
+
+ this.trigger_up('order_now', {});
+ },
+ _onLunchOpenWizard: function (ev) {
+ ev.preventDefault();
+ ev.stopPropagation();
+
+ var target = $(ev.currentTarget);
+ this.trigger_up('open_wizard', {productId: target.data('product-id'), lineId: target.data('id')});
+ },
+ _onFieldChanged: function (ev) {
+ ev.stopPropagation();
+
+ if (ev.data.dataPointID === 'users') {
+ this.trigger_up('change_user', {userId: ev.data.changes.users.id});
+ } else if (ev.data.dataPointID === 'locations') {
+ this.trigger_up('change_location', {locationId: ev.data.changes.locations.id});
+ }
+ },
+ _onRemoveProduct: function (ev) {
+ ev.preventDefault();
+ ev.stopPropagation();
+
+ this.trigger_up('remove_product', {lineId: $(ev.currentTarget).data('id')});
+ },
+ _onUnlinkOrder: function (ev) {
+ ev.preventDefault();
+ ev.stopPropagation();
+
+ this.trigger_up('unlink_order', {});
+ },
+});
+
+return LunchWidget;
+
+});