diff --git a/addons/point_of_sale/models/pos_config.py b/addons/point_of_sale/models/pos_config.py index 7001fed9017..a5d6f18c91c 100644 --- a/addons/point_of_sale/models/pos_config.py +++ b/addons/point_of_sale/models/pos_config.py @@ -395,6 +395,7 @@ class PosConfig(models.Model): pos_configs = super().create(vals_list) pos_configs.sudo()._check_modules_to_install() pos_configs.sudo()._check_groups_implied() + pos_configs._update_preparation_printers_menuitem_visibility() # If you plan to add something after this, use a new environment. The one above is no longer valid after the modules install. return pos_configs @@ -406,16 +407,25 @@ class PosConfig(models.Model): else: raise UserError(_('The default tip product is missing. Please manually specify the tip product. (See Tips field.)')) + def _update_preparation_printers_menuitem_visibility(self): + prepa_printers_menuitem = self.sudo().env.ref('point_of_sale.menu_pos_preparation_printer', raise_if_not_found=False) + if prepa_printers_menuitem: + prepa_printers_menuitem.active = self.sudo().env['pos.config'].search_count([('is_order_printer', '=', True)], limit=1) > 0 + def write(self, vals): self._reset_default_on_vals(vals) if ('is_order_printer' in vals and not vals['is_order_printer']): vals['printer_ids'] = [fields.Command.clear()] + bypass_categories_forbidden_change = self.env.context.get('bypass_categories_forbidden_change', False) + opened_session = self.mapped('session_ids').filtered(lambda s: s.state != 'closed') if opened_session: forbidden_fields = [] for key in self._get_forbidden_change_fields(): if key in vals.keys(): + if bypass_categories_forbidden_change and key in ('limit_categories', 'iface_available_categ_ids'): + continue if key == 'use_pricelist' and vals[key]: continue if key == 'available_pricelist_ids': @@ -434,6 +444,8 @@ class PosConfig(models.Model): self.sudo()._set_fiscal_position() self.sudo()._check_modules_to_install() self.sudo()._check_groups_implied() + if 'is_order_printer' in vals: + self._update_preparation_printers_menuitem_visibility() return result def _get_forbidden_change_fields(self): diff --git a/addons/point_of_sale/models/pos_payment_method.py b/addons/point_of_sale/models/pos_payment_method.py index 6ac7c18d7fb..5679c0fe038 100644 --- a/addons/point_of_sale/models/pos_payment_method.py +++ b/addons/point_of_sale/models/pos_payment_method.py @@ -38,7 +38,7 @@ class PosPaymentMethod(models.Model): default=False, help='Forces to set a customer when using this payment method and splits the journal entries for each customer. It could slow down the closing process.') open_session_ids = fields.Many2many('pos.session', string='Pos Sessions', compute='_compute_open_session_ids', help='Open PoS sessions that are using this payment method.') - config_ids = fields.Many2many('pos.config', string='Point of Sale Configurations') + config_ids = fields.Many2many('pos.config', string='Point of Sale') company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.company) use_payment_terminal = fields.Selection(selection=lambda self: self._get_payment_terminal_selection(), string='Use a Payment Terminal', help='Record payments with a terminal on this journal.') # used to hide use_payment_terminal when no payment interfaces are installed diff --git a/addons/point_of_sale/models/pos_session.py b/addons/point_of_sale/models/pos_session.py index f4119017bcc..75d14c290b5 100644 --- a/addons/point_of_sale/models/pos_session.py +++ b/addons/point_of_sale/models/pos_session.py @@ -1563,8 +1563,8 @@ class PosSession(models.Model): def get_onboarding_data(self): return { - "categories": self._load_model('pos.category'), - "products": self._load_model('product.product'), + 'pos.category': self._load_model('pos.category'), + 'product.product': self._load_model('product.product'), } def _load_model(self, model): @@ -1636,6 +1636,7 @@ class PosSession(models.Model): loaded_data['attributes_by_ptal_id'] = self._get_attributes_by_ptal_id() loaded_data['base_url'] = self.get_base_url() + loaded_data['pos_has_valid_product'] = self._pos_has_valid_product() @api.model def _pos_ui_models_to_load(self): @@ -2094,10 +2095,21 @@ class PosSession(models.Model): self.message_post(body=body, author_id=partner_id) + def _pos_has_valid_product(self): + return self.env['product.product'].sudo().search_count(['&', ('available_in_pos', '=', True), ('list_price', '>', 0)], limit=1) > 0 + + def _load_onboarding_data(self): + convert.convert_file(self.env, 'point_of_sale', 'data/point_of_sale_onboarding.xml', None, mode='init', kind='data') + def load_product_frontend(self): - convert.convert_file(self.env, 'point_of_sale', 'data/point_of_sale_onboarding.xml', None, mode='init', - kind='data') - return self.get_onboarding_data() + allowed = not self._pos_has_valid_product() + if allowed: + self._load_onboarding_data() + + return { + 'models_data': self.get_onboarding_data(), + 'successful': allowed, + } class ProcurementGroup(models.Model): diff --git a/addons/point_of_sale/static/src/app/screens/product_screen/product_list/control_panel/control_panel.xml b/addons/point_of_sale/static/src/app/screens/product_screen/product_list/control_panel/control_panel.xml index ee739ea1da1..8e4c2a2c379 100644 --- a/addons/point_of_sale/static/src/app/screens/product_screen/product_list/control_panel/control_panel.xml +++ b/addons/point_of_sale/static/src/app/screens/product_screen/product_list/control_panel/control_panel.xml @@ -4,18 +4,20 @@
-
- - - - - - -
+ +
+ + + + + + +
+
diff --git a/addons/point_of_sale/static/src/app/screens/product_screen/product_list/product_list.js b/addons/point_of_sale/static/src/app/screens/product_screen/product_list/product_list.js index d6b4992b64d..25e4491daff 100644 --- a/addons/point_of_sale/static/src/app/screens/product_screen/product_list/product_list.js +++ b/addons/point_of_sale/static/src/app/screens/product_screen/product_list/product_list.js @@ -10,6 +10,7 @@ import { ProductsWidgetControlPanel } from "@point_of_sale/app/screens/product_s import { Component, useState } from "@odoo/owl"; import { sprintf } from "@web/core/utils/strings"; import { OfflineErrorPopup } from "@point_of_sale/app/errors/popups/offline_error_popup"; +import { ErrorPopup } from "@point_of_sale/app/errors/popups/error_popup"; export class ProductsWidget extends Component { static components = { ProductItem, ProductsWidgetControlPanel }; @@ -30,8 +31,8 @@ export class ProductsWidget extends Component { this.notification = useService("pos_notification"); this.orm = useService("orm"); } - get hasProducts() { - return Object.keys(this.pos.db.product_by_id).length > 0; + get posHasValidProduct() { + return this.pos.posHasValidProduct(); } get selectedCategoryId() { return this.pos.selectedCategoryId; @@ -166,17 +167,42 @@ export class ProductsWidget extends Component { } } async loadDemoDataProducts() { - const { products, categories } = await this.orm.call( + const { models_data, successful } = await this.orm.call( "pos.session", "load_product_frontend", [this.pos.pos_session.id] ); - this.pos.db.add_categories(categories); - this.pos._loadProductProduct(products); + if (!successful) { + this.popup.add(ErrorPopup, { + title: this.env._t("Demo products are no longer available"), + body: this.env._t( + "A valid product already exists for Point of Sale. Therefore, demonstration products cannot be loaded." + ), + }); + // But the received models_data is still used to update the current session. + } + if (!models_data) { + this._showLoadDemoDataMissingDataError("models_data"); + return; + } + for (const dataName of ["pos.category", "product.product"]) { + if (!models_data[dataName]) { + this._showLoadDemoDataMissingDataError(dataName); + return; + } + } + this.pos.updateModelsData(models_data); + } + _showLoadDemoDataMissingDataError(missingData) { + console.error( + "Missing '", + missingData, + "' in pos.session:load_product_frontend server answer." + ); } createNewProducts() { - window.open("/web#action=point_of_sale.action_client_product_menu", "_blank"); + window.open("/web#action=point_of_sale.action_client_product_menu", "_self"); this.state.showReloadMessage = true; } } diff --git a/addons/point_of_sale/static/src/app/screens/product_screen/product_list/product_list.xml b/addons/point_of_sale/static/src/app/screens/product_screen/product_list/product_list.xml index e9eb102c249..c581cdfc9d5 100644 --- a/addons/point_of_sale/static/src/app/screens/product_screen/product_list/product_list.xml +++ b/addons/point_of_sale/static/src/app/screens/product_screen/product_list/product_list.xml @@ -13,26 +13,30 @@ hasNoCategories="hasNoCategories" loadProductFromServer.bind="onPressEnterKey" />
-
+
-

- No product found for "" in this category. -

-

- There are no products in this category. -

-
- - -
- Please reload this page once products have been created -
-
+ +

No products found for "" in this category.

+
+ + +

There are no products in this category.

+
+ +
+

No products here, but don't worry, we've got your back.

+

Play with our demo products or create your own products

+
+ Please reload this page once products have been created +
+
+
+
Search more
diff --git a/addons/point_of_sale/static/src/app/store/db.js b/addons/point_of_sale/static/src/app/store/db.js index 50f8a1f9a1d..6d7417d9c26 100644 --- a/addons/point_of_sale/static/src/app/store/db.js +++ b/addons/point_of_sale/static/src/app/store/db.js @@ -118,7 +118,10 @@ export class PosDB { if (!self.category_childs[parent_id]) { self.category_childs[parent_id] = []; } - self.category_childs[parent_id].push(cat.id); + + if (!self.category_childs[parent_id].includes(cat.id)) { + self.category_childs[parent_id].push(cat.id); + } }); function make_ancestors(cat_id, ancestors) { self.category_ancestors[cat_id] = ancestors; @@ -133,7 +136,43 @@ export class PosDB { } make_ancestors(this.root_category_id, []); } + /** + * Removes all categories specified by their id. + * @param {integer[]} categories_id + */ + remove_categories(categories_id) { + categories_id = categories_id.filter((cat_id) => cat_id !== this.root_category_id); + categories_id.forEach((cat_id) => { + if (cat_id === undefined || cat_id === null) { + return; + } + const cat = this.category_by_id[cat_id]; + if (!cat) { + return; + } + const parent_id = this.category_parent[cat.id]; + if (this.category_childs[parent_id]) { + this._remove_all_occurrences_from_array(this.category_childs[parent_id], cat.id); + if (this.category_childs[parent_id].length === 0) { + delete this.category_childs[parent_id]; + } + } + delete this.category_parent[cat.id]; + + delete this.category_by_id[cat_id]; + }); + const removed_categories_id = new Set(categories_id); + for (const cat_id_str in this.category_ancestors) { + if (removed_categories_id.has(Number(cat_id_str))) { + delete this.category_ancestors[cat_id_str]; + } else { + this.category_ancestors[cat_id_str] = this.category_ancestors[cat_id_str].filter( + (anc_id_str) => !removed_categories_id.has(Number(anc_id_str)) + ); + } + } + } /* loads a record store from the database. returns default if nothing is found */ load(store, deft) { if (CACHE[store] !== undefined) { @@ -220,6 +259,72 @@ export class PosDB { } } } + /** + * Removes all products specified by their id. + * @param {integer[]} products_id + */ + remove_products(products_id) { + if (!(products_id instanceof Array)) { + products_id = [products_id]; + } + products_id.forEach((product_id) => { + if (product_id === undefined || product_id === null) { + return; + } + const product = this.product_by_id[product_id]; + if (!product) { + return; + } + if (product.available_in_pos) { + const product_search_string = unaccent(this._product_search_string(product)); + const all_categ_ids = product.pos_categ_ids.length + ? product.pos_categ_ids + : [this.root_category_id]; + + for (const categ_id of all_categ_ids) { + this.remove_product_from_category(product.id, product_search_string, categ_id); + const categ_ancestors_id = this.get_category_ancestors_ids(categ_id) || []; + categ_ancestors_id.forEach((ancestor_id) => { + this.remove_product_from_category( + product.id, + product_search_string, + ancestor_id + ); + }); + } + } + delete this.product_by_id[product.id]; + if (product.barcode) { + delete this.product_by_barcode[product.barcode]; + } + }); + } + remove_product_from_category(product_id, product_search_string, categ_id) { + const stored_categories = this.product_by_category_id; + if (stored_categories[categ_id]) { + this._remove_all_occurrences_from_array(stored_categories[categ_id], product_id); + if (stored_categories[categ_id].length === 0) { + delete stored_categories[categ_id]; + } + } + + if (this.category_search_string[categ_id]) { + this.category_search_string[categ_id] = this.category_search_string[categ_id].replace( + product_search_string, + "" + ); + } + if (!this.category_search_string[categ_id]) { + delete this.category_search_string[categ_id]; + } + } + _remove_all_occurrences_from_array(array, element) { + for (let i = array.length - 1; i >= 0; i--) { + if (array[i] === element) { + array.splice(i, 1); + } + } + } add_packagings(product_packagings) { var self = this; Object.values(product_packagings || {}).map((product_packaging) => { diff --git a/addons/point_of_sale/static/src/app/store/pos_store.js b/addons/point_of_sale/static/src/app/store/pos_store.js index 6f000c71566..e484e4c7759 100644 --- a/addons/point_of_sale/static/src/app/store/pos_store.js +++ b/addons/point_of_sale/static/src/app/store/pos_store.js @@ -243,6 +243,7 @@ export class PosStore extends Reactive { this._loadPosPaymentMethod(); this.fiscal_positions = loadedData["account.fiscal.position"]; this.base_url = loadedData["base_url"]; + this.pos_has_valid_product = loadedData["pos_has_valid_product"]; await this._loadPictures(); await this._loadPosPrinters(loadedData["pos.printer"]); } @@ -393,6 +394,53 @@ export class PosStore extends Reactive { return this.addPartners(partners); } + async updateModelsData(models_data) { + const products = models_data["product.product"]; + const categories = models_data["pos.category"]; + + let removed_categories_id; + if (categories) { + const previous_categories_id = Object.values(this.db.category_by_id).map((c) => c.id); + const received_categories_id = new Set(categories.map((c) => c.id)); + this.db.add_categories(categories); + removed_categories_id = previous_categories_id.filter( + (p) => !received_categories_id.has(p) + ); + } + if (products) { + const previous_products_id = Object.values(this.db.product_by_id).map((p) => p.id); + const received_products_id = new Set(products.map((p) => p.id)); + this._loadProductProduct(products); + + const removed_products_id = previous_products_id.filter( + (p) => !received_products_id.has(p) + ); + this.db.remove_products(removed_products_id); + + if ( + Object.values(this.db.product_by_id).some( + (p) => p.available_in_pos && p.lst_price > 0 + ) + ) { + this.pos_has_valid_product = true; + } + } + + if (categories) { + this.db.remove_categories(removed_categories_id); + } + } + + /** + * @returns true if the POS app (not only this POS config) has at least one valid product. + */ + posHasValidProduct() { + return ( + this.pos_has_valid_product || + Object.values(this.db.product_by_id).some((p) => p.available_in_pos && p.lst_price > 0) + ); + } + setSelectedCategoryId(categoryId) { this.selectedCategoryId = categoryId; } diff --git a/addons/point_of_sale/static/src/scss/pos.scss b/addons/point_of_sale/static/src/scss/pos.scss index 3e0d0c3eb3f..38207782383 100644 --- a/addons/point_of_sale/static/src/scss/pos.scss +++ b/addons/point_of_sale/static/src/scss/pos.scss @@ -485,7 +485,7 @@ td { justify-content: center; flex-direction: column; border: none; - + h1 { font-size: 20px; margin: 0; @@ -889,7 +889,7 @@ td { color: white; border: solid 1px $primary; } - + } .pos .product-list-scroller{ @@ -2945,7 +2945,7 @@ td { font-size: 12px; font-weight: bold; margin: 5px; - + div { margin: 0; } @@ -3719,6 +3719,8 @@ td { padding: 10px 0; cursor: pointer; font-size: large; + color: #017e84; + font-weight: bold; } .info-load-product-message { @@ -3901,7 +3903,7 @@ td { .menu-item { padding: 10px; - + span, i { color: black; inline-size: 196px; diff --git a/addons/pos_restaurant/__manifest__.py b/addons/pos_restaurant/__manifest__.py index ad9a92b4b8e..fdff2235057 100644 --- a/addons/pos_restaurant/__manifest__.py +++ b/addons/pos_restaurant/__manifest__.py @@ -17,12 +17,14 @@ This module adds several features to the Point of Sale that are specific to rest """, 'depends': ['point_of_sale'], + 'auto_install': True, 'website': 'https://www.odoo.com/app/point-of-sale-restaurant', 'data': [ 'security/ir.model.access.csv', 'views/pos_order_views.xml', 'views/pos_restaurant_views.xml', 'views/res_config_settings_views.xml', + 'data/pos_restaurant_data.xml', ], 'demo': [ 'data/pos_restaurant_demo.xml', diff --git a/addons/pos_restaurant/data/pos_restaurant_data.xml b/addons/pos_restaurant/data/pos_restaurant_data.xml new file mode 100644 index 00000000000..a12752b99da --- /dev/null +++ b/addons/pos_restaurant/data/pos_restaurant_data.xml @@ -0,0 +1,19 @@ + + + + + Restaurant + True + True + False + True + False + False + False + + + + + + + diff --git a/addons/pos_restaurant/data/pos_restaurant_onboarding.xml b/addons/pos_restaurant/data/pos_restaurant_onboarding.xml new file mode 100644 index 00000000000..2bd34ff67a7 --- /dev/null +++ b/addons/pos_restaurant/data/pos_restaurant_onboarding.xml @@ -0,0 +1,55 @@ + + + + Drinks + + + + Food + + + + + Restaurant food + + + + + True + 7.0 + Margherita + 0.01 + + + + + + True + 7.0 + Cheese Burger + 0.01 + + + + + + + + True + 2.20 + Coca-Cola + 0.01 + + + + + + True + 2.20 + Water + 0.01 + + + + + diff --git a/addons/pos_restaurant/models/pos_config.py b/addons/pos_restaurant/models/pos_config.py index 2e61fee03d1..a9a47d70170 100644 --- a/addons/pos_restaurant/models/pos_config.py +++ b/addons/pos_restaurant/models/pos_config.py @@ -59,10 +59,33 @@ class PosConfig(models.Model): forbidden_keys.append('floor_ids') return forbidden_keys + def _set_tips_after_payment_if_country_custom(self): + self.ensure_one() + company = self.company_id or self.env.company or self.env['res.company']._get_main_company() + if company and company.country_id and company.country_id.code == 'US': + self.update({ + 'iface_tipproduct': True, + 'set_tip_after_payment': True, + }) + + @api.model_create_multi + def create(self, vals_list): + for vals in vals_list: + is_restaurant = 'module_pos_restaurant' not in vals or vals['module_pos_restaurant'] + if is_restaurant and 'iface_splitbill' not in vals: + vals['iface_splitbill'] = True + if not is_restaurant or not vals.get('iface_tipproduct', False): + vals['set_tip_after_payment'] = False + return super(PosConfig, self).create(vals_list) + def write(self, vals): if ('module_pos_restaurant' in vals and vals['module_pos_restaurant'] is False): vals['floor_ids'] = [(5, 0, 0)] - return super(PosConfig, self).write(vals) + + if ('module_pos_restaurant' in vals and not vals['module_pos_restaurant']) or ('iface_tipproduct' in vals and not vals['iface_tipproduct']): + vals['set_tip_after_payment'] = False + + return super().write(vals) @api.model def add_cash_payment_method(self): diff --git a/addons/pos_restaurant/models/pos_session.py b/addons/pos_restaurant/models/pos_session.py index 87897eadcce..68dc2a4ab92 100644 --- a/addons/pos_restaurant/models/pos_session.py +++ b/addons/pos_restaurant/models/pos_session.py @@ -1,7 +1,8 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import models +from odoo import models, Command +from odoo.tools import convert from itertools import groupby from odoo.osv.expression import AND @@ -52,3 +53,12 @@ class PosSession(models.Model): def get_pos_ui_restaurant_floor(self): return self._get_pos_ui_restaurant_floor(self._loader_params_restaurant_floor()) + + def _load_onboarding_data(self): + super()._load_onboarding_data() + convert.convert_file(self.env, 'pos_restaurant', 'data/pos_restaurant_onboarding.xml', None, mode='init', kind='data') + configs = self.config_id.filtered('module_pos_restaurant').union(self.env.ref('pos_restaurant.pos_config_main_restaurant', raise_if_not_found=False)) + configs.with_context(bypass_categories_forbidden_change=True).write({ + 'limit_categories': True, + 'iface_available_categ_ids': [Command.link(self.env.ref('pos_restaurant.onboarding_drinks_category').id), Command.link(self.env.ref('pos_restaurant.onboarding_food_category').id)] + }) diff --git a/addons/pos_restaurant/static/src/app/floor_screen/edit_bar.xml b/addons/pos_restaurant/static/src/app/floor_screen/edit_bar.xml index c1f296d5d71..1ffc030533f 100644 --- a/addons/pos_restaurant/static/src/app/floor_screen/edit_bar.xml +++ b/addons/pos_restaurant/static/src/app/floor_screen/edit_bar.xml @@ -6,7 +6,7 @@ - ADD + TABLE @@ -63,7 +63,7 @@
-
+
diff --git a/addons/pos_restaurant/static/src/app/floor_screen/floor_screen.js b/addons/pos_restaurant/static/src/app/floor_screen/floor_screen.js index d3125225668..a656f24fcf1 100644 --- a/addons/pos_restaurant/static/src/app/floor_screen/floor_screen.js +++ b/addons/pos_restaurant/static/src/app/floor_screen/floor_screen.js @@ -363,7 +363,8 @@ export class FloorScreen extends Component { } async addFloor() { const { confirmed, payload: newName } = await this.popup.add(TextInputPopup, { - title: this.env._t("Floor Name"), + title: this.env._t("New Floor"), + placeholder: this.env._t("Floor name"), }); if (!confirmed) { return; diff --git a/addons/pos_restaurant/static/src/app/floor_screen/floor_screen.xml b/addons/pos_restaurant/static/src/app/floor_screen/floor_screen.xml index 41e4236dc51..38a9db8f913 100644 --- a/addons/pos_restaurant/static/src/app/floor_screen/floor_screen.xml +++ b/addons/pos_restaurant/static/src/app/floor_screen/floor_screen.xml @@ -3,10 +3,10 @@
- @@ -31,7 +31,7 @@ >
- No tables available,
ADD your first table
+ Oops! No tables available.
Add a new table to get started.
@@ -42,7 +42,7 @@
- No floors available,
ADD a floor to start
+ Oops! No floors available.
Add a new floor to get started.
diff --git a/addons/pos_restaurant/static/src/app/floor_screen/table.js b/addons/pos_restaurant/static/src/app/floor_screen/table.js index 06c4ea0fbb5..92fb2b383d3 100644 --- a/addons/pos_restaurant/static/src/app/floor_screen/table.js +++ b/addons/pos_restaurant/static/src/app/floor_screen/table.js @@ -99,12 +99,15 @@ export class Table extends Component { // do not count the orders that are already finalized !o.finalized ); + let result; if (table.changes_count > 0) { - return table.changes_count; + result = table.changes_count; } else if (table.skip_changes > 0) { - return table.skip_changes; + result = table.skip_changes; + } else { + result = table.order_count + unsynced_orders.length; } - return table.order_count + unsynced_orders.length; + return !Number.isNaN(result) ? result : 0; } get orderCountClass() { const countClass = { "order-count": true }; diff --git a/addons/pos_restaurant/static/src/js/Screens/TicketScreen.js b/addons/pos_restaurant/static/src/js/Screens/TicketScreen.js index ffba45c1059..66dafc852fe 100644 --- a/addons/pos_restaurant/static/src/js/Screens/TicketScreen.js +++ b/addons/pos_restaurant/static/src/js/Screens/TicketScreen.js @@ -117,7 +117,7 @@ patch(TicketScreen.prototype, "pos_restaurant.TicketScreen", { } }, async setNoTip(serverId) { - await this.orm.call("set_no_tip", "pos.order", [serverId]); + await this.orm.call("pos.order", "set_no_tip", [serverId]); }, _getOrderStates() { const result = this._super(...arguments); diff --git a/addons/pos_restaurant/tests/test_frontend.py b/addons/pos_restaurant/tests/test_frontend.py index 21dc7c52880..9a074e84829 100644 --- a/addons/pos_restaurant/tests/test_frontend.py +++ b/addons/pos_restaurant/tests/test_frontend.py @@ -49,6 +49,7 @@ class TestFrontend(odoo.tests.HttpCase): 'start_category': True, 'is_order_printer': True, 'printer_ids': [(4, printer.id)], + 'iface_tipproduct': False, }) main_floor = self.env['restaurant.floor'].create({ diff --git a/addons/pos_restaurant/views/res_config_settings_views.xml b/addons/pos_restaurant/views/res_config_settings_views.xml index b741f5f049d..8994ec0e24c 100644 --- a/addons/pos_restaurant/views/res_config_settings_views.xml +++ b/addons/pos_restaurant/views/res_config_settings_views.xml @@ -33,7 +33,7 @@
-
diff --git a/addons/pos_self_order/__manifest__.py b/addons/pos_self_order/__manifest__.py index ef24383ac54..7aaf2812e37 100644 --- a/addons/pos_self_order/__manifest__.py +++ b/addons/pos_self_order/__manifest__.py @@ -19,6 +19,7 @@ "data/restaurant_table_data.xml", "views/res_config_settings_views.xml", "views/point_of_sale_dashboard.xml", + "data/pos_restaurant_data.xml", ], "assets": { "pos_self_order.assets_self_order": [ diff --git a/addons/pos_self_order/data/pos_restaurant_data.xml b/addons/pos_self_order/data/pos_restaurant_data.xml new file mode 100644 index 00000000000..2460f4c862a --- /dev/null +++ b/addons/pos_self_order/data/pos_restaurant_data.xml @@ -0,0 +1,17 @@ + + + + + True + True + + + + + diff --git a/addons/pos_self_order/models/pos_config.py b/addons/pos_self_order/models/pos_config.py index ce936d34c9f..5e384e62f2a 100644 --- a/addons/pos_self_order/models/pos_config.py +++ b/addons/pos_self_order/models/pos_config.py @@ -36,7 +36,7 @@ class PosConfig(models.Model): self_order_pay_after = fields.Selection( [("each", "Each Order"), ("meal", "Meal")], string="Pay After:", - default="each", + default="meal", help="Choose when the customer will pay", required=True, ) diff --git a/addons/pos_self_order/models/res_config_settings.py b/addons/pos_self_order/models/res_config_settings.py index 806b683e8c4..f0e4b1d918d 100644 --- a/addons/pos_self_order/models/res_config_settings.py +++ b/addons/pos_self_order/models/res_config_settings.py @@ -16,7 +16,7 @@ class ResConfigSettings(models.TransientModel): pos_self_order_pay_after = fields.Selection( [("each", "Each Order"), ("meal", "Meal")], string="Pay After:", - default="each", + default="meal", help="Choose when the customer will pay", readonly=False, required=True,