diff --git a/addons/point_of_sale/__manifest__.py b/addons/point_of_sale/__manifest__.py index 06988f6149f..9822e584ba8 100644 --- a/addons/point_of_sale/__manifest__.py +++ b/addons/point_of_sale/__manifest__.py @@ -42,8 +42,9 @@ 'views/report_saledetails.xml', 'views/point_of_sale_dashboard.xml', 'views/report_invoice.xml', - 'views/res_config_settings_views.xml', + 'views/pos_printer_view.xml', 'views/pos_ticket_view.xml', + 'views/res_config_settings_views.xml', ], 'demo': [ 'data/point_of_sale_demo.xml', diff --git a/addons/point_of_sale/data/point_of_sale_demo.xml b/addons/point_of_sale/data/point_of_sale_demo.xml index c5a5dee0949..ca4625d7826 100644 --- a/addons/point_of_sale/data/point_of_sale_demo.xml +++ b/addons/point_of_sale/data/point_of_sale_demo.xml @@ -36,6 +36,13 @@ True + + + Preparation Printer + localhost + + + diff --git a/addons/point_of_sale/models/__init__.py b/addons/point_of_sale/models/__init__.py index fa5ffbc95f7..c71d05f2c84 100644 --- a/addons/point_of_sale/models/__init__.py +++ b/addons/point_of_sale/models/__init__.py @@ -24,3 +24,4 @@ from . import pos_payment from . import pos_payment_method from . import pos_bill from . import report_sale_details +from . import pos_printer diff --git a/addons/point_of_sale/models/pos_config.py b/addons/point_of_sale/models/pos_config.py index dfabda5fb01..24dc0967403 100644 --- a/addons/point_of_sale/models/pos_config.py +++ b/addons/point_of_sale/models/pos_config.py @@ -47,6 +47,8 @@ class PosConfig(models.Model): return self.env.ref('point_of_sale.group_pos_user') name = fields.Char(string='Point of Sale', required=True, help="An internal identification of the point of sale.") + printer_ids = fields.Many2many('pos.printer', 'pos_config_printer_rel', 'config_id', 'printer_id', string='Order Printers') + is_order_printer = fields.Boolean('Order Printer') is_installed_account_accountant = fields.Boolean(string="Is the Full Accounting Installed", compute="_compute_is_installed_account_accountant") picking_type_id = fields.Many2one( @@ -402,6 +404,9 @@ class PosConfig(models.Model): 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()] + opened_session = self.mapped('session_ids').filtered(lambda s: s.state != 'closed') if opened_session: forbidden_fields = [] @@ -484,7 +489,7 @@ class PosConfig(models.Model): def _force_http(self): enforce_https = self.env['ir.config_parameter'].sudo().get_param('point_of_sale.enforce_https') - if not enforce_https and self.other_devices: + if not enforce_https and (self.other_devices or self.printer_ids.filtered(lambda pt: pt.printer_type == 'epson_epos')): return True return False diff --git a/addons/point_of_sale/models/pos_order.py b/addons/point_of_sale/models/pos_order.py index 0895abdfc21..04adc0afb11 100644 --- a/addons/point_of_sale/models/pos_order.py +++ b/addons/point_of_sale/models/pos_order.py @@ -59,6 +59,7 @@ class PosOrder(models.Model): 'tip_amount': ui_order.get('tip_amount', 0), 'access_token': ui_order.get('access_token', ''), 'ticket_code': ui_order.get('ticket_code', ''), + 'last_order_preparation_change': ui_order.get('last_order_preparation_change', False), } @api.model @@ -237,6 +238,7 @@ class PosOrder(models.Model): return price_unit name = fields.Char(string='Order Ref', required=True, readonly=True, copy=False, default='/') + last_order_preparation_change = fields.Char(string='Last preparation change', help="Last printed state of the order") date_order = fields.Datetime(string='Date', readonly=True, index=True, default=fields.Datetime.now) user_id = fields.Many2one( comodel_name='res.users', string='Responsible', @@ -280,7 +282,7 @@ class PosOrder(models.Model): picking_type_id = fields.Many2one('stock.picking.type', related='session_id.config_id.picking_type_id', string="Operation Type", readonly=False) procurement_group_id = fields.Many2one('procurement.group', 'Procurement Group', copy=False) - note = fields.Text(string='Kitchen Notes') + note = fields.Text(string='Internal Notes') nb_print = fields.Integer(string='Number of Print', readonly=True, copy=False, default=0) pos_reference = fields.Char(string='Receipt Number', readonly=True, copy=False) sale_journal = fields.Many2one('account.journal', related='session_id.config_id.journal_id', string='Sales Journal', store=True, readonly=True, ondelete='restrict') @@ -1103,6 +1105,7 @@ class PosOrder(models.Model): 'create_uid', 'create_date', 'fiscal_position_id', + 'last_order_preparation_change', 'to_invoice', 'access_token', 'ticket_code', @@ -1232,7 +1235,9 @@ class PosOrder(models.Model): """This function is here to be overriden""" fields = [ 'id', + 'uuid', 'discount', + 'skip_change', 'product_id', 'price_unit', 'order_id', @@ -1278,6 +1283,7 @@ class PosOrderLine(models.Model): company_id = fields.Many2one('res.company', string='Company', related="order_id.company_id", store=True) name = fields.Char(string='Line No', required=True, copy=False) + skip_change = fields.Boolean('Skip line when sending ticket to kitchen printers.') notice = fields.Char(string='Discount Notice') product_id = fields.Many2one('product.product', string='Product', domain=[('sale_ok', '=', True)], required=True, change_default=True) price_unit = fields.Float(string='Unit Price', digits=0) @@ -1303,6 +1309,7 @@ class PosOrderLine(models.Model): refund_orderline_ids = fields.One2many('pos.order.line', 'refunded_orderline_id', 'Refund Order Lines', help='Orderlines in this field are the lines that refunded this orderline.') refunded_orderline_id = fields.Many2one('pos.order.line', 'Refunded Order Line', help='If this orderline is a refund, then the refunded orderline is specified in this field.') refunded_qty = fields.Float('Refunded Quantity', compute='_compute_refund_qty', help='Number of items refunded in this orderline.') + uuid = fields.Char(string='Uuid', readonly=True, copy=False) @api.depends('refund_orderline_ids') def _compute_refund_qty(self): @@ -1402,6 +1409,8 @@ class PosOrderLine(models.Model): return { 'qty': orderline.qty, 'price_unit': orderline.price_unit, + 'skip_change': orderline.skip_change, + 'uuid': orderline.uuid, 'price_subtotal': orderline.price_subtotal, 'price_subtotal_incl': orderline.price_subtotal_incl, 'product_id': orderline.product_id.id, diff --git a/addons/point_of_sale/models/pos_printer.py b/addons/point_of_sale/models/pos_printer.py new file mode 100644 index 00000000000..c9d6c182c5c --- /dev/null +++ b/addons/point_of_sale/models/pos_printer.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models, api, _ +from odoo.exceptions import ValidationError + +class PosPrinter(models.Model): + + _name = 'pos.printer' + _description = 'Point of Sale Printer' + + name = fields.Char('Printer Name', required=True, default='Printer', help='An internal identification of the printer') + printer_type = fields.Selection(string='Printer Type', default='iot', + selection=[('iot', ' Use a printer connected to the IoT Box')]) + proxy_ip = fields.Char('Proxy IP Address', help="The IP Address or hostname of the Printer's hardware proxy") + product_categories_ids = fields.Many2many('pos.category', 'printer_category_rel', 'printer_id', 'category_id', string='Printed Product Categories') + + @api.constrains('proxy_ip') + def _constrains_proxy_ip(self): + for record in self: + if record.printer_type == 'iot' and not record.proxy_ip: + raise ValidationError(_("Proxy IP cannot be empty.")) diff --git a/addons/point_of_sale/models/pos_session.py b/addons/point_of_sale/models/pos_session.py index c20393212b8..7a7c65e214c 100644 --- a/addons/point_of_sale/models/pos_session.py +++ b/addons/point_of_sale/models/pos_session.py @@ -1654,6 +1654,7 @@ class PosSession(models.Model): 'account.tax', 'pos.session', 'pos.config', + 'pos.printer', 'pos.bill', 'res.partner', 'stock.picking.type', @@ -1887,6 +1888,17 @@ class PosSession(models.Model): def _get_pos_ui_res_currency(self, params): return self.env['res.currency'].search_read(**params['search_params'])[0] + def _get_pos_ui_pos_printer(self, params): + return self.env['pos.printer'].search_read(**params['search_params']) + + def _loader_params_pos_printer(self): + return { + 'search_params': { + 'domain': [('id', 'in', self.config_id.printer_ids.ids)], + 'fields': ['name', 'proxy_ip', 'product_categories_ids', 'printer_type'], + }, + } + def _loader_params_pos_category(self): domain = [] if self.config_id.limit_categories and self.config_id.iface_available_categ_ids: diff --git a/addons/point_of_sale/models/res_config_settings.py b/addons/point_of_sale/models/res_config_settings.py index 30c11da236b..91b4d7bb657 100644 --- a/addons/point_of_sale/models/res_config_settings.py +++ b/addons/point_of_sale/models/res_config_settings.py @@ -45,6 +45,8 @@ class ResConfigSettings(models.TransientModel): pos_module_pos_discount = fields.Boolean(related='pos_config_id.module_pos_discount', readonly=False) pos_module_pos_hr = fields.Boolean(related='pos_config_id.module_pos_hr', readonly=False) pos_module_pos_restaurant = fields.Boolean(related='pos_config_id.module_pos_restaurant', readonly=False) + pos_is_order_printer = fields.Boolean(compute='_compute_pos_printer', store=True, readonly=False) + pos_printer_ids = fields.Many2many(related='pos_config_id.printer_ids', readonly=False) pos_allowed_pricelist_ids = fields.Many2many('product.pricelist', compute='_compute_pos_allowed_pricelist_ids') pos_amount_authorized_diff = fields.Float(related='pos_config_id.amount_authorized_diff', readonly=False) @@ -182,6 +184,13 @@ class ResConfigSettings(models.TransientModel): def _is_cashdrawer_displayed(self, res_config): return res_config.pos_iface_print_via_proxy + @api.depends('pos_module_pos_restaurant', 'pos_config_id') + def _compute_pos_printer(self): + for res_config in self: + res_config.update({ + 'pos_is_order_printer': res_config.pos_config_id.is_order_printer, + }) + @api.depends('pos_limit_categories', 'pos_config_id') def _compute_pos_iface_available_categ_ids(self): for res_config in self: diff --git a/addons/point_of_sale/security/ir.model.access.csv b/addons/point_of_sale/security/ir.model.access.csv index d88bb408051..78d331cc471 100644 --- a/addons/point_of_sale/security/ir.model.access.csv +++ b/addons/point_of_sale/security/ir.model.access.csv @@ -1,4 +1,6 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_pos_printer_manager,pos.printer.manager,model_pos_printer,point_of_sale.group_pos_manager,1,1,1,1 +access_pos_printer,pos.printer.user,model_pos_printer,point_of_sale.group_pos_user,1,0,0,0 access_pos_order,pos.order,model_pos_order,group_pos_user,1,1,1,1 access_pos_order_line,pos.order.line,model_pos_order_line,group_pos_user,1,1,1,1 access_pos_pack_operation_lot,pos.pack.operation.lot,model_pos_pack_operation_lot,group_pos_user,1,1,1,1 diff --git a/addons/point_of_sale/static/src/app/pos_store.js b/addons/point_of_sale/static/src/app/pos_store.js index 739eb120e61..dfe73c74786 100644 --- a/addons/point_of_sale/static/src/app/pos_store.js +++ b/addons/point_of_sale/static/src/app/pos_store.js @@ -56,6 +56,25 @@ export class PosStore extends Reactive { } } + // Now the printer should work in PoS without restaurant + async sendOrderInPreparation(order) { + if (this.globalState.printers_category_ids_set.size) { + try { + if (order.hasChangesToPrint()) { + const isPrintSuccessful = await order.printChanges(); + if (!isPrintSuccessful) { + this.popup.add(ErrorPopup, { + title: _t("Printing failed"), + body: _t("Failed in printing the changes in the order"), + }); + } + } + } catch (e) { + console.warn("Failed in printing the changes in the order", e); + } + } + order.updateLastOrderChange(); + } closeScreen() { const { name: screenName } = this.globalState.get_order().get_screen_data(); this.showScreen(screenName); diff --git a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/CustomerButton.js b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/CustomerButton.js index b3b97abf2da..f64d80b4476 100644 --- a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/CustomerButton.js +++ b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/CustomerButton.js @@ -23,7 +23,7 @@ ProductScreen.addControlButton({ condition: function () { return ( this.pos.globalState.config.module_pos_restaurant && - this.pos.globalState.printers_category_ids_set.size + this.pos.globalState.orderPreparationCategories.size ); }, }); diff --git a/addons/point_of_sale/static/src/js/Screens/ProductScreen/Orderline.js b/addons/point_of_sale/static/src/js/Screens/ProductScreen/Orderline.js index e1b96722b1a..1554c4c977f 100644 --- a/addons/point_of_sale/static/src/js/Screens/ProductScreen/Orderline.js +++ b/addons/point_of_sale/static/src/js/Screens/ProductScreen/Orderline.js @@ -1,11 +1,34 @@ /** @odoo-module */ import { Component } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/pos_hook"; export class Orderline extends Component { static template = "Orderline"; + /** + * if doubleclick, change hasChange to skipChange + * + * IMPROVEMENT: Instead of handling both double click and click in single + * method, perhaps we can separate double click from single click. + */ + setup() { + this.pos = usePos(); + } + selectLine() { + const line = this.props.line; // the orderline + if (this.env.pos.get_order().selected_orderline.id !== line.id) { + this.mp_dbclk_time = new Date().getTime(); + } else if (!this.mp_dbclk_time) { + this.mp_dbclk_time = new Date().getTime(); + } else if (this.mp_dbclk_time + 500 > new Date().getTime()) { + line.toggleSkipChange(); + this.mp_dbclk_time = 0; + } else { + this.mp_dbclk_time = new Date().getTime(); + } + this.props.selectLine(this.props.line); } lotIconClicked() { @@ -14,6 +37,10 @@ export class Orderline extends Component { get addedClasses() { return { selected: this.props.line.selected, + "has-change": + this.props.line.hasChange && this.pos.globalState.config.module_pos_restaurant, + "skip-change": + this.props.line.skipChange && this.pos.globalState.config.module_pos_restaurant, }; } get customerNote() { diff --git a/addons/point_of_sale/static/src/js/Screens/ReceiptScreen/ReceiptScreen.js b/addons/point_of_sale/static/src/js/Screens/ReceiptScreen/ReceiptScreen.js index e90252ab228..f8f916a2f34 100644 --- a/addons/point_of_sale/static/src/js/Screens/ReceiptScreen/ReceiptScreen.js +++ b/addons/point_of_sale/static/src/js/Screens/ReceiptScreen/ReceiptScreen.js @@ -43,6 +43,12 @@ export class ReceiptScreen extends AbstractReceiptScreen { await this.handleAutoPrint(); } }, 0); + + // When the order is paid, if there is still a part of the order + // to send in preparation it is automatically sent + if (this.pos.globalState.orderPreparationCategories.size) { + this.pos.sendOrderInPreparation(this.currentOrder); + } }); } _addNewOrder() { diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index 8ed0cf49220..eed913f9863 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -3,9 +3,10 @@ import { PosDB } from "@point_of_sale/js/db"; import { formatFloat } from "@web/views/fields/formatters"; +import { uuidv4, batched, deduceUrl } from "@point_of_sale/js/utils"; +import { HWPrinter } from "@point_of_sale/app/printer/hw_printer"; // FIXME POSREF - unify use of native parseFloat and web's parseFloat. We probably don't need the native version. import { parseFloat as oParseFloat } from "@web/views/fields/parsers"; -import { batched, uuidv4 } from "@point_of_sale/js/utils"; import { formatDate, formatDateTime, serializeDateTime } from "@web/core/l10n/dates"; import { roundDecimals as round_di, @@ -21,7 +22,7 @@ import { sprintf } from "@web/core/utils/strings"; import { Mutex } from "@web/core/utils/concurrency"; import { memoize } from "@web/core/utils/functions"; import { _t } from "@web/core/l10n/translation"; -import { renderToString } from "@web/core/utils/render"; +import { renderToString, renderToElement } from "@web/core/utils/render"; const { DateTime } = luxon; @@ -159,6 +160,7 @@ export class PosGlobalState extends PosModel { this.uom_unit_id = null; this.default_pricelist = null; this.order_sequence = 1; + this.printers_category_ids_set = new Set(); // Object mapping the order's name (which contains the uid) to it's server_id after // validation (order paid then sent to the backend). @@ -277,6 +279,7 @@ export class PosGlobalState extends PosModel { this.base_url = loadedData["base_url"]; await this._loadFonts(); await this._loadPictures(); + await this._loadPosPrinters(loadedData["pos.printer"]); } _loadPosSession() { // We need to do it here, since only then the local storage has the correct uuid @@ -286,6 +289,23 @@ export class PosGlobalState extends PosModel { this.pos_session.sequence_number = Math.max(this.pos_session.sequence_number, ...sequences); this.pos_session.login_number = odoo.login_number; } + _loadPosPrinters(printers) { + this.unwatched.printers = []; + // list of product categories that belong to one or more order printer + for (const printerConfig of printers) { + const printer = this.create_printer(printerConfig); + printer.config = printerConfig; + this.unwatched.printers.push(printer); + for (const id of printer.config.product_categories_ids) { + this.printers_category_ids_set.add(id); + } + } + this.config.iface_printers = !!this.unwatched.printers.length; + } + create_printer(config) { + const url = deduceUrl(config.proxy_ip || ""); + return new HWPrinter({ rpc: this.env.services.rpc, url }); + } _loadPoSConfig() { this.db.set_uuid(this.config.uuid); } @@ -447,6 +467,12 @@ export class PosGlobalState extends PosModel { get_cashier_user_id() { return this.user.id; } + get orderPreparationCategories() { + if (this.printers_category_ids_set) { + return new Set([...this.printers_category_ids_set]); + } + return new Set(); + } cashierHasPriceControlRights() { return !this.config.restrict_price_control || this.get_cashier().role == "manager"; } @@ -730,10 +756,11 @@ export class PosGlobalState extends PosModel { return message; } async _getPricelistJson(pricelistsToGet) { - return await this.orm.call("pos.session", "get_pos_ui_product_pricelists_by_ids", [ - [odoo.pos_session_id], - pricelistsToGet, - ]); + return await this.env.services.orm.call( + "pos.session", + "get_pos_ui_product_pricelists_by_ids", + [[odoo.pos_session_id], pricelistsToGet] + ); } _addPosPricelists(pricelistsJson) { if (!this.config.use_pricelist) { @@ -772,10 +799,11 @@ export class PosGlobalState extends PosModel { return message; } async _getFiscalPositionJson(fiscalPositionToGet) { - return await this.orm.call("pos.session", "get_pos_ui_account_fiscal_positions_by_ids", [ - [odoo.pos_session_id], - fiscalPositionToGet, - ]); + return await this.env.services.orm.call( + "pos.session", + "get_pos_ui_account_fiscal_positions_by_ids", + [[odoo.pos_session_id], fiscalPositionToGet] + ); } _addPosFiscalPosition(fiscalPositionJson) { this.fiscal_positions.push(...fiscalPositionJson); @@ -1003,15 +1031,13 @@ export class PosGlobalState extends PosModel { // - timeout: timeout for the rpc call in ms // returns a promise that resolves with the list of // server generated ids for the sent orders - _save_to_server(orders, options) { + async _save_to_server(orders, options) { if (!orders || !orders.length) { return Promise.resolve([]); } this.set_synch("connecting", orders.length); options = options || {}; - var self = this; - // Keep the order ids that are about to be sent to the // backend. In between create_from_ui and the success callback // new orders may have been added to it. @@ -1023,32 +1049,46 @@ export class PosGlobalState extends PosModel { // we try to send the order. silent prevents a spinner if it takes too long. (unless we are sending an invoice, // then we want to notify the user that we are waiting on something ) const orm = options.to_invoice ? this.orm : this.orm.silent; - // FIXME POSREF timeout - // const timeout = typeof options.timeout === "number" ? options.timeout : 30000 * orders.length; - return orm - .call("pos.order", "create_from_ui", [orders, options.draft || false]) - .then(function (server_ids) { - order_ids_to_sync.forEach((order_id) => { - self.db.remove_order(order_id); - }); - self.failed = false; - self.set_synch("connected"); - return server_ids; - }) - .catch(function (error) { - console.warn("Failed to send orders:", orders); - if (error.code === 200) { - // Business Logic Error, not a connection problem - // Hide error if already shown before ... - if ((!self.failed || options.show_error) && !options.to_invoice) { - self.failed = error; - self.set_synch("error"); - throw error; - } + + try { + // FIXME POSREF timeout + // const timeout = typeof options.timeout === "number" ? options.timeout : 30000 * orders.length; + const serverIds = await orm.call("pos.order", "create_from_ui", [ + orders, + options.draft || false, + ]); + + for (const serverId of serverIds) { + const order = this.env.services.pos.globalState.orders.find( + (order) => order.name === serverId.pos_reference + ); + + if (order) { + order.server_id = serverId.id; } - self.set_synch("disconnected"); - throw error; - }); + } + + for (const order_id of order_ids_to_sync) { + this.db.remove_order(order_id); + } + + this.failed = false; + this.set_synch("connected"); + return serverIds; + } catch (error) { + console.warn("Failed to send orders:", orders); + if (error.code === 200) { + // Business Logic Error, not a connection problem + // Hide error if already shown before ... + if ((!this.failed || options.show_error) && !options.to_invoice) { + this.failed = error; + this.set_synch("error"); + throw error; + } + } + this.set_synch("disconnected"); + throw error; + } } // Exports the paid orders (the ones waiting for internet connection) @@ -1797,6 +1837,8 @@ export class Orderline extends PosModel { this.pos = options.pos; this.order = options.order; this.price_manually_set = options.price_manually_set || false; + this.uuid = this.uuid || uuidv4(); + this.price_automatically_set = options.price_automatically_set || false; if (options.json) { try { @@ -1815,6 +1857,9 @@ export class Orderline extends PosModel { this.set_product_lot(this.product); this.set_quantity(1); this.discount = 0; + this.note = ""; + this.hasChange = false; + this.skipChange = false; this.discountStr = "0"; this.selected = false; this.description = ""; @@ -1854,6 +1899,8 @@ export class Orderline extends PosModel { this.refunded_qty = json.refunded_qty; this.refunded_orderline_id = json.refunded_orderline_id; this.saved_quantity = json.qty; + this.uuid = json.uuid; + this.skipChange = json.skip_change; } clone() { var orderline = new Orderline( @@ -1934,6 +1981,20 @@ export class Orderline extends PosModel { this.has_product_lot = product.tracking !== "none"; this.pack_lot_lines = this.has_product_lot && new PosCollection(); } + getNote() { + return this.note; + } + setNote(note) { + this.note = note; + } + toggleSkipChange() { + if (this.hasChange || this.skipChange) { + this.skipChange = !this.skipChange; + } + } + setHasChange(isChange) { + this.hasChange = isChange; + } // sets a discount [0,100]% set_discount(discount) { var parsed_discount = @@ -2142,6 +2203,8 @@ export class Orderline extends PosModel { ); // only orderlines of the same product can be merged return ( + !this.skipChange && + orderline.getNote() === this.getNote() && this.get_product().id === orderline.get_product().id && this.get_unit() && this.get_unit().is_pos_groupable && @@ -2172,6 +2235,8 @@ export class Orderline extends PosModel { }); } return { + uuid: this.uuid, + skip_change: this.skipChange, qty: this.get_quantity(), price_unit: this.get_unit_price(), price_subtotal: this.get_price_without_tax(), @@ -2726,6 +2791,8 @@ export class Order extends PosModel { return fp.id === self.pos.config.default_fiscal_position_id[0]; }); } + + this.lastOrderPrepaChange = this.lastOrderPrepaChange || {}; } save_to_db() { if (!this.temporary && !this.locked && !this.finalized) { @@ -2828,6 +2895,8 @@ export class Order extends PosModel { this.tip_amount = json.tip_amount || 0; this.access_token = json.access_token || ""; this.ticketCode = json.ticket_code || ""; + this.lastOrderPrepaChange = + json.last_order_preparation_change && JSON.parse(json.last_order_preparation_change); } export_as_JSON() { var orderLines, paymentLines; @@ -2861,6 +2930,7 @@ export class Order extends PosModel { is_tipped: this.is_tipped || false, tip_amount: this.tip_amount || 0, access_token: this.access_token || "", + last_order_preparation_change: JSON.stringify(this.lastOrderPrepaChange), ticket_code: this.ticketCode || "", }; if (!this.is_paid && this.user_id) { @@ -2956,6 +3026,195 @@ export class Order extends PosModel { return receipt; } + async printChanges() { + const orderChange = this.changesToOrder; + let isPrintSuccessful = true; + const d = new Date(); + let hours = "" + d.getHours(); + hours = hours.length < 2 ? "0" + hours : hours; + let minutes = "" + d.getMinutes(); + minutes = minutes.length < 2 ? "0" + minutes : minutes; + for (const printer of this.pos.unwatched.printers) { + const changes = this._getPrintingCategoriesChanges( + printer.config.product_categories_ids, + orderChange + ); + if (changes["new"].length > 0 || changes["cancelled"].length > 0) { + const printingChanges = { + new: changes["new"], + cancelled: changes["cancelled"], + table_name: this.pos.config.is_table_management ? this.getTable().name : false, + floor_name: this.pos.config.is_table_management + ? this.getTable().floor.name + : false, + name: this.name || "unknown order", + time: { + hours, + minutes, + }, + }; + const receipt = renderToElement("OrderChangeReceipt", { changes: printingChanges }); + const result = await printer.printReceipt(receipt); + if (!result.successful) { + isPrintSuccessful = false; + } + } + } + + return isPrintSuccessful; + } + _getPrintingCategoriesChanges(categories) { + const currentOrderChange = this.changesToOrder; + return { + new: currentOrderChange["new"].filter((change) => + this.pos.db.is_product_in_category(categories, change["product_id"]) + ), + cancelled: currentOrderChange["cancelled"].filter((change) => + this.pos.db.is_product_in_category(categories, change["product_id"]) + ), + }; + } + /** + * This function is called after the order has been successfully sent to the preparation tool(s). + * In the future, this status should be separated between the different preparation tools, + * so that if one of them returns an error, it is possible to send the information back to it + * without impacting the other tools. + */ + updateLastOrderChange() { + const orderlineIdx = []; + this.orderlines.forEach((line) => { + if (!line.skipChange) { + const note = line.getNote(); + const lineKey = `${line.uuid} - ${note}`; + orderlineIdx.push(lineKey); + + if (this.lastOrderPrepaChange[lineKey]) { + this.lastOrderPrepaChange[lineKey]["quantity"] = line.get_quantity(); + } else { + this.lastOrderPrepaChange[lineKey] = { + line_uuid: line.uuid, + product_id: line.get_product().id, + name: line.get_full_product_name(), + note: note, + quantity: line.get_quantity(), + }; + } + line.setHasChange(false); + } + }); + + // Checks whether an orderline has been deleted from the order since it + // was last sent to the preparation tools. If so we delete it to the changes. + for (const lineKey in this.lastOrderPrepaChange) { + if (!this.getOrderedLine(lineKey)) { + delete this.lastOrderPrepaChange[lineKey]; + } + } + } + + /** + * @returns {{ [productKey: string]: { product_id: number, name: string, note: string, quantity: number } }} + * This function recalculates the information to be sent to the preparation tools, + * it uses the variable lastOrderPrepaChange which contains the last changes sent + * to perform this calculation. + */ + getOrderChanges() { + const prepaCategoryIds = this.pos.orderPreparationCategories; + const oldChanges = this.lastOrderPrepaChange; + const changes = {}; + + if (!prepaCategoryIds.size) { + return {}; + } + + // Compares the orderlines of the order with the last ones sent. + // When one of them has changed, we add the change. + for (const orderlineIdx in this.orderlines) { + const orderline = this.orderlines[orderlineIdx]; + + if (orderline.skipChange) { + continue; + } + + const product = orderline.get_product(); + const note = orderline.getNote(); + const productKey = `${product.id} - ${orderline.get_full_product_name()} - ${note}`; + const lineKey = `${orderline.uuid} - ${note}`; + + if (prepaCategoryIds.has(product.pos_categ_id[0])) { + const quantity = orderline.get_quantity(); + const quantityDiff = oldChanges[lineKey] + ? quantity - oldChanges[lineKey].quantity + : quantity; + + if (quantityDiff) { + changes[productKey] = { + name: orderline.get_full_product_name(), + product_id: product.id, + quantity: quantityDiff, + note: note, + }; + orderline.setHasChange(true); + } else { + orderline.setHasChange(false); + } + } else { + orderline.setHasChange(false); + } + } + + // Checks whether an orderline has been deleted from the order since it + // was last sent to the preparation tools. If so we add this to the changes. + for (const [lineKey, lineResume] of Object.entries(this.lastOrderPrepaChange)) { + if (!this.getOrderedLine(lineKey)) { + const productKey = `${lineResume["product_id"]} - ${lineResume["name"]} - ${lineResume["note"]}`; + if (!changes[productKey]) { + changes[productKey] = { + product_id: lineResume["product_id"], + name: lineResume["name"], + note: lineResume["note"], + quantity: -lineResume["quantity"], + }; + } else { + changes[productKey]["quantity"] -= lineResume["quantity"]; + } + } + } + + return changes; + } + // This function transforms the data generated by getOrderChanges into the old + // pattern used by the printer and the display preparation. This old pattern comes from + // the time when this logic was in pos_restaurant. + get changesToOrder() { + const toAdd = []; + const toRemove = []; + const changes = Object.values(this.getOrderChanges()); + + for (const lineChange of changes) { + if (lineChange["quantity"] > 0) { + toAdd.push(lineChange); + } else if (lineChange["quantity"] < 0) { + lineChange["quantity"] *= -1; // we change the sign because that's how it is + toRemove.push(lineChange); + } + } + + return { new: toAdd, cancelled: toRemove }; + } + getOrderedLine(lineKey) { + return this.orderlines.find( + (line) => + line.uuid === this.lastOrderPrepaChange[lineKey]["line_uuid"] && + line.note === this.lastOrderPrepaChange[lineKey]["note"] + ); + } + hasSkippedChanges() { + return this.orderlines.find((orderline) => orderline.skipChange) ? true : false; + } + hasChangesToPrint() { + return Object.keys(this.getOrderChanges()).length ? true : false; + } async pay() { if ( this.orderlines.some( diff --git a/addons/point_of_sale/static/src/scss/pos.scss b/addons/point_of_sale/static/src/scss/pos.scss index 4cf75ed1545..abe37ed5a7b 100644 --- a/addons/point_of_sale/static/src/scss/pos.scss +++ b/addons/point_of_sale/static/src/scss/pos.scss @@ -5,6 +5,18 @@ src: url(../fonts/Inconsolata.otf); } +/* ------ ORDER LINE STATUS ------- */ +.pos .order .orderline.has-change { + border-left: solid 6px #6EC89B; + color: #6EC89B; + padding-left: 9px; +} +.pos .order .orderline.skip-change { + border-left: solid 6px #7F82AC; + color: #7F82AC; + padding-left: 9px; +} + /* --- Styling of OpenERP Elements --- */ .ui-dialog, .modal-dialog { background: white; diff --git a/addons/pos_restaurant/static/src/xml/multiprint.xml b/addons/point_of_sale/static/src/xml/multiprint.xml similarity index 100% rename from addons/pos_restaurant/static/src/xml/multiprint.xml rename to addons/point_of_sale/static/src/xml/multiprint.xml diff --git a/addons/point_of_sale/static/tests/utils.js b/addons/point_of_sale/static/tests/utils.js index 6dc9443ca2c..6d7e7e17d5d 100644 --- a/addons/point_of_sale/static/tests/utils.js +++ b/addons/point_of_sale/static/tests/utils.js @@ -6,6 +6,7 @@ registry.category("mock_server").add("pos.session/load_pos_data", async function return { "res.company": { id: 1 }, "pos.session": { id: 1 }, + "pos.printer": [], "pos.config": { id: 1, uuid: "TEST-UUID", trusted_config_ids: [] }, "res.partner": [...(this.models["res.partner"]?.records || [])], "pos.category": [...(this.models["pos.category"]?.records || [])], diff --git a/addons/point_of_sale/views/pos_printer_view.xml b/addons/point_of_sale/views/pos_printer_view.xml new file mode 100644 index 00000000000..be6197fe814 --- /dev/null +++ b/addons/point_of_sale/views/pos_printer_view.xml @@ -0,0 +1,49 @@ + + + Preparation Printer + pos.printer + +
+ + + + + + + + +
+
+
+ + + Preparation Printers + pos.printer + tree,kanban,form + +

+ Add a new restaurant order printer +

+ Order Printers are used by restaurants and bars to print the + order updates in the kitchen/bar when the waiter updates the order. +

+ Each Order Printer has an IP Address that defines the IoT Box/Hardware + Proxy where the printer can be found, and a list of product categories. + An Order Printer will only print updates for products belonging to one of + its categories. +

+
+
+ + + Preparation Printers + pos.printer + + + + + + + + +
diff --git a/addons/point_of_sale/views/res_config_settings_views.xml b/addons/point_of_sale/views/res_config_settings_views.xml index 3a982f3d451..f71c0806b7d 100644 --- a/addons/point_of_sale/views/res_config_settings_views.xml +++ b/addons/point_of_sale/views/res_config_settings_views.xml @@ -333,6 +333,18 @@ + + +
+
+
+
+
+
+
diff --git a/addons/pos_epson_printer/__manifest__.py b/addons/pos_epson_printer/__manifest__.py index 65d2da36b3c..011dd89fed3 100644 --- a/addons/pos_epson_printer/__manifest__.py +++ b/addons/pos_epson_printer/__manifest__.py @@ -16,6 +16,7 @@ Use Epson ePOS Printers without the IoT Box in the Point of Sale 'data': [ 'views/pos_config_views.xml', 'views/res_config_settings_views.xml', + 'views/pos_printer_views.xml', ], 'installable': True, 'auto_install': True, diff --git a/addons/pos_epson_printer/models/__init__.py b/addons/pos_epson_printer/models/__init__.py index 2fd2bb5567d..9225067d5c2 100644 --- a/addons/pos_epson_printer/models/__init__.py +++ b/addons/pos_epson_printer/models/__init__.py @@ -3,3 +3,5 @@ from . import pos_config from . import res_config_settings +from . import pos_printer +from . import pos_session diff --git a/addons/pos_epson_printer/models/pos_printer.py b/addons/pos_epson_printer/models/pos_printer.py new file mode 100644 index 00000000000..a680830ec2d --- /dev/null +++ b/addons/pos_epson_printer/models/pos_printer.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models, api, _ +from odoo.exceptions import ValidationError + +class PosPrinter(models.Model): + + _inherit = 'pos.printer' + + printer_type = fields.Selection(selection_add=[('epson_epos', 'Use an Epson printer')]) + epson_printer_ip = fields.Char(string='Epson Printer IP Address', help="Local IP address of an Epson receipt printer.", default="0.0.0.0") + + @api.constrains('epson_printer_ip') + def _constrains_epson_printer_ip(self): + for record in self: + if record.printer_type == 'epson_epos' and not record.epson_printer_ip: + raise ValidationError(_("Epson Printer IP Address cannot be empty.")) diff --git a/addons/pos_epson_printer_restaurant/models/pos_session.py b/addons/pos_epson_printer/models/pos_session.py similarity index 71% rename from addons/pos_epson_printer_restaurant/models/pos_session.py rename to addons/pos_epson_printer/models/pos_session.py index f785a8bb823..d1cf061cbbb 100644 --- a/addons/pos_epson_printer_restaurant/models/pos_session.py +++ b/addons/pos_epson_printer/models/pos_session.py @@ -3,11 +3,10 @@ from odoo import models - class PosSession(models.Model): _inherit = 'pos.session' - def _loader_params_restaurant_printer(self): - result = super()._loader_params_restaurant_printer() + def _loader_params_pos_printer(self): + result = super()._loader_params_pos_printer() result['search_params']['fields'].append('epson_printer_ip') return result diff --git a/addons/pos_epson_printer/static/src/js/models.js b/addons/pos_epson_printer/static/src/js/models.js index 07f56871428..ca4c270a513 100644 --- a/addons/pos_epson_printer/static/src/js/models.js +++ b/addons/pos_epson_printer/static/src/js/models.js @@ -13,4 +13,11 @@ patch(PosGlobalState.prototype, "pos_epson_printer.PosGlobalState", { } }); }, + create_printer(config) { + if (config.printer_type === "epson_epos") { + return new EpsonPrinter({ ip: config.epson_printer_ip }); + } else { + return this._super(...arguments); + } + }, }); diff --git a/addons/pos_epson_printer_restaurant/views/pos_restaurant_views.xml b/addons/pos_epson_printer/views/pos_printer_views.xml similarity index 52% rename from addons/pos_epson_printer_restaurant/views/pos_restaurant_views.xml rename to addons/pos_epson_printer/views/pos_printer_views.xml index 8f95a3ee49c..8673fcb465f 100644 --- a/addons/pos_epson_printer_restaurant/views/pos_restaurant_views.xml +++ b/addons/pos_epson_printer/views/pos_printer_views.xml @@ -1,9 +1,9 @@ - - pos.restaurant.iot.config.form.view - restaurant.printer - + + pos.iot.config.form.view + pos.printer + diff --git a/addons/pos_epson_printer_restaurant/__init__.py b/addons/pos_epson_printer_restaurant/__init__.py deleted file mode 100644 index dc5e6b693d1..00000000000 --- a/addons/pos_epson_printer_restaurant/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from . import models diff --git a/addons/pos_epson_printer_restaurant/__manifest__.py b/addons/pos_epson_printer_restaurant/__manifest__.py deleted file mode 100644 index ed22a1e4bfc..00000000000 --- a/addons/pos_epson_printer_restaurant/__manifest__.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - - -{ - 'name': 'POS Epson Printer Restaurant', - 'version': '1.0', - 'category': 'Sales/Point of Sale', - 'sequence': 6, - 'summary': 'Epson Printers as Order Printers', - 'description': """ - -Use Epson Printers as Order Printers in the Point of Sale without the IoT Box -""", - 'depends': ['pos_epson_printer', 'pos_restaurant'], - 'data': [ - 'views/pos_restaurant_views.xml', - ], - 'installable': True, - 'auto_install': True, - 'assets': { - 'point_of_sale.assets': [ - 'pos_epson_printer_restaurant/static/**/*', - ], - }, - 'license': 'LGPL-3', -} diff --git a/addons/pos_epson_printer_restaurant/i18n/ar.po b/addons/pos_epson_printer_restaurant/i18n/ar.po deleted file mode 100644 index 32f13692105..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/ar.po +++ /dev/null @@ -1,45 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -# Translators: -# Ali Alrehawi , 2019 -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Last-Translator: Ali Alrehawi , 2019\n" -"Language-Team: Arabic (https://www.transifex.com/odoo/teams/41243/ar/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: ar\n" -"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "طابعة مطعم" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "" diff --git a/addons/pos_epson_printer_restaurant/i18n/cs.po b/addons/pos_epson_printer_restaurant/i18n/cs.po deleted file mode 100644 index 9e62a0b2832..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/cs.po +++ /dev/null @@ -1,45 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -# Translators: -# trendspotter , 2019 -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Last-Translator: trendspotter , 2019\n" -"Language-Team: Czech (https://www.transifex.com/odoo/teams/41243/cs/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: cs\n" -"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "Tiskárna restaurace" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "" diff --git a/addons/pos_epson_printer_restaurant/i18n/da.po b/addons/pos_epson_printer_restaurant/i18n/da.po deleted file mode 100644 index 31fe76fbb48..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/da.po +++ /dev/null @@ -1,41 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Language-Team: Danish (https://www.transifex.com/odoo/teams/41243/da/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: da\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "" diff --git a/addons/pos_epson_printer_restaurant/i18n/de.po b/addons/pos_epson_printer_restaurant/i18n/de.po deleted file mode 100644 index 12b31129366..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/de.po +++ /dev/null @@ -1,45 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -# Translators: -# Chris Egal , 2019 -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Last-Translator: Chris Egal , 2019\n" -"Language-Team: German (https://www.transifex.com/odoo/teams/41243/de/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: de\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "Restaurant-Drucker" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "" diff --git a/addons/pos_epson_printer_restaurant/i18n/es.po b/addons/pos_epson_printer_restaurant/i18n/es.po deleted file mode 100644 index 4cafa993542..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/es.po +++ /dev/null @@ -1,45 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -# Translators: -# Jon Perez , 2019 -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Last-Translator: Jon Perez , 2019\n" -"Language-Team: Spanish (https://www.transifex.com/odoo/teams/41243/es/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: es\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "Dirección IP de la impresora de recibos Epson" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "Dirección IP local de una impresora de recibos Epson." - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "Tipo de impresora" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "Impresora de restaurante" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "Use una impresora Epson" diff --git a/addons/pos_epson_printer_restaurant/i18n/fr.po b/addons/pos_epson_printer_restaurant/i18n/fr.po deleted file mode 100644 index f4ae0545948..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/fr.po +++ /dev/null @@ -1,46 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -# Translators: -# Nicolas Roussey , 2019 -# thomas quertinmont , 2019 -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Last-Translator: thomas quertinmont , 2019\n" -"Language-Team: French (https://www.transifex.com/odoo/teams/41243/fr/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: fr\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "Adresse IP de l'imprimante de reçus Epson" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "Adresse IP locale d'une imprimante de reçus Epson." - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "Type d'imprimante" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "Imprimante du restaurant" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "Utiliser une imprimante Epson" diff --git a/addons/pos_epson_printer_restaurant/i18n/he.po b/addons/pos_epson_printer_restaurant/i18n/he.po deleted file mode 100644 index 24403406097..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/he.po +++ /dev/null @@ -1,41 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Language-Team: Hebrew (https://www.transifex.com/odoo/teams/41243/he/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: he\n" -"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: (n % 10 == 0 && n % 1 == 0 && n > 10) ? 2 : 3;\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "" diff --git a/addons/pos_epson_printer_restaurant/i18n/hr.po b/addons/pos_epson_printer_restaurant/i18n/hr.po deleted file mode 100644 index b61502c5f83..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/hr.po +++ /dev/null @@ -1,41 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Language-Team: Croatian (https://www.transifex.com/odoo/teams/41243/hr/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: hr\n" -"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "" diff --git a/addons/pos_epson_printer_restaurant/i18n/hu.po b/addons/pos_epson_printer_restaurant/i18n/hu.po deleted file mode 100644 index f0832bcf9ce..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/hu.po +++ /dev/null @@ -1,41 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Language-Team: Hungarian (https://www.transifex.com/odoo/teams/41243/hu/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: hu\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "" diff --git a/addons/pos_epson_printer_restaurant/i18n/it.po b/addons/pos_epson_printer_restaurant/i18n/it.po deleted file mode 100644 index 46502fce1cb..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/it.po +++ /dev/null @@ -1,46 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -# Translators: -# Sergio Zanchetta , 2019 -# Luigia Cimmino Caserta , 2019 -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Last-Translator: Luigia Cimmino Caserta , 2019\n" -"Language-Team: Italian (https://www.transifex.com/odoo/teams/41243/it/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: it\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "Indirizzo IP stampante ricevute Epson" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "Indirizzo IP locale stampante ricevute Epson." - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "Tipo stampante" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "Stampante ristorante" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "Usa una stampante Epson" diff --git a/addons/pos_epson_printer_restaurant/i18n/lb.po b/addons/pos_epson_printer_restaurant/i18n/lb.po deleted file mode 100644 index 38c4abd74af..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/lb.po +++ /dev/null @@ -1,41 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Language-Team: Luxembourgish (https://www.transifex.com/odoo/teams/41243/lb/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: lb\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "" diff --git a/addons/pos_epson_printer_restaurant/i18n/lt.po b/addons/pos_epson_printer_restaurant/i18n/lt.po deleted file mode 100644 index 23bb806570a..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/lt.po +++ /dev/null @@ -1,45 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -# Translators: -# Linas Versada , 2019 -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Last-Translator: Linas Versada , 2019\n" -"Language-Team: Lithuanian (https://www.transifex.com/odoo/teams/41243/lt/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: lt\n" -"Plural-Forms: nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "Restorano spausdintuvas" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "" diff --git a/addons/pos_epson_printer_restaurant/i18n/mn.po b/addons/pos_epson_printer_restaurant/i18n/mn.po deleted file mode 100644 index 042eabc55e9..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/mn.po +++ /dev/null @@ -1,41 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Language-Team: Mongolian (https://www.transifex.com/odoo/teams/41243/mn/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: mn\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "" diff --git a/addons/pos_epson_printer_restaurant/i18n/nb.po b/addons/pos_epson_printer_restaurant/i18n/nb.po deleted file mode 100644 index b8f8c4d6cea..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/nb.po +++ /dev/null @@ -1,41 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Language-Team: Norwegian Bokmål (https://www.transifex.com/odoo/teams/41243/nb/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: nb\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "" diff --git a/addons/pos_epson_printer_restaurant/i18n/nl.po b/addons/pos_epson_printer_restaurant/i18n/nl.po deleted file mode 100644 index 207039ddfd8..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/nl.po +++ /dev/null @@ -1,46 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -# Translators: -# Cas Vissers , 2019 -# Yenthe Van Ginneken , 2019 -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Last-Translator: Yenthe Van Ginneken , 2019\n" -"Language-Team: Dutch (https://www.transifex.com/odoo/teams/41243/nl/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: nl\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "Lokaal IP adres van een Epson ticket printer." - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "Soort printer" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "Restaurant printer" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "Gebruik een Epson printe" diff --git a/addons/pos_epson_printer_restaurant/i18n/pl.po b/addons/pos_epson_printer_restaurant/i18n/pl.po deleted file mode 100644 index 4a98b70b140..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/pl.po +++ /dev/null @@ -1,41 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Language-Team: Polish (https://www.transifex.com/odoo/teams/41243/pl/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: pl\n" -"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "" diff --git a/addons/pos_epson_printer_restaurant/i18n/pos_epson_printer_restaurant.pot b/addons/pos_epson_printer_restaurant/i18n/pos_epson_printer_restaurant.pot deleted file mode 100644 index b9137dc4efa..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/pos_epson_printer_restaurant.pot +++ /dev/null @@ -1,46 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 15.5alpha1\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-20 09:01+0000\n" -"PO-Revision-Date: 2022-09-20 09:01+0000\n" -"Last-Translator: \n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Plural-Forms: \n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Printer IP Address" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_pos_session -msgid "Point of Sale Session" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "" diff --git a/addons/pos_epson_printer_restaurant/i18n/pt.po b/addons/pos_epson_printer_restaurant/i18n/pt.po deleted file mode 100644 index 2fc81ff95fa..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/pt.po +++ /dev/null @@ -1,41 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Language-Team: Portuguese (https://www.transifex.com/odoo/teams/41243/pt/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: pt\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "" diff --git a/addons/pos_epson_printer_restaurant/i18n/pt_BR.po b/addons/pos_epson_printer_restaurant/i18n/pt_BR.po deleted file mode 100644 index 42a00408a8f..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/pt_BR.po +++ /dev/null @@ -1,41 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Language-Team: Portuguese (Brazil) (https://www.transifex.com/odoo/teams/41243/pt_BR/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: pt_BR\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "" diff --git a/addons/pos_epson_printer_restaurant/i18n/ro.po b/addons/pos_epson_printer_restaurant/i18n/ro.po deleted file mode 100644 index b730885758b..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/ro.po +++ /dev/null @@ -1,41 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Language-Team: Romanian (https://www.transifex.com/odoo/teams/41243/ro/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: ro\n" -"Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "" diff --git a/addons/pos_epson_printer_restaurant/i18n/ru.po b/addons/pos_epson_printer_restaurant/i18n/ru.po deleted file mode 100644 index c9fa3fb527f..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/ru.po +++ /dev/null @@ -1,41 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Language-Team: Russian (https://www.transifex.com/odoo/teams/41243/ru/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: ru\n" -"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "" diff --git a/addons/pos_epson_printer_restaurant/i18n/tr.po b/addons/pos_epson_printer_restaurant/i18n/tr.po deleted file mode 100644 index e8eb9dd32ec..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/tr.po +++ /dev/null @@ -1,41 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Language-Team: Turkish (https://www.transifex.com/odoo/teams/41243/tr/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: tr\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "" diff --git a/addons/pos_epson_printer_restaurant/i18n/uk.po b/addons/pos_epson_printer_restaurant/i18n/uk.po deleted file mode 100644 index d5de0cf6d47..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/uk.po +++ /dev/null @@ -1,45 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -# Translators: -# Alina Lisnenko , 2019 -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Last-Translator: Alina Lisnenko , 2019\n" -"Language-Team: Ukrainian (https://www.transifex.com/odoo/teams/41243/uk/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: uk\n" -"Plural-Forms: nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "IP-адреса принтера чеків Epson" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "Локальна IP-адреса принтера чеків Epson." - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "Тип принтера" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "Ресторанний принтер" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "Використовуйте принтер Epson" diff --git a/addons/pos_epson_printer_restaurant/i18n/vi.po b/addons/pos_epson_printer_restaurant/i18n/vi.po deleted file mode 100644 index da512df4412..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/vi.po +++ /dev/null @@ -1,41 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Language-Team: Vietnamese (https://www.transifex.com/odoo/teams/41243/vi/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: vi\n" -"Plural-Forms: nplurals=1; plural=0;\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "" diff --git a/addons/pos_epson_printer_restaurant/i18n/zh_CN.po b/addons/pos_epson_printer_restaurant/i18n/zh_CN.po deleted file mode 100644 index ea9cf036bec..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/zh_CN.po +++ /dev/null @@ -1,46 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -# Translators: -# keecome <7017511@qq.com>, 2019 -# Felix Yuen , 2019 -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Last-Translator: Felix Yuen , 2019\n" -"Language-Team: Chinese (China) (https://www.transifex.com/odoo/teams/41243/zh_CN/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: zh_CN\n" -"Plural-Forms: nplurals=1; plural=0;\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "Epson收据打印机IP地址" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "Epson收据打印机的本地IP地址。" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "打印机类型" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "餐厅打印机" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "使用Epson打印机" diff --git a/addons/pos_epson_printer_restaurant/i18n/zh_TW.po b/addons/pos_epson_printer_restaurant/i18n/zh_TW.po deleted file mode 100644 index c43a9245bb7..00000000000 --- a/addons/pos_epson_printer_restaurant/i18n/zh_TW.po +++ /dev/null @@ -1,45 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * pos_epson_printer_restaurant -# -# Translators: -# 敬雲 林 , 2019 -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server saas~12.5\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-08-26 08:15+0000\n" -"PO-Revision-Date: 2019-08-26 09:13+0000\n" -"Last-Translator: 敬雲 林 , 2019\n" -"Language-Team: Chinese (Taiwan) (https://www.transifex.com/odoo/teams/41243/zh_TW/)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: zh_TW\n" -"Plural-Forms: nplurals=1; plural=0;\n" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Epson Receipt Printer IP Address" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,help:pos_epson_printer_restaurant.field_restaurant_printer__epson_printer_ip -msgid "Local IP address of an Epson receipt printer." -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields,field_description:pos_epson_printer_restaurant.field_restaurant_printer__printer_type -msgid "Printer Type" -msgstr "" - -#. module: pos_epson_printer_restaurant -#: model:ir.model,name:pos_epson_printer_restaurant.model_restaurant_printer -msgid "Restaurant Printer" -msgstr "餐廳列印機" - -#. module: pos_epson_printer_restaurant -#: model:ir.model.fields.selection,name:pos_epson_printer_restaurant.selection__restaurant_printer__printer_type__epson_epos -msgid "Use an Epson printer" -msgstr "" diff --git a/addons/pos_epson_printer_restaurant/models/__init__.py b/addons/pos_epson_printer_restaurant/models/__init__.py deleted file mode 100644 index 0007f7fb980..00000000000 --- a/addons/pos_epson_printer_restaurant/models/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from . import pos_restaurant -from . import pos_session diff --git a/addons/pos_epson_printer_restaurant/models/pos_restaurant.py b/addons/pos_epson_printer_restaurant/models/pos_restaurant.py deleted file mode 100644 index 37138f346f9..00000000000 --- a/addons/pos_epson_printer_restaurant/models/pos_restaurant.py +++ /dev/null @@ -1,11 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from odoo import fields, models - -class RestaurantPrinter(models.Model): - - _inherit = 'restaurant.printer' - - printer_type = fields.Selection(selection_add=[('epson_epos', 'Use an Epson printer')]) - epson_printer_ip = fields.Char(string='Epson Printer IP Address', help="Local IP address of an Epson receipt printer.") diff --git a/addons/pos_epson_printer_restaurant/static/src/js/models.js b/addons/pos_epson_printer_restaurant/static/src/js/models.js deleted file mode 100644 index 9a1c8b2dccd..00000000000 --- a/addons/pos_epson_printer_restaurant/static/src/js/models.js +++ /dev/null @@ -1,20 +0,0 @@ -/** @odoo-module */ - -import { PosGlobalState } from "@point_of_sale/js/models"; -import { EpsonPrinter } from "@pos_epson_printer/js/epson_printer"; -import { patch } from "@web/core/utils/patch"; - -// The override of create_printer needs to happen after its declaration in -// pos_restaurant. We need to make sure that this code is executed after the -// models file in pos_restaurant. -import "@pos_restaurant/js/models"; - -patch(PosGlobalState.prototype, "pos_epson_printer_restaurant.PosGlobalState", { - create_printer(config) { - if (config.printer_type === "epson_epos") { - return new EpsonPrinter({ ip: config.epson_printer_ip }); - } else { - return this._super(...arguments); - } - }, -}); diff --git a/addons/pos_hr_restaurant/models/pos_order.py b/addons/pos_hr_restaurant/models/pos_order.py index d59391dad0a..f6ed5afa9b1 100644 --- a/addons/pos_hr_restaurant/models/pos_order.py +++ b/addons/pos_hr_restaurant/models/pos_order.py @@ -7,11 +7,6 @@ from odoo import models, api class PosOrder(models.Model): _inherit = "pos.order" - def _get_fields_for_draft_order(self): - fields = super()._get_fields_for_draft_order() - fields.append('employee_id') - return fields - @api.model def get_table_draft_orders(self, table_ids): table_orders = super().get_table_draft_orders(table_ids) diff --git a/addons/pos_restaurant/data/pos_restaurant_demo.xml b/addons/pos_restaurant/data/pos_restaurant_demo.xml index a4baa475a8e..07b35a65e40 100644 --- a/addons/pos_restaurant/data/pos_restaurant_demo.xml +++ b/addons/pos_restaurant/data/pos_restaurant_demo.xml @@ -3,14 +3,6 @@ - - - - Kitchen Printer - localhost - - - Drinks diff --git a/addons/pos_restaurant/models/pos_config.py b/addons/pos_restaurant/models/pos_config.py index f3a408dc758..e097b46f99e 100644 --- a/addons/pos_restaurant/models/pos_config.py +++ b/addons/pos_restaurant/models/pos_config.py @@ -9,20 +9,12 @@ class PosConfig(models.Model): iface_splitbill = fields.Boolean(string='Bill Splitting', help='Enables Bill Splitting in the Point of Sale.') iface_printbill = fields.Boolean(string='Bill Printing', help='Allows to print the Bill before payment.') - iface_orderline_notes = fields.Boolean(string='Kitchen Notes', help='Allow custom kitchen notes on Orderlines.', default=True) + iface_orderline_notes = fields.Boolean(string='Internal Notes', help='Allow custom Internal notes on Orderlines.', default=True) floor_ids = fields.Many2many('restaurant.floor', string='Restaurant Floors', help='The restaurant floors served by this point of sale.') - printer_ids = fields.Many2many('restaurant.printer', 'pos_config_printer_rel', 'config_id', 'printer_id', string='Order Printers') is_table_management = fields.Boolean('Floors & Tables') - is_order_printer = fields.Boolean('Order Printer') set_tip_after_payment = fields.Boolean('Set Tip After Payment', help="Adjust the amount authorized by payment terminals to add a tip after the customers left or at the end of the day.") module_pos_restaurant = fields.Boolean(default=True) - def _force_http(self): - enforce_https = self.env['ir.config_parameter'].sudo().get_param('point_of_sale.enforce_https') - if not enforce_https and self.printer_ids.filtered(lambda pt: pt.printer_type == 'epson_epos'): - return True - return super(PosConfig, self)._force_http() - def get_tables_order_count(self): """ """ self.ensure_one() @@ -46,8 +38,6 @@ class PosConfig(models.Model): def write(self, vals): if ('is_table_management' in vals and vals['is_table_management'] == False): vals['floor_ids'] = [(5, 0, 0)] - if ('is_order_printer' in vals and vals['is_order_printer'] == False): - vals['printer_ids'] = [(5, 0, 0)] return super(PosConfig, self).write(vals) @api.model diff --git a/addons/pos_restaurant/models/pos_order.py b/addons/pos_restaurant/models/pos_order.py index 1c51e9724fd..dc213a4edf3 100644 --- a/addons/pos_restaurant/models/pos_order.py +++ b/addons/pos_restaurant/models/pos_order.py @@ -12,9 +12,7 @@ from odoo import api, fields, models class PosOrderLine(models.Model): _inherit = 'pos.order.line' - note = fields.Char('Kitchen Note added by the waiter.') - uuid = fields.Char(string='Uuid', readonly=True, copy=False) - mp_skip = fields.Boolean('Skip line when sending ticket to kitchen printers.') + note = fields.Char('Internal Note added by the waiter.') class PosOrder(models.Model): @@ -22,14 +20,11 @@ class PosOrder(models.Model): table_id = fields.Many2one('restaurant.table', string='Table', help='The table where this order was served', index='btree_not_null', readonly=True) customer_count = fields.Integer(string='Guests', help='The amount of customers that have been served by this order.', readonly=True) - multiprint_resume = fields.Char(string='Multiprint Resume', help="Last printed state of the order") def _get_fields_for_order_line(self): fields = super(PosOrder, self)._get_fields_for_order_line() fields.extend([ 'note', - 'uuid', - 'mp_skip', 'full_product_name', 'customer_note', 'price_extra', @@ -42,7 +37,6 @@ class PosOrder(models.Model): fields.extend([ 'table_id', 'customer_count', - 'multiprint_resume', ]) return fields @@ -126,7 +120,6 @@ class PosOrder(models.Model): order_fields = super(PosOrder, self)._order_fields(ui_order) order_fields['table_id'] = ui_order.get('table_id', False) order_fields['customer_count'] = ui_order.get('customer_count', 0) - order_fields['multiprint_resume'] = ui_order.get('multiprint_resume', False) return order_fields def _export_for_ui(self, order): diff --git a/addons/pos_restaurant/models/pos_restaurant.py b/addons/pos_restaurant/models/pos_restaurant.py index e566982cf22..53573f14ac6 100644 --- a/addons/pos_restaurant/models/pos_restaurant.py +++ b/addons/pos_restaurant/models/pos_restaurant.py @@ -118,15 +118,3 @@ class RestaurantTable(models.Model): error_msg = _("You cannot remove a table that is used in a PoS session, close the session(s) first.") if confs: raise UserError(error_msg) - - -class RestaurantPrinter(models.Model): - - _name = 'restaurant.printer' - _description = 'Restaurant Printer' - - name = fields.Char('Printer Name', required=True, default='Printer', help='An internal identification of the printer') - printer_type = fields.Selection(string='Printer Type', default='iot', - selection=[('iot', ' Use a printer connected to the IoT Box')]) - proxy_ip = fields.Char('Proxy IP Address', help="The IP Address or hostname of the Printer's hardware proxy") - product_categories_ids = fields.Many2many('pos.category', 'printer_category_rel', 'printer_id', 'category_id', string='Printed Product Categories') diff --git a/addons/pos_restaurant/models/pos_session.py b/addons/pos_restaurant/models/pos_session.py index c0b0a73c9ba..e771485a13b 100644 --- a/addons/pos_restaurant/models/pos_session.py +++ b/addons/pos_restaurant/models/pos_session.py @@ -10,10 +10,8 @@ class PosSession(models.Model): def _pos_ui_models_to_load(self): result = super()._pos_ui_models_to_load() - if self.config_id.module_pos_restaurant: - result.append('restaurant.printer') - if self.config_id.is_table_management: - result.append('restaurant.floor') + if self.config_id.module_pos_restaurant and self.config_id.is_table_management: + result.append('restaurant.floor') return result def _loader_params_restaurant_floor(self): @@ -52,15 +50,5 @@ class PosSession(models.Model): return floors - def _loader_params_restaurant_printer(self): - return { - 'search_params': { - 'domain': [('id', 'in', self.config_id.printer_ids.ids)], - 'fields': ['name', 'proxy_ip', 'product_categories_ids', 'printer_type'], - }, - } - def _get_pos_ui_restaurant_printer(self, params): - return self.env['restaurant.printer'].search_read(**params['search_params']) - def get_pos_ui_restaurant_floor(self): return self._get_pos_ui_restaurant_floor(self._loader_params_restaurant_floor()) diff --git a/addons/pos_restaurant/models/res_config_settings.py b/addons/pos_restaurant/models/res_config_settings.py index c68db279d8c..c22f10bf9e1 100644 --- a/addons/pos_restaurant/models/res_config_settings.py +++ b/addons/pos_restaurant/models/res_config_settings.py @@ -10,9 +10,7 @@ class ResConfigSettings(models.TransientModel): pos_iface_orderline_notes = fields.Boolean(compute='_compute_pos_module_pos_restaurant', store=True, readonly=False) pos_iface_printbill = fields.Boolean(compute='_compute_pos_module_pos_restaurant', store=True, readonly=False) pos_iface_splitbill = fields.Boolean(compute='_compute_pos_module_pos_restaurant', store=True, readonly=False) - pos_is_order_printer = fields.Boolean(compute='_compute_pos_module_pos_restaurant', store=True, readonly=False) pos_is_table_management = fields.Boolean(compute='_compute_pos_module_pos_restaurant', store=True, readonly=False) - pos_printer_ids = fields.Many2many(related='pos_config_id.printer_ids', readonly=False) pos_set_tip_after_payment = fields.Boolean(compute='_compute_pos_set_tip_after_payment', store=True, readonly=False) @api.depends('pos_module_pos_restaurant', 'pos_config_id') @@ -23,7 +21,6 @@ class ResConfigSettings(models.TransientModel): 'pos_iface_orderline_notes': False, 'pos_iface_printbill': False, 'pos_iface_splitbill': False, - 'pos_is_order_printer': False, 'pos_is_table_management': False, }) else: @@ -31,7 +28,6 @@ class ResConfigSettings(models.TransientModel): 'pos_iface_orderline_notes': res_config.pos_config_id.iface_orderline_notes, 'pos_iface_printbill': res_config.pos_config_id.iface_printbill, 'pos_iface_splitbill': res_config.pos_config_id.iface_splitbill, - 'pos_is_order_printer': res_config.pos_config_id.is_order_printer, 'pos_is_table_management': res_config.pos_config_id.is_table_management, }) diff --git a/addons/pos_restaurant/security/ir.model.access.csv b/addons/pos_restaurant/security/ir.model.access.csv index 57a39f69552..37a0c39164a 100644 --- a/addons/pos_restaurant/security/ir.model.access.csv +++ b/addons/pos_restaurant/security/ir.model.access.csv @@ -1,6 +1,4 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_restaurant_printer,restaurant.printer.user,model_restaurant_printer,point_of_sale.group_pos_user,1,0,0,0 -access_restaurant_printer_manager,restaurant.printer.manager,model_restaurant_printer,point_of_sale.group_pos_manager,1,1,1,1 access_restaurant_floor,restaurant.floor.user,model_restaurant_floor,point_of_sale.group_pos_user,1,0,0,0 access_restaurant_floor_manager,restaurant.floor.manager,model_restaurant_floor,point_of_sale.group_pos_manager,1,1,1,1 access_restaurant_table,restaurant.table.user,model_restaurant_table,point_of_sale.group_pos_user,1,0,0,0 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 4d15f3aa75a..9d3f0298ff2 100644 --- a/addons/pos_restaurant/static/src/app/floor_screen/table.js +++ b/addons/pos_restaurant/static/src/app/floor_screen/table.js @@ -55,7 +55,6 @@ export class Table extends Component { font-size: ${table.height >= 150 && table.width >= 150 ? 32 : 16}px; `; } - } get fill() { const customerCount = this.env.pos.getCustomerCount(this.props.table.id); @@ -71,7 +70,7 @@ export class Table extends Component { } get orderCountClass() { const countClass = { "order-count": true }; - if (this.env.pos.config.iface_printers) { + if (this.env.pos.orderPreparationCategories.size) { const notifications = this._getNotifications(); countClass["notify-printing"] = notifications.printing; countClass["notify-skipped"] = notifications.skipped; diff --git a/addons/pos_restaurant/static/src/app/pos_store.js b/addons/pos_restaurant/static/src/app/pos_store.js index 68eb778af4f..4535485e09b 100644 --- a/addons/pos_restaurant/static/src/app/pos_store.js +++ b/addons/pos_restaurant/static/src/app/pos_store.js @@ -17,9 +17,6 @@ const NON_IDLE_EVENTS = [ ]; let IDLE_TIMER_SETTER; -/** - * Go back to the floor screen if the user has been idle for a while. - */ patch(PosStore.prototype, "pos_restaurant.PosStore", { /** * @override diff --git a/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ActionpadWidget.js b/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ActionpadWidget.js index 3b5e4e165d3..9604aad61fa 100644 --- a/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ActionpadWidget.js +++ b/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ActionpadWidget.js @@ -11,7 +11,7 @@ patch(ActionpadWidget.prototype, "point_of_sale.ActionpadWidget", { return ( this.props.actionName === "Payment" && this.pos.globalState.config.module_pos_restaurant && - this.pos.globalState.printers_category_ids_set.size + this.pos.globalState.orderPreparationCategories.size ); }, get currentOrder() { @@ -32,7 +32,7 @@ patch(ActionpadWidget.prototype, "point_of_sale.ActionpadWidget", { if (!this.clicked) { this.clicked = true; try { - this.currentOrder.submitOrder(); + await this.pos.sendOrderInPreparation(this.currentOrder); } finally { this.clicked = false; } @@ -50,15 +50,18 @@ patch(ActionpadWidget.prototype, "point_of_sale.ActionpadWidget", { get highlightPay() { return ( this._super(...arguments) && - this.pos.globalState.printers_category_ids_set.size && + this.pos.globalState.orderPreparationCategories.size && !this.currentOrder.hasChangesToPrint() && this.hasQuantity(this.currentOrder) ); }, get categoryCount() { const categories = {}; - for (const orderline of this.currentOrder.printingChanges.new) { - const category = this.pos.globalState.db.get_product_by_id(orderline.product_id).pos_categ_id[1]; + const orderChange = this.currentOrder.getOrderChanges(); + for (const idx in orderChange) { + const orderline = orderChange[idx]; + const category = this.pos.globalState.db.get_product_by_id(orderline.product_id) + .pos_categ_id[1]; const numProd = orderline.quantity; categories[category] = categories[category] ? categories[category] + numProd : numProd; } diff --git a/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/OrderlineNoteButton.js b/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/OrderlineNoteButton.js index 2691b1d64e0..0409f576dfe 100644 --- a/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/OrderlineNoteButton.js +++ b/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/OrderlineNoteButton.js @@ -21,12 +21,12 @@ export class OrderlineNoteButton extends Component { } const { confirmed, payload: inputNote } = await this.popup.add(TextAreaPopup, { - startingValue: this.selectedOrderline.get_note(), - title: this.env._t("Add kitchen Note"), + startingValue: this.selectedOrderline.getNote(), + title: this.env._t("Add internal Note"), }); if (confirmed) { - this.selectedOrderline.set_note(inputNote); + this.selectedOrderline.setNote(inputNote); } } } diff --git a/addons/pos_restaurant/static/src/js/Screens/ProductScreen/Orderline.js b/addons/pos_restaurant/static/src/js/Screens/ProductScreen/Orderline.js deleted file mode 100644 index 9c99fd3c897..00000000000 --- a/addons/pos_restaurant/static/src/js/Screens/ProductScreen/Orderline.js +++ /dev/null @@ -1,39 +0,0 @@ -/** @odoo-module */ - -import { Orderline } from "@point_of_sale/js/Screens/ProductScreen/Orderline"; -import { patch } from "@web/core/utils/patch"; - -patch(Orderline.prototype, "pos_restaurant.Orderline", { - /** - * @override - */ - get addedClasses() { - const res = this._super(...arguments); - Object.assign(res, { - dirty: this.props.line.mp_dirty, - skip: this.props.line.mp_skip, - }); - return res; - }, - /** - * @override - * if doubleclick, change mp_dirty to mp_skip - * - * IMPROVEMENT: Instead of handling both double click and click in single - * method, perhaps we can separate double click from single click. - */ - selectLine() { - const line = this.props.line; // the orderline - if (this.env.pos.get_order().selected_orderline.id !== line.id) { - this.mp_dbclk_time = new Date().getTime(); - } else if (!this.mp_dbclk_time) { - this.mp_dbclk_time = new Date().getTime(); - } else if (this.mp_dbclk_time + 500 > new Date().getTime()) { - line.set_skip(!line.mp_skip); - this.mp_dbclk_time = 0; - } else { - this.mp_dbclk_time = new Date().getTime(); - } - this._super(...arguments); - }, -}); diff --git a/addons/pos_restaurant/static/src/js/Screens/SplitBillScreen/SplitBillScreen.js b/addons/pos_restaurant/static/src/js/Screens/SplitBillScreen/SplitBillScreen.js index 750e6bd63ba..41997eb4592 100644 --- a/addons/pos_restaurant/static/src/js/Screens/SplitBillScreen/SplitBillScreen.js +++ b/addons/pos_restaurant/static/src/js/Screens/SplitBillScreen/SplitBillScreen.js @@ -65,9 +65,9 @@ export class SplitBillScreen extends Component { // order and for the new one. This is not entirely correct // but avoids flooding the kitchen with unnecessary orders. // Not sure what to do in this case. - if (this.env.pos.isInterfacePrinter()) { - this.currentOrder.updatePrintedResume(); - this.newOrder.updatePrintedResume(); + if (this.env.pos.orderPreparationCategories.size) { + this.currentOrder.updateLastOrderChange(); + this.newOrder.updateLastOrderChange(); } this.newOrder.setCustomerCount(1); diff --git a/addons/pos_restaurant/static/src/js/models.js b/addons/pos_restaurant/static/src/js/models.js index 5a1f01c0ddb..ce66020f6d8 100644 --- a/addons/pos_restaurant/static/src/js/models.js +++ b/addons/pos_restaurant/static/src/js/models.js @@ -1,19 +1,13 @@ /** @odoo-module */ import { PosGlobalState, Order, Orderline, Payment } from "@point_of_sale/js/models"; -import { uuidv4, batched, deduceUrl } from "@point_of_sale/js/utils"; -import { HWPrinter } from "@point_of_sale/app/printer/hw_printer"; import { patch } from "@web/core/utils/patch"; -import { ErrorPopup } from "@point_of_sale/js/Popups/ErrorPopup"; -import { _t } from "@web/core/l10n/translation"; -import { renderToElement } from "@web/core/utils/render"; patch(PosGlobalState.prototype, "pos_restaurant.PosGlobalState", { setup() { this._super(...arguments); this.orderToTransfer = null; // table transfer feature this.transferredOrdersSet = new Set(); // used to know which orders has been transferred but not sent to the back end yet - this.printers_category_ids_set = new Set(); this.floorPlanStyle = "default"; this.isEditMode = false; }, @@ -24,9 +18,6 @@ patch(PosGlobalState.prototype, "pos_restaurant.PosGlobalState", { this.floors = loadedData["restaurant.floor"]; this.loadRestaurantFloor(); } - if (this.config.module_pos_restaurant) { - this._loadRestaurantPrinter(loadedData["restaurant.printer"]); - } }, //@override async after_load_server_data() { @@ -44,38 +35,11 @@ patch(PosGlobalState.prototype, "pos_restaurant.PosGlobalState", { this._super(...arguments); } }, - isInterfacePrinter() { - return this.config.iface_printers; - }, - addSubmitOrderButton() { - return this.config.module_pos_restaurant && this.unwatched.printers.length; - }, //@override - createReactiveOrder(json) { - let reactiveOrder = this._super(...arguments); - if (this.isInterfacePrinter()) { - const updateOrderChanges = () => { - if (reactiveOrder.get_screen_data().name === "ProductScreen") { - reactiveOrder.updateChangesToPrint(); - } - }; - reactiveOrder = owl.reactive(reactiveOrder, batched(updateOrderChanges)); - reactiveOrder.updateChangesToPrint(); - } - return reactiveOrder; - }, - _loadRestaurantPrinter(printers) { - this.unwatched.printers = []; - // list of product categories that belong to one or more order printer - for (const printerConfig of printers) { - const printer = this.create_printer(printerConfig); - printer.config = printerConfig; - this.unwatched.printers.push(printer); - for (const id of printer.config.product_categories_ids) { - this.printers_category_ids_set.add(id); - } - } - this.config.iface_printers = !!this.unwatched.printers.length; + add_new_order() { + const order = this._super(...arguments); + this.ordersToUpdateSet.add(order); + return order; }, async _getTableOrdersFromServer(tableIds) { this.set_synch("connecting", 1); @@ -98,25 +62,12 @@ patch(PosGlobalState.prototype, "pos_restaurant.PosGlobalState", { * @param tableId ID of the table we want to sync */ async _syncTableOrdersToServer() { - await this._pushOrdersToServer(); + await this.sendDraftToServer(); await this._removeOrdersFromServer(); // This need to be called here otherwise _onReactiveOrderUpdated() will be called after the set is being cleared this.ordersToUpdateSet.clear(); this.transferredOrdersSet.clear(); }, - /** - * Send the orders to be saved to the back end - * @throw error - */ - async _pushOrdersToServer() { - const ordersUidsToSync = [...this.ordersToUpdateSet].map((order) => order.uid); - const ordersToSync = this.db.get_unpaid_orders_to_sync(ordersUidsToSync); - const ordersResponse = await this._save_to_server(ordersToSync, { draft: true }); - const tableOrders = [...this.ordersToUpdateSet].map((order) => order); - ordersResponse.forEach((orderResponseData) => - this._updateOrder(orderResponseData, tableOrders) - ); - }, /** * Replace all the orders of a table by orders fetched from the backend * @param tableId ID of the table @@ -230,10 +181,6 @@ patch(PosGlobalState.prototype, "pos_restaurant.PosGlobalState", { const tableOrders = this.getTableOrders(tableId).filter((order) => !order.finalized); return tableOrders.reduce((count, order) => count + order.getCustomerCount(), 0); }, - create_printer(config) { - const url = deduceUrl(config.proxy_ip || ""); - return new HWPrinter({ rpc: this.env.services.rpc, url }); - }, isOpenOrderShareable() { return this._super(...arguments) || this.config.is_table_management; }, @@ -257,16 +204,6 @@ patch(Order.prototype, "pos_restaurant.Order", { } this.customerCount = this.customerCount || 1; } - if (this.pos.isInterfacePrinter()) { - // printedResume will store the previous state of the orderlines (when there were no skip), it will - // store all the orderlines even if the product are not printable. This way, when we add a new category in - // the printers, the already added products of the newly added category are not printed. - this.printedResume = owl.markRaw(this.printedResume || {}); // we don't wanna track it and re-render - // no need to store this in the backend, we can just compute it once the order is fetched from clicking a table - if (!this.printingChanges) { - this._resetPrintingChanges(); - } - } }, //@override export_as_JSON() { @@ -277,11 +214,7 @@ patch(Order.prototype, "pos_restaurant.Order", { } json.customer_count = this.customerCount; } - if (this.pos.isInterfacePrinter()) { - json.multiprint_resume = JSON.stringify(this.printedResume); - // so that it can be stored in local storage and be used when loading the pos in the floorscreen - json.printing_changes = JSON.stringify(this.printingChanges); - } + return json; }, //@override @@ -294,24 +227,6 @@ patch(Order.prototype, "pos_restaurant.Order", { } this.customerCount = json.customer_count; } - if (this.pos.isInterfacePrinter()) { - this.printedResume = json.multiprint_resume && JSON.parse(json.multiprint_resume); - this.printingChanges = json.printing_changes && JSON.parse(json.printing_changes); - } - }, - async submitOrder() { - if (this.pos.unwatched.printers.length) { - if (this.hasChangesToPrint()) { - const isPrintSuccessful = await this.printChanges(); - if (!isPrintSuccessful) { - this.pos.env.services.popup.add(ErrorPopup, { - title: _t("Printing failed"), - body: _t("Failed in printing the changes in the order"), - }); - } - } - } - this.updatePrintedResume(); }, //@override export_for_printing() { @@ -324,79 +239,6 @@ patch(Order.prototype, "pos_restaurant.Order", { } return json; }, - _resetPrintingChanges() { - this.printingChanges = { new: [], cancelled: [] }; - }, - /** - * @returns {{ [productKey: string]: { product_id: number, name: string, note: string, quantity: number } }} - */ - _computePrintChanges() { - const changes = {}; - - // If there's a new orderline, we add it otherwise we add the change if there's one - this.orderlines.forEach((line) => { - if (!line.mp_skip) { - const productId = line.get_product().id; - const note = line.get_note(); - const productKey = `${productId} - ${line.get_full_product_name()} - ${note}`; - const lineKey = `${line.uuid} - ${note}`; - const quantityDiff = - line.get_quantity() - - (this.printedResume[lineKey] ? this.printedResume[lineKey]["quantity"] : 0); - if (quantityDiff) { - if (!changes[productKey]) { - changes[productKey] = { - product_id: productId, - name: line.get_full_product_name(), - note: note, - quantity: quantityDiff, - }; - } else { - changes[productKey]["quantity"] += quantityDiff; - } - line.set_dirty(true); - } else { - line.set_dirty(false); - } - } - }); - - // If there's an orderline that's not present anymore, we consider it as removed (even if note changed) - for (const [lineKey, lineResume] of Object.entries(this.printedResume)) { - if (!this._getPrintedLine(lineKey)) { - const productKey = `${lineResume["product_id"]} - ${lineResume["name"]} - ${lineResume["note"]}`; - if (!changes[productKey]) { - changes[productKey] = { - product_id: lineResume["product_id"], - name: lineResume["name"], - note: lineResume["note"], - quantity: -lineResume["quantity"], - }; - } else { - changes[productKey]["quantity"] -= lineResume["quantity"]; - } - } - } - - return changes; - }, - _getPrintingCategoriesChanges(categories) { - return { - new: this.printingChanges["new"].filter((change) => - this.pos.db.is_product_in_category(categories, change["product_id"]) - ), - cancelled: this.printingChanges["cancelled"].filter((change) => - this.pos.db.is_product_in_category(categories, change["product_id"]) - ), - }; - }, - _getPrintedLine(lineKey) { - return this.orderlines.find( - (line) => - line.uuid === this.printedResume[lineKey]["line_uuid"] && - line.note === this.printedResume[lineKey]["note"] - ); - }, getCustomerCount() { return this.customerCount; }, @@ -409,130 +251,12 @@ patch(Order.prototype, "pos_restaurant.Order", { } return null; }, - updatePrintedResume() { - // we first remove the removed orderlines - for (const lineKey in this.printedResume) { - if (!this._getPrintedLine(lineKey)) { - delete this.printedResume[lineKey]; - } - } - // we then update the added orderline or product quantity change - this.orderlines.forEach((line) => { - if (!line.mp_skip) { - const note = line.get_note(); - const lineKey = `${line.uuid} - ${note}`; - if (this.printedResume[lineKey]) { - this.printedResume[lineKey]["quantity"] = line.get_quantity(); - } else { - this.printedResume[lineKey] = { - line_uuid: line.uuid, - product_id: line.get_product().id, - name: line.get_full_product_name(), - note: note, - quantity: line.get_quantity(), - }; - } - line.set_dirty(false); - } - }); - this._resetPrintingChanges(); - }, - updateChangesToPrint() { - const changes = this._computePrintChanges(); // it's possible to have a change's quantity of 0 - // we thoroughly parse the changes we just computed to properly separate them into two - const toAdd = []; - const toRemove = []; - - for (const lineChange of Object.values(changes)) { - if (lineChange["quantity"] > 0) { - toAdd.push(lineChange); - } else if (lineChange["quantity"] < 0) { - lineChange["quantity"] *= -1; // we change the sign because that's how it is - toRemove.push(lineChange); - } - } - - this.printingChanges = { new: toAdd, cancelled: toRemove }; - }, - hasChangesToPrint() { - for (const printer of this.pos.unwatched.printers) { - const changes = this._getPrintingCategoriesChanges( - printer.config.product_categories_ids - ); - if (changes["new"].length > 0 || changes["cancelled"].length > 0) { - return true; - } - } - return false; - }, - hasSkippedChanges() { - var orderlines = this.get_orderlines(); - for (var i = 0; i < orderlines.length; i++) { - if (orderlines[i].mp_skip) { - return true; - } - } - return false; - }, - async printChanges() { - let isPrintSuccessful = true; - const d = new Date(); - let hours = "" + d.getHours(); - hours = hours.length < 2 ? "0" + hours : hours; - let minutes = "" + d.getMinutes(); - minutes = minutes.length < 2 ? "0" + minutes : minutes; - - for (const printer of this.pos.unwatched.printers) { - const changes = this._getPrintingCategoriesChanges( - printer.config.product_categories_ids - ); - if (changes["new"].length > 0 || changes["cancelled"].length > 0) { - const printingChanges = { - new: changes["new"], - cancelled: changes["cancelled"], - table_name: this.pos.config.is_table_management ? this.getTable().name : false, - floor_name: this.pos.config.is_table_management - ? this.getTable().floor.name - : false, - name: this.name || "unknown order", - time: { - hours, - minutes, - }, - }; - const receipt = renderToElement("OrderChangeReceipt", { changes: printingChanges }); - const result = await printer.printReceipt(receipt); - if (!result.successful) { - isPrintSuccessful = false; - } - } - } - return isPrintSuccessful; - }, }); patch(Orderline.prototype, "pos_restaurant.Orderline", { setup() { this._super(...arguments); this.note = this.note || ""; - if (this.pos.isInterfacePrinter()) { - this.uuid = this.uuid || uuidv4(); - // mp dirty is true if this orderline has changed since the last kitchen print - this.mp_dirty = false; - if (!this.mp_skip) { - // mp_skip is true if the cashier want this orderline - // not to be sent to the kitchen - this.mp_skip = false; - } - } - }, - //@override - can_be_merged_with(orderline) { - if (orderline.get_note() !== this.get_note()) { - return false; - } else { - return !this.mp_skip && !orderline.mp_skip && this._super(...arguments); - } }, //@override clone() { @@ -544,9 +268,8 @@ patch(Orderline.prototype, "pos_restaurant.Orderline", { export_as_JSON() { const json = this._super(...arguments); json.note = this.note; - if (this.pos.isInterfacePrinter()) { + if (this.pos.config.iface_printers) { json.uuid = this.uuid; - json.mp_skip = this.mp_skip; } return json; }, @@ -554,44 +277,17 @@ patch(Orderline.prototype, "pos_restaurant.Orderline", { init_from_JSON(json) { this._super(...arguments); this.note = json.note; - if (this.pos.isInterfacePrinter()) { + if (this.pos.config.iface_printers) { this.uuid = json.uuid; - this.mp_skip = json.mp_skip; - } - }, - set_note(note) { - this.note = note; - }, - get_note() { - return this.note; - }, - set_skip(skip) { - if (this.mp_dirty && skip && !this.mp_skip) { - this.mp_skip = true; - } - if (this.mp_skip && !skip) { - this.mp_skip = false; - } - }, - set_dirty(dirty) { - if (this.printable()) { - this.mp_dirty = dirty; } }, get_line_diff_hash() { - if (this.get_note()) { - return this.id + "|" + this.get_note(); + if (this.getNote()) { + return this.id + "|" + this.getNote(); } else { return "" + this.id; } }, - // can this orderline be potentially printed ? - printable() { - return this.pos.db.is_product_in_category( - this.pos.printers_category_ids_set, - this.get_product().id - ); - }, }); patch(Payment.prototype, "pos_restaurant.Payment", { diff --git a/addons/pos_restaurant/static/src/scss/restaurant.scss b/addons/pos_restaurant/static/src/scss/restaurant.scss index af648f3212f..44341ecb082 100644 --- a/addons/pos_restaurant/static/src/scss/restaurant.scss +++ b/addons/pos_restaurant/static/src/scss/restaurant.scss @@ -95,18 +95,6 @@ font-size: 24px; line-height: 42px; } -/* ------ ORDER LINE STATUS ------- */ - -.pos .order .orderline.dirty { - border-left: solid 6px #6EC89B; - color: #6EC89B; - padding-left: 9px; -} -.pos .order .orderline.skip { - border-left: solid 6px #7F82AC; - color: #7F82AC; - padding-left: 9px; -} /* ------ SPLIT BILL SCREEN ------- */ diff --git a/addons/pos_restaurant/static/src/xml/Screens/ProductScreen/ControlButtons/OrderlineNoteButton.xml b/addons/pos_restaurant/static/src/xml/Screens/ProductScreen/ControlButtons/OrderlineNoteButton.xml index 0e5a2c0bdca..0f4c6efb635 100644 --- a/addons/pos_restaurant/static/src/xml/Screens/ProductScreen/ControlButtons/OrderlineNoteButton.xml +++ b/addons/pos_restaurant/static/src/xml/Screens/ProductScreen/ControlButtons/OrderlineNoteButton.xml @@ -5,7 +5,7 @@
- Kitchen Note + Internal Note
diff --git a/addons/pos_restaurant/static/src/xml/Screens/ProductScreen/Orderline.xml b/addons/pos_restaurant/static/src/xml/Screens/ProductScreen/Orderline.xml index a5c96dedad9..f574b89460a 100644 --- a/addons/pos_restaurant/static/src/xml/Screens/ProductScreen/Orderline.xml +++ b/addons/pos_restaurant/static/src/xml/Screens/ProductScreen/Orderline.xml @@ -3,10 +3,10 @@ - +
  • - +
  • diff --git a/addons/pos_restaurant/static/tests/tours/helpers/ProductScreenTourMethods.js b/addons/pos_restaurant/static/tests/tours/helpers/ProductScreenTourMethods.js index 30b05b60c85..6ed5c411331 100644 --- a/addons/pos_restaurant/static/tests/tours/helpers/ProductScreenTourMethods.js +++ b/addons/pos_restaurant/static/tests/tours/helpers/ProductScreenTourMethods.js @@ -24,7 +24,7 @@ class DoExt extends Do { return [ { content: "click note button", - trigger: '.control-buttons .control-button span:contains("Kitchen Note")', + trigger: '.control-buttons .control-button span:contains("Internal Note")', }, ]; } diff --git a/addons/pos_restaurant/tests/test_frontend.py b/addons/pos_restaurant/tests/test_frontend.py index 1a0d5098cbc..a5b58352a02 100644 --- a/addons/pos_restaurant/tests/test_frontend.py +++ b/addons/pos_restaurant/tests/test_frontend.py @@ -15,10 +15,6 @@ class TestFrontend(odoo.tests.HttpCase): 'account_type': 'asset_receivable', 'reconcile': True}) - printer = self.env['restaurant.printer'].create({ - 'name': 'Kitchen Printer', - 'proxy_ip': 'localhost', - }) drinks_category = self.env['pos.category'].create({'name': 'Drinks'}) main_company = self.env.ref('base.main_company') @@ -43,7 +39,6 @@ class TestFrontend(odoo.tests.HttpCase): 'iface_splitbill': True, 'iface_printbill': True, 'iface_orderline_notes': True, - 'printer_ids': [(4, printer.id)], 'iface_start_categ_id': drinks_category.id, 'start_category': True, }) diff --git a/addons/pos_restaurant/views/pos_restaurant_views.xml b/addons/pos_restaurant/views/pos_restaurant_views.xml index 1f994e7f700..3c0c769a5b2 100644 --- a/addons/pos_restaurant/views/pos_restaurant_views.xml +++ b/addons/pos_restaurant/views/pos_restaurant_views.xml @@ -111,61 +111,4 @@ action="action_restaurant_floor_form" sequence="10" groups="base.group_no_one"/> - - - - - Order Printer - restaurant.printer - -
    - - - - - - - - -
    -
    -
    - - - Order Printers - restaurant.printer - tree,kanban,form - -

    - Add a new restaurant order printer -

    - Order Printers are used by restaurants and bars to print the - order updates in the kitchen/bar when the waiter updates the order. -

    - Each Order Printer has an IP Address that defines the IoT Box/Hardware - Proxy where the printer can be found, and a list of product categories. - An Order Printer will only print updates for products belonging to one of - its categories. -

    -
    -
    - - - Order Printers - restaurant.printer - - - - - - - - - - -
    diff --git a/addons/pos_restaurant/views/res_config_settings_views.xml b/addons/pos_restaurant/views/res_config_settings_views.xml index 0185259077e..28a6d767cc9 100644 --- a/addons/pos_restaurant/views/res_config_settings_views.xml +++ b/addons/pos_restaurant/views/res_config_settings_views.xml @@ -20,7 +20,7 @@ - + @@ -29,18 +29,6 @@ - - -
    -
    -
    -
    -
    -
    -