[IMP] point_of_sale,*: move kitchen printer logic to point_of_sale
*:pos_epson_printer,pos_epson_printer_restaurant,point_of_sale, pos_restaurant,pos_hr_restaurant Before the printers only worked in the pos_restaurant and not in the point_of_sale. Indeed, the methods managing the printers were located in the pos_restaurant. Now all these methods have been moved. For the community part here are the affected modules: - The methods in pos_epson_printer_restaurant have been moved to pos_epson_printer. - The methods in pos_restaurant have been moved to point_of_sale. - The module pos_epson_printer_restaurant has been removed as it only handled printers. Some of these methods have been adapted/renamed to better suit the needs. This branch the first part of the following task: 3224508 closes odoo/odoo#114655 Related: odoo/upgrade#4414 Related: odoo/enterprise#37901 Signed-off-by: Joseph Caburnay (jcb) <jcb@odoo.com>
This commit is contained in:
@@ -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',
|
||||
|
||||
@@ -36,6 +36,13 @@
|
||||
<field name="start_category">True</field>
|
||||
</record>
|
||||
|
||||
<!-- Preparation Printer -->
|
||||
<record id="preparation_printer" model="pos.printer">
|
||||
<field name="name">Preparation Printer</field>
|
||||
<field name="proxy_ip">localhost</field>
|
||||
<field name="product_categories_ids" eval="[(6, 0, [ref('point_of_sale.pos_category_miscellaneous')])]" />
|
||||
</record>
|
||||
|
||||
<!-- Resource: product.product -->
|
||||
<record id="stock.product_cable_management_box" model="product.product">
|
||||
<field name="pos_categ_id" ref="point_of_sale.pos_category_miscellaneous"/>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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."))
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
+1
-1
@@ -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
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 || [])],
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
<odoo>
|
||||
<record id="view_pos_printer_form" model="ir.ui.view">
|
||||
<field name="name">Preparation Printer</field>
|
||||
<field name="model">pos.printer</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="POS Printer">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="name" />
|
||||
<field name="printer_type" widget="radio"/>
|
||||
<field name="proxy_ip" attrs="{'invisible': [('printer_type', '!=', 'iot')]}"/>
|
||||
<field name="product_categories_ids" />
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_pos_printer_form" model="ir.actions.act_window">
|
||||
<field name="name">Preparation Printers</field>
|
||||
<field name="res_model">pos.printer</field>
|
||||
<field name="view_mode">tree,kanban,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Add a new restaurant order printer
|
||||
</p><p>
|
||||
Order Printers are used by restaurants and bars to print the
|
||||
order updates in the kitchen/bar when the waiter updates the order.
|
||||
</p><p>
|
||||
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.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_pos_printer" model="ir.ui.view">
|
||||
<field name="name">Preparation Printers</field>
|
||||
<field name="model">pos.printer</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Preparation Printers">
|
||||
<field name="name" />
|
||||
<field name="proxy_ip" />
|
||||
<field name="product_categories_ids" widget="many2many_tags"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -333,6 +333,18 @@
|
||||
</div>
|
||||
</div>
|
||||
</setting>
|
||||
<setting string="Preparation Printers" help="Print orders at the kitchen, at the bar, etc." id="is_order_printer">
|
||||
<field name="pos_is_order_printer"/>
|
||||
<div class="content-group" attrs="{'invisible': [('pos_is_order_printer', '=', False)]}">
|
||||
<div class="mt16">
|
||||
<label string="Printers" for="pos_printer_ids" class="o_light_label"/>
|
||||
<field name="pos_printer_ids" widget="many2many_tags"/>
|
||||
</div>
|
||||
<div>
|
||||
<button name="%(point_of_sale.action_pos_printer_form)d" icon="fa-arrow-right" type="action" string="Printers" class="btn-link"/>
|
||||
</div>
|
||||
</div>
|
||||
</setting>
|
||||
<setting string="Preparation Display" help="Display orders on the preparation display" id="preparation_display">
|
||||
<field name="module_pos_preparation_display"/>
|
||||
</setting>
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -3,3 +3,5 @@
|
||||
|
||||
from . import pos_config
|
||||
from . import res_config_settings
|
||||
from . import pos_printer
|
||||
from . import pos_session
|
||||
|
||||
@@ -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."))
|
||||
+2
-3
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
+4
-4
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="view_restaurant_printer_iot_form" model="ir.ui.view">
|
||||
<field name="name">pos.restaurant.iot.config.form.view</field>
|
||||
<field name="model">restaurant.printer</field>
|
||||
<field name="inherit_id" ref="pos_restaurant.view_restaurant_printer_form"/>
|
||||
<record id="view_pos_printer_form" model="ir.ui.view">
|
||||
<field name="name">pos.iot.config.form.view</field>
|
||||
<field name="model">pos.printer</field>
|
||||
<field name="inherit_id" ref="point_of_sale.view_pos_printer_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="printer_type" position="after">
|
||||
<field name="epson_printer_ip" attrs="{'invisible': [('printer_type', '!=', 'epson_epos')]}"/>
|
||||
@@ -1,4 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import models
|
||||
@@ -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',
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * pos_epson_printer_restaurant
|
||||
#
|
||||
# Translators:
|
||||
# Ali Alrehawi <alrehawi@hotmail.com>, 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 <alrehawi@hotmail.com>, 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 ""
|
||||
@@ -1,45 +0,0 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * pos_epson_printer_restaurant
|
||||
#
|
||||
# Translators:
|
||||
# trendspotter <j.podhorecky@volny.cz>, 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 <j.podhorecky@volny.cz>, 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 ""
|
||||
@@ -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 ""
|
||||
@@ -1,45 +0,0 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * pos_epson_printer_restaurant
|
||||
#
|
||||
# Translators:
|
||||
# Chris Egal <sodaswed@web.de>, 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 <sodaswed@web.de>, 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 ""
|
||||
@@ -1,45 +0,0 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * pos_epson_printer_restaurant
|
||||
#
|
||||
# Translators:
|
||||
# Jon Perez <jop@odoo.com>, 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 <jop@odoo.com>, 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"
|
||||
@@ -1,46 +0,0 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * pos_epson_printer_restaurant
|
||||
#
|
||||
# Translators:
|
||||
# Nicolas Roussey <nro@odoo.com>, 2019
|
||||
# thomas quertinmont <tqu@odoo.com>, 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 <tqu@odoo.com>, 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"
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -1,46 +0,0 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * pos_epson_printer_restaurant
|
||||
#
|
||||
# Translators:
|
||||
# Sergio Zanchetta <primes2h@gmail.com>, 2019
|
||||
# Luigia Cimmino Caserta <lcc@odoo.com>, 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 <lcc@odoo.com>, 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"
|
||||
@@ -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 ""
|
||||
@@ -1,45 +0,0 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * pos_epson_printer_restaurant
|
||||
#
|
||||
# Translators:
|
||||
# Linas Versada <linaskrisiukenas@gmail.com>, 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 <linaskrisiukenas@gmail.com>, 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 ""
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -1,46 +0,0 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * pos_epson_printer_restaurant
|
||||
#
|
||||
# Translators:
|
||||
# Cas Vissers <casvissers@brahoo.nl>, 2019
|
||||
# Yenthe Van Ginneken <yenthespam@gmail.com>, 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 <yenthespam@gmail.com>, 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"
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -1,45 +0,0 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * pos_epson_printer_restaurant
|
||||
#
|
||||
# Translators:
|
||||
# Alina Lisnenko <alinasemeniuk1@gmail.com>, 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 <alinasemeniuk1@gmail.com>, 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"
|
||||
@@ -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 ""
|
||||
@@ -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 <fyu@odoo.com>, 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 <fyu@odoo.com>, 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打印机"
|
||||
@@ -1,45 +0,0 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * pos_epson_printer_restaurant
|
||||
#
|
||||
# Translators:
|
||||
# 敬雲 林 <chingyun@yuanchih-consult.com>, 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: 敬雲 林 <chingyun@yuanchih-consult.com>, 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 ""
|
||||
@@ -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
|
||||
@@ -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.")
|
||||
@@ -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);
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -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)
|
||||
|
||||
@@ -3,14 +3,6 @@
|
||||
|
||||
<!-- ****** Basic Restaurant Setup ***** -->
|
||||
|
||||
<!-- Kitchen Printer -->
|
||||
|
||||
<record id="kitchen_printer" model="restaurant.printer">
|
||||
<field name="name">Kitchen Printer</field>
|
||||
<field name="proxy_ip">localhost</field>
|
||||
<field name="product_categories_ids" eval="[(6, 0, [ref('point_of_sale.pos_category_miscellaneous')])]" />
|
||||
</record>
|
||||
|
||||
<record id="drinks" model="pos.category">
|
||||
<field name="name">Drinks</field>
|
||||
</record>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+3
-3
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
});
|
||||
@@ -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);
|
||||
|
||||
@@ -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", {
|
||||
|
||||
@@ -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 ------- */
|
||||
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<div class="control-button" t-on-click="() => this.click()">
|
||||
<i class="fa fa-tag" />
|
||||
<span> </span>
|
||||
<span>Kitchen Note</span>
|
||||
<span>Internal Note</span>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
|
||||
<t t-name="Orderline" t-inherit="point_of_sale.Orderline" t-inherit-mode="extension" owl="1">
|
||||
<xpath expr="//ul[hasclass('info-list')]" position="inside">
|
||||
<t t-if="props.line.get_note()">
|
||||
<t t-if="props.line.getNote()">
|
||||
<li class="info orderline-note">
|
||||
<i class="fa fa-tag" role="img" aria-label="Note" title="Note"/>
|
||||
<t t-esc="props.line.get_note()" />
|
||||
<t t-esc="props.line.getNote()" />
|
||||
</li>
|
||||
</t>
|
||||
</xpath>
|
||||
|
||||
@@ -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")',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
|
||||
@@ -111,61 +111,4 @@
|
||||
action="action_restaurant_floor_form"
|
||||
sequence="10"
|
||||
groups="base.group_no_one"/>
|
||||
|
||||
<!-- RESTAURANT PRINTERS -->
|
||||
|
||||
<record id="view_restaurant_printer_form" model="ir.ui.view">
|
||||
<field name="name">Order Printer</field>
|
||||
<field name="model">restaurant.printer</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="POS Printer">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="name" />
|
||||
<field name="printer_type" widget="radio"/>
|
||||
<field name="proxy_ip" attrs="{'invisible': [('printer_type', '!=', 'iot')]}"/>
|
||||
<field name="product_categories_ids" />
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_restaurant_printer_form" model="ir.actions.act_window">
|
||||
<field name="name">Order Printers</field>
|
||||
<field name="res_model">restaurant.printer</field>
|
||||
<field name="view_mode">tree,kanban,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Add a new restaurant order printer
|
||||
</p><p>
|
||||
Order Printers are used by restaurants and bars to print the
|
||||
order updates in the kitchen/bar when the waiter updates the order.
|
||||
</p><p>
|
||||
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.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_restaurant_printer" model="ir.ui.view">
|
||||
<field name="name">Order Printers</field>
|
||||
<field name="model">restaurant.printer</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Restaurant Order Printers">
|
||||
<field name="name" />
|
||||
<field name="proxy_ip" />
|
||||
<field name="product_categories_ids" widget="many2many_tags"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_restaurant_printer_all"
|
||||
parent="point_of_sale.menu_point_config_product"
|
||||
action="action_restaurant_printer_form"
|
||||
sequence="15"
|
||||
groups="base.group_no_one"/>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</setting>
|
||||
<setting string="Kitchen Notes" help="Add kitchen notes on order lines for the kitchen" id="iface_orderline_notes" attrs="{'invisible': [('pos_module_pos_restaurant', '=', False)]}">
|
||||
<setting string="Internal Notes" help="Add internal notes on order lines for the kitchen" id="iface_orderline_notes" attrs="{'invisible': [('pos_module_pos_restaurant', '=', False)]}">
|
||||
<field name="pos_iface_orderline_notes"/>
|
||||
</setting>
|
||||
<setting string="Early Receipt Printing" help="Allow to print receipt before payment" id="iface_printbill" attrs="{'invisible': [('pos_module_pos_restaurant', '=', False)]}">
|
||||
@@ -29,18 +29,6 @@
|
||||
<setting help="Split total or order lines" id="iface_splitbill" attrs="{'invisible': [('pos_module_pos_restaurant', '=', False)]}">
|
||||
<field name="pos_iface_splitbill" string="Allow Bill Splitting"/>
|
||||
</setting>
|
||||
<setting string="Kitchen Printers" help="Print orders at the kitchen, at the bar, etc." id="is_order_printer" attrs="{'invisible': [('pos_module_pos_restaurant', '=', False)]}">
|
||||
<field name="pos_is_order_printer"/>
|
||||
<div class="content-group" attrs="{'invisible': [('pos_is_order_printer', '=', False)]}">
|
||||
<div class="mt16">
|
||||
<label string="Printers" for="pos_printer_ids" class="o_light_label"/>
|
||||
<field name="pos_printer_ids" widget="many2many_tags"/>
|
||||
</div>
|
||||
<div>
|
||||
<button name="%(pos_restaurant.action_restaurant_printer_form)d" icon="fa-arrow-right" type="action" string="Printers" class="btn-link"/>
|
||||
</div>
|
||||
</div>
|
||||
</setting>
|
||||
</block>
|
||||
</block>
|
||||
<div id="tip_product" position="after">
|
||||
|
||||
Reference in New Issue
Block a user