From 03678ef8a34e19d6be4404576d8a9a6975a4c1d1 Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Wed, 19 Feb 2025 14:09:44 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=B0=D1=87=D0=B0=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D0=BE=D0=B5=20=D0=BD=D0=B0=D0=BF=D0=BE=D0=BB=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +- __init__.py | 5 + __manifest__.py | 24 ++ controllers/__init__.py | 4 + controllers/main.py | 342 +++++++++++++++ escpos/LICENSE.txt | 21 + escpos/__init__.py | 1 + escpos/constants.py | 190 ++++++++ escpos/escpos.py | 935 ++++++++++++++++++++++++++++++++++++++++ escpos/exceptions.py | 115 +++++ escpos/printer.py | 227 ++++++++++ i18n/af.po | 42 ++ i18n/ar.po | 42 ++ i18n/bg.po | 42 ++ i18n/bs.po | 42 ++ i18n/ca.po | 42 ++ i18n/cs.po | 43 ++ i18n/da.po | 42 ++ i18n/de.po | 44 ++ i18n/el.po | 43 ++ i18n/en_GB.po | 42 ++ i18n/es.po | 44 ++ i18n/es_BO.po | 42 ++ i18n/es_CL.po | 42 ++ i18n/es_CO.po | 43 ++ i18n/es_CR.po | 42 ++ i18n/es_DO.po | 43 ++ i18n/es_EC.po | 43 ++ i18n/es_PE.po | 43 ++ i18n/es_PY.po | 42 ++ i18n/es_VE.po | 42 ++ i18n/et.po | 42 ++ i18n/eu.po | 42 ++ i18n/fa.po | 42 ++ i18n/fi.po | 43 ++ i18n/fr.po | 45 ++ i18n/gu.po | 43 ++ i18n/he.po | 56 +++ i18n/hi.po | 42 ++ i18n/hr.po | 42 ++ i18n/hu.po | 43 ++ i18n/hw_escpos.pot | 41 ++ i18n/id.po | 42 ++ i18n/it.po | 42 ++ i18n/ja.po | 43 ++ i18n/kab.po | 42 ++ i18n/ko.po | 42 ++ i18n/lt.po | 42 ++ i18n/lv.po | 42 ++ i18n/mk.po | 43 ++ i18n/mn.po | 42 ++ i18n/nb.po | 42 ++ i18n/nl.po | 43 ++ i18n/pl.po | 43 ++ i18n/pt.po | 54 +++ i18n/pt_BR.po | 43 ++ i18n/ro.po | 43 ++ i18n/ru.po | 43 ++ i18n/sk.po | 43 ++ i18n/sl.po | 42 ++ i18n/sq.po | 42 ++ i18n/sr.po | 42 ++ i18n/sr@latin.po | 42 ++ i18n/sv.po | 43 ++ i18n/th.po | 43 ++ i18n/tr.po | 43 ++ i18n/uk.po | 44 ++ i18n/vi.po | 42 ++ i18n/zh_CN.po | 45 ++ i18n/zh_HK.po | 42 ++ i18n/zh_TW.po | 42 ++ 71 files changed, 4444 insertions(+), 1 deletion(-) create mode 100644 __init__.py create mode 100644 __manifest__.py create mode 100644 controllers/__init__.py create mode 100644 controllers/main.py create mode 100644 escpos/LICENSE.txt create mode 100644 escpos/__init__.py create mode 100644 escpos/constants.py create mode 100644 escpos/escpos.py create mode 100644 escpos/exceptions.py create mode 100644 escpos/printer.py create mode 100644 i18n/af.po create mode 100644 i18n/ar.po create mode 100644 i18n/bg.po create mode 100644 i18n/bs.po create mode 100644 i18n/ca.po create mode 100644 i18n/cs.po create mode 100644 i18n/da.po create mode 100644 i18n/de.po create mode 100644 i18n/el.po create mode 100644 i18n/en_GB.po create mode 100644 i18n/es.po create mode 100644 i18n/es_BO.po create mode 100644 i18n/es_CL.po create mode 100644 i18n/es_CO.po create mode 100644 i18n/es_CR.po create mode 100644 i18n/es_DO.po create mode 100644 i18n/es_EC.po create mode 100644 i18n/es_PE.po create mode 100644 i18n/es_PY.po create mode 100644 i18n/es_VE.po create mode 100644 i18n/et.po create mode 100644 i18n/eu.po create mode 100644 i18n/fa.po create mode 100644 i18n/fi.po create mode 100644 i18n/fr.po create mode 100644 i18n/gu.po create mode 100644 i18n/he.po create mode 100644 i18n/hi.po create mode 100644 i18n/hr.po create mode 100644 i18n/hu.po create mode 100644 i18n/hw_escpos.pot create mode 100644 i18n/id.po create mode 100644 i18n/it.po create mode 100644 i18n/ja.po create mode 100644 i18n/kab.po create mode 100644 i18n/ko.po create mode 100644 i18n/lt.po create mode 100644 i18n/lv.po create mode 100644 i18n/mk.po create mode 100644 i18n/mn.po create mode 100644 i18n/nb.po create mode 100644 i18n/nl.po create mode 100644 i18n/pl.po create mode 100644 i18n/pt.po create mode 100644 i18n/pt_BR.po create mode 100644 i18n/ro.po create mode 100644 i18n/ru.po create mode 100644 i18n/sk.po create mode 100644 i18n/sl.po create mode 100644 i18n/sq.po create mode 100644 i18n/sr.po create mode 100644 i18n/sr@latin.po create mode 100644 i18n/sv.po create mode 100644 i18n/th.po create mode 100644 i18n/tr.po create mode 100644 i18n/uk.po create mode 100644 i18n/vi.po create mode 100644 i18n/zh_CN.po create mode 100644 i18n/zh_HK.po create mode 100644 i18n/zh_TW.po diff --git a/README.md b/README.md index 0de9f35..792571a 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ -# hw_escpos +The escpos directory contains the MIT licensed pyxmlescpos lib taken from + +https://github.com/fvdsn/py-xml-escpos diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..175e48a --- /dev/null +++ b/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import controllers +from . import escpos diff --git a/__manifest__.py b/__manifest__.py new file mode 100644 index 0000000..1b0d5d9 --- /dev/null +++ b/__manifest__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +{ + 'name': 'ESC/POS Hardware Driver', + 'category': 'Sales/Point of Sale', + 'sequence': 6, + 'website': 'https://www.odoo.com/app/point-of-sale-hardware', + 'summary': 'Hardware Driver for ESC/POS Printers and Cashdrawers', + 'description': """ +ESC/POS Hardware Driver +======================= + +This module allows Odoo to print with ESC/POS compatible printers and +to open ESC/POS controlled cashdrawers in the point of sale and other modules +that would need such functionality. + +""", + 'external_dependencies': { + 'python' : ['pyusb','pyserial','qrcode'], + }, + 'installable': False, + 'license': 'LGPL-3', +} diff --git a/controllers/__init__.py b/controllers/__init__.py new file mode 100644 index 0000000..5d4b25d --- /dev/null +++ b/controllers/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import main diff --git a/controllers/main.py b/controllers/main.py new file mode 100644 index 0000000..dbe2b12 --- /dev/null +++ b/controllers/main.py @@ -0,0 +1,342 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from __future__ import print_function +import logging +import math +import os +import os.path +import subprocess +import time +import netifaces as ni +import traceback + +try: + from .. escpos import * + from .. escpos.exceptions import * + from .. escpos.printer import Usb +except ImportError: + escpos = printer = None + +from queue import Queue +from threading import Thread, Lock + +try: + import usb.core +except ImportError: + usb = None + +from odoo import http, _ +from odoo.addons.hw_drivers.controllers import proxy + +_logger = logging.getLogger(__name__) + +# workaround https://bugs.launchpad.net/openobject-server/+bug/947231 +# related to http://bugs.python.org/issue7980 +from datetime import datetime +datetime.strptime('2012-01-01', '%Y-%m-%d') + +class EscposDriver(Thread): + def __init__(self): + Thread.__init__(self) + self.queue = Queue() + self.lock = Lock() + self.status = {'status':'connecting', 'messages':[]} + + def connected_usb_devices(self): + connected = [] + + # printers can either define bDeviceClass=7, or they can define one of + # their interfaces with bInterfaceClass=7. This class checks for both. + class FindUsbClass(object): + def __init__(self, usb_class): + self._class = usb_class + def __call__(self, device): + # first, let's check the device + if device.bDeviceClass == self._class: + return True + # transverse all devices and look through their interfaces to + # find a matching class + for cfg in device: + intf = usb.util.find_descriptor(cfg, bInterfaceClass=self._class) + + if intf is not None: + return True + + return False + + printers = usb.core.find(find_all=True, custom_match=FindUsbClass(7)) + + # if no printers are found after this step we will take the + # first epson or star device we can find. + # epson + if not printers: + printers = usb.core.find(find_all=True, idVendor=0x04b8) + # star + if not printers: + printers = usb.core.find(find_all=True, idVendor=0x0519) + + for printer in printers: + try: + description = usb.util.get_string(printer, printer.iManufacturer) + " " + usb.util.get_string(printer, printer.iProduct) + except Exception as e: + _logger.error("Can not get printer description: %s" % e) + description = 'Unknown printer' + connected.append({ + 'vendor': printer.idVendor, + 'product': printer.idProduct, + 'name': description + }) + + return connected + + def lockedstart(self): + with self.lock: + if not self.is_alive(): + self.daemon = True + self.start() + + def get_escpos_printer(self): + + printers = self.connected_usb_devices() + if len(printers) > 0: + try: + print_dev = Usb(printers[0]['vendor'], printers[0]['product']) + except HandleDeviceError: + # Escpos printers are now integrated to PrinterDriver, if the IoTBox is printing + # through Cups at the same time, we get an USBError(16, 'Resource busy'). This means + # that the Odoo instance connected to this IoTBox is up to date and no longer uses + # this escpos library. + return None + self.set_status( + 'connected', + "Connected to %s (in=0x%02x,out=0x%02x)" % (printers[0]['name'], print_dev.in_ep, print_dev.out_ep) + ) + return print_dev + else: + self.set_status('disconnected','Printer Not Found') + return None + + def get_status(self): + self.push_task('status') + return self.status + + def open_cashbox(self,printer): + printer.cashdraw(2) + printer.cashdraw(5) + + def set_status(self, status, message = None): + _logger.info(status+' : '+ (message or 'no message')) + if status == self.status['status']: + if message != None and (len(self.status['messages']) == 0 or message != self.status['messages'][-1]): + self.status['messages'].append(message) + else: + self.status['status'] = status + if message: + self.status['messages'] = [message] + else: + self.status['messages'] = [] + + if status == 'error' and message: + _logger.error('ESC/POS Error: %s', message) + elif status == 'disconnected' and message: + _logger.warning('ESC/POS Device Disconnected: %s', message) + + def run(self): + printer = None + if not escpos: + _logger.error('ESC/POS cannot initialize, please verify system dependencies.') + return + while True: + error = True + timestamp, task, data = self.queue.get(True) + try: + printer = self.get_escpos_printer() + + if printer == None: + if task != 'status': + self.queue.put((timestamp,task,data)) + error = False + time.sleep(5) + continue + elif task == 'receipt': + if timestamp >= time.time() - 1 * 60 * 60: + self.print_receipt_body(printer,data) + printer.cut() + elif task == 'xml_receipt': + if timestamp >= time.time() - 1 * 60 * 60: + printer.receipt(data) + elif task == 'cashbox': + if timestamp >= time.time() - 12: + self.open_cashbox(printer) + elif task == 'status': + pass + error = False + + except NoDeviceError as e: + print("No device found %s" % e) + except HandleDeviceError as e: + printer = None + print("Impossible to handle the device due to previous error %s" % e) + except TicketNotPrinted as e: + print("The ticket does not seems to have been fully printed %s" % e) + except NoStatusError as e: + print("Impossible to get the status of the printer %s" % e) + except Exception as e: + self.set_status('error') + _logger.exception(e) + finally: + if error: + self.queue.put((timestamp, task, data)) + if printer: + printer.close() + printer = None + + def push_task(self,task, data = None): + self.lockedstart() + self.queue.put((time.time(),task,data)) + + def print_receipt_body(self,eprint,receipt): + + def check(string): + return string != True and bool(string) and string.strip() + + def price(amount): + return ("{0:."+str(receipt['precision']['price'])+"f}").format(amount) + + def money(amount): + return ("{0:."+str(receipt['precision']['money'])+"f}").format(amount) + + def quantity(amount): + if math.floor(amount) != amount: + return ("{0:."+str(receipt['precision']['quantity'])+"f}").format(amount) + else: + return str(amount) + + def printline(left, right='', width=40, ratio=0.5, indent=0): + lwidth = int(width * ratio) + rwidth = width - lwidth + lwidth = lwidth - indent + + left = left[:lwidth] + if len(left) != lwidth: + left = left + ' ' * (lwidth - len(left)) + + right = right[-rwidth:] + if len(right) != rwidth: + right = ' ' * (rwidth - len(right)) + right + + return ' ' * indent + left + right + '\n' + + def print_taxes(): + taxes = receipt['tax_details'] + for tax in taxes: + eprint.text(printline(tax['tax']['name'],price(tax['amount']), width=40,ratio=0.6)) + + # Receipt Header + if receipt['company']['logo']: + eprint.set(align='center') + eprint.print_base64_image(receipt['company']['logo']) + eprint.text('\n') + else: + eprint.set(align='center',type='b',height=2,width=2) + eprint.text(receipt['company']['name'] + '\n') + + eprint.set(align='center',type='b') + if check(receipt['company']['contact_address']): + eprint.text(receipt['company']['contact_address'] + '\n') + if check(receipt['company']['phone']): + eprint.text('Tel:' + receipt['company']['phone'] + '\n') + if check(receipt['company']['vat']): + eprint.text('VAT:' + receipt['company']['vat'] + '\n') + if check(receipt['company']['email']): + eprint.text(receipt['company']['email'] + '\n') + if check(receipt['company']['website']): + eprint.text(receipt['company']['website'] + '\n') + if check(receipt['header']): + eprint.text(receipt['header']+'\n') + if check(receipt['cashier']): + eprint.text('-'*32+'\n') + eprint.text('Served by '+receipt['cashier']+'\n') + + # Orderlines + eprint.text('\n\n') + eprint.set(align='center') + for line in receipt['orderlines']: + pricestr = price(line['price_display']) + if line['discount'] == 0 and line['unit_name'] == 'Units' and line['quantity'] == 1: + eprint.text(printline(line['product_name'],pricestr,ratio=0.6)) + else: + eprint.text(printline(line['product_name'],ratio=0.6)) + if line['discount'] != 0: + eprint.text(printline('Discount: '+str(line['discount'])+'%', ratio=0.6, indent=2)) + if line['unit_name'] == 'Units': + eprint.text( printline( quantity(line['quantity']) + ' x ' + price(line['price']), pricestr, ratio=0.6, indent=2)) + else: + eprint.text( printline( quantity(line['quantity']) + line['unit_name'] + ' x ' + price(line['price']), pricestr, ratio=0.6, indent=2)) + + # Subtotal if the taxes are not included + taxincluded = True + if money(receipt['subtotal']) != money(receipt['total_with_tax']): + eprint.text(printline('', '-------')) + eprint.text(printline(_('Subtotal'),money(receipt['subtotal']),width=40, ratio=0.6)) + print_taxes() + #eprint.text(printline(_('Taxes'),money(receipt['total_tax']),width=40, ratio=0.6)) + taxincluded = False + + # Total + eprint.text(printline('', '-------')) + eprint.set(align='center',height=2) + eprint.text(printline(_(' TOTAL'),money(receipt['total_with_tax']),width=40, ratio=0.6)) + eprint.text('\n\n') + + # Paymentlines + eprint.set(align='center') + for line in receipt['paymentlines']: + eprint.text(printline(line['journal'], money(line['amount']), ratio=0.6)) + + eprint.text('\n') + eprint.set(align='center',height=2) + eprint.text(printline(_(' CHANGE'),money(receipt['change']),width=40, ratio=0.6)) + eprint.set(align='center') + eprint.text('\n') + + # Extra Payment info + if receipt['total_discount'] != 0: + eprint.text(printline(_('Discounts'),money(receipt['total_discount']),width=40, ratio=0.6)) + if taxincluded: + print_taxes() + #eprint.text(printline(_('Taxes'),money(receipt['total_tax']),width=40, ratio=0.6)) + + # Footer + if check(receipt['footer']): + eprint.text('\n'+receipt['footer']+'\n\n') + eprint.text(receipt['name']+'\n') + eprint.text( str(receipt['date']['date']).zfill(2) + +'/'+ str(receipt['date']['month']+1).zfill(2) + +'/'+ str(receipt['date']['year']).zfill(4) + +' '+ str(receipt['date']['hour']).zfill(2) + +':'+ str(receipt['date']['minute']).zfill(2) ) + + +driver = EscposDriver() + +proxy.proxy_drivers['escpos'] = driver + + +class EscposProxy(proxy.ProxyController): + + @http.route('/hw_proxy/open_cashbox', type='json', auth='none', cors='*') + def open_cashbox(self): + _logger.info('ESC/POS: OPEN CASHBOX') + driver.push_task('cashbox') + + @http.route('/hw_proxy/print_receipt', type='json', auth='none', cors='*') + def print_receipt(self, receipt): + _logger.info('ESC/POS: PRINT RECEIPT') + driver.push_task('receipt',receipt) + + @http.route('/hw_proxy/print_xml_receipt', type='json', auth='none', cors='*') + def print_xml_receipt(self, receipt): + _logger.info('ESC/POS: PRINT XML RECEIPT') + driver.push_task('xml_receipt',receipt) diff --git a/escpos/LICENSE.txt b/escpos/LICENSE.txt new file mode 100644 index 0000000..8920ee2 --- /dev/null +++ b/escpos/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Frederic van der Essen & Manuel F. Martinez + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/escpos/__init__.py b/escpos/__init__.py new file mode 100644 index 0000000..22a5af6 --- /dev/null +++ b/escpos/__init__.py @@ -0,0 +1 @@ +__all__ = ["constants","escpos","exceptions","printer"] diff --git a/escpos/constants.py b/escpos/constants.py new file mode 100644 index 0000000..0000109 --- /dev/null +++ b/escpos/constants.py @@ -0,0 +1,190 @@ +# -*- coding: utf-8 -*- + +""" ESC/POS Commands (Constants) """ + +# Control characters +ESC = '\x1b' + +# Feed control sequences +CTL_LF = '\x0a' # Print and line feed +CTL_FF = '\x0c' # Form feed +CTL_CR = '\x0d' # Carriage return +CTL_HT = '\x09' # Horizontal tab +CTL_VT = '\x0b' # Vertical tab + +# RT Status commands +DLE_EOT_PRINTER = '\x10\x04\x01' # Transmit printer status +DLE_EOT_OFFLINE = '\x10\x04\x02' +DLE_EOT_ERROR = '\x10\x04\x03' +DLE_EOT_PAPER = '\x10\x04\x04' + +# Printer hardware +HW_INIT = '\x1b\x40' # Clear data in buffer and reset modes +HW_SELECT = '\x1b\x3d\x01' # Printer select +HW_RESET = '\x1b\x3f\x0a\x00' # Reset printer hardware +# Cash Drawer (ESC p ) +_CASH_DRAWER = lambda m, t1='', t2='': ESC + 'p' + m + chr(t1) + chr(t2) +CD_KICK_2 = _CASH_DRAWER('\x00', 50, 50) # Sends a pulse to pin 2 [] +CD_KICK_5 = _CASH_DRAWER('\x01', 50, 50) # Sends a pulse to pin 5 [] +# Paper +PAPER_FULL_CUT = '\x1d\x56\x00' # Full cut paper +PAPER_PART_CUT = '\x1d\x56\x01' # Partial cut paper +# Text format +TXT_NORMAL = '\x1b\x21\x00' # Normal text +TXT_2HEIGHT = '\x1b\x21\x10' # Double height text +TXT_2WIDTH = '\x1b\x21\x20' # Double width text +TXT_DOUBLE = '\x1b\x21\x30' # Double height & Width +TXT_UNDERL_OFF = '\x1b\x2d\x00' # Underline font OFF +TXT_UNDERL_ON = '\x1b\x2d\x01' # Underline font 1-dot ON +TXT_UNDERL2_ON = '\x1b\x2d\x02' # Underline font 2-dot ON +TXT_BOLD_OFF = '\x1b\x45\x00' # Bold font OFF +TXT_BOLD_ON = '\x1b\x45\x01' # Bold font ON +TXT_FONT_A = '\x1b\x4d\x00' # Font type A +TXT_FONT_B = '\x1b\x4d\x01' # Font type B +TXT_ALIGN_LT = '\x1b\x61\x00' # Left justification +TXT_ALIGN_CT = '\x1b\x61\x01' # Centering +TXT_ALIGN_RT = '\x1b\x61\x02' # Right justification +TXT_COLOR_BLACK = '\x1b\x72\x00' # Default Color +TXT_COLOR_RED = '\x1b\x72\x01' # Alternative Color ( Usually Red ) + +# Text Encoding + +TXT_ENC_PC437 = '\x1b\x74\x00' # PC437 USA +TXT_ENC_KATAKANA= '\x1b\x74\x01' # KATAKANA (JAPAN) +TXT_ENC_PC850 = '\x1b\x74\x02' # PC850 Multilingual +TXT_ENC_PC860 = '\x1b\x74\x03' # PC860 Portuguese +TXT_ENC_PC863 = '\x1b\x74\x04' # PC863 Canadian-French +TXT_ENC_PC865 = '\x1b\x74\x05' # PC865 Nordic +TXT_ENC_KANJI6 = '\x1b\x74\x06' # One-pass Kanji, Hiragana +TXT_ENC_KANJI7 = '\x1b\x74\x07' # One-pass Kanji +TXT_ENC_KANJI8 = '\x1b\x74\x08' # One-pass Kanji +TXT_ENC_PC851 = '\x1b\x74\x0b' # PC851 Greek +TXT_ENC_PC853 = '\x1b\x74\x0c' # PC853 Turkish +TXT_ENC_PC857 = '\x1b\x74\x0d' # PC857 Turkish +TXT_ENC_PC737 = '\x1b\x74\x0e' # PC737 Greek +TXT_ENC_8859_7 = '\x1b\x74\x0f' # ISO8859-7 Greek +TXT_ENC_WPC1252 = '\x1b\x74\x10' # WPC1252 +TXT_ENC_PC866 = '\x1b\x74\x11' # PC866 Cyrillic #2 +TXT_ENC_PC852 = '\x1b\x74\x12' # PC852 Latin2 +TXT_ENC_PC858 = '\x1b\x74\x13' # PC858 Euro +TXT_ENC_KU42 = '\x1b\x74\x14' # KU42 Thai +TXT_ENC_TIS11 = '\x1b\x74\x15' # TIS11 Thai +TXT_ENC_TIS18 = '\x1b\x74\x1a' # TIS18 Thai +TXT_ENC_TCVN3 = '\x1b\x74\x1e' # TCVN3 Vietnamese +TXT_ENC_TCVN3B = '\x1b\x74\x1f' # TCVN3 Vietnamese +TXT_ENC_PC720 = '\x1b\x74\x20' # PC720 Arabic +TXT_ENC_WPC775 = '\x1b\x74\x21' # WPC775 Baltic Rim +TXT_ENC_PC855 = '\x1b\x74\x22' # PC855 Cyrillic +TXT_ENC_PC861 = '\x1b\x74\x23' # PC861 Icelandic +TXT_ENC_PC862 = '\x1b\x74\x24' # PC862 Hebrew +TXT_ENC_PC864 = '\x1b\x74\x25' # PC864 Arabic +TXT_ENC_PC869 = '\x1b\x74\x26' # PC869 Greek +TXT_ENC_PC936 = '\x1C\x21\x00' # PC936 GBK(Guobiao Kuozhan) +TXT_ENC_8859_2 = '\x1b\x74\x27' # ISO8859-2 Latin2 +TXT_ENC_8859_9 = '\x1b\x74\x28' # ISO8859-2 Latin9 +TXT_ENC_PC1098 = '\x1b\x74\x29' # PC1098 Farsi +TXT_ENC_PC1118 = '\x1b\x74\x2a' # PC1118 Lithuanian +TXT_ENC_PC1119 = '\x1b\x74\x2b' # PC1119 Lithuanian +TXT_ENC_PC1125 = '\x1b\x74\x2c' # PC1125 Ukrainian +TXT_ENC_WPC1250 = '\x1b\x74\x2d' # WPC1250 Latin2 +TXT_ENC_WPC1251 = '\x1b\x74\x2e' # WPC1251 Cyrillic +TXT_ENC_WPC1253 = '\x1b\x74\x2f' # WPC1253 Greek +TXT_ENC_WPC1254 = '\x1b\x74\x30' # WPC1254 Turkish +TXT_ENC_WPC1255 = '\x1b\x74\x31' # WPC1255 Hebrew +TXT_ENC_WPC1256 = '\x1b\x74\x32' # WPC1256 Arabic +TXT_ENC_WPC1257 = '\x1b\x74\x33' # WPC1257 Baltic Rim +TXT_ENC_WPC1258 = '\x1b\x74\x34' # WPC1258 Vietnamese +TXT_ENC_KZ1048 = '\x1b\x74\x35' # KZ-1048 Kazakhstan + +TXT_ENC_KATAKANA_MAP = { + # Maps UTF-8 Katakana symbols to KATAKANA Page Codes + + # Half-Width Katakanas + '\xef\xbd\xa1':'\xa1', # 。 + '\xef\xbd\xa2':'\xa2', # 「 + '\xef\xbd\xa3':'\xa3', # 」 + '\xef\xbd\xa4':'\xa4', # 、 + '\xef\xbd\xa5':'\xa5', # ・ + + '\xef\xbd\xa6':'\xa6', # ヲ + '\xef\xbd\xa7':'\xa7', # ァ + '\xef\xbd\xa8':'\xa8', # ィ + '\xef\xbd\xa9':'\xa9', # ゥ + '\xef\xbd\xaa':'\xaa', # ェ + '\xef\xbd\xab':'\xab', # ォ + '\xef\xbd\xac':'\xac', # ャ + '\xef\xbd\xad':'\xad', # ュ + '\xef\xbd\xae':'\xae', # ョ + '\xef\xbd\xaf':'\xaf', # ッ + '\xef\xbd\xb0':'\xb0', # ー + '\xef\xbd\xb1':'\xb1', # ア + '\xef\xbd\xb2':'\xb2', # イ + '\xef\xbd\xb3':'\xb3', # ウ + '\xef\xbd\xb4':'\xb4', # エ + '\xef\xbd\xb5':'\xb5', # オ + '\xef\xbd\xb6':'\xb6', # カ + '\xef\xbd\xb7':'\xb7', # キ + '\xef\xbd\xb8':'\xb8', # ク + '\xef\xbd\xb9':'\xb9', # ケ + '\xef\xbd\xba':'\xba', # コ + '\xef\xbd\xbb':'\xbb', # サ + '\xef\xbd\xbc':'\xbc', # シ + '\xef\xbd\xbd':'\xbd', # ス + '\xef\xbd\xbe':'\xbe', # セ + '\xef\xbd\xbf':'\xbf', # ソ + '\xef\xbe\x80':'\xc0', # タ + '\xef\xbe\x81':'\xc1', # チ + '\xef\xbe\x82':'\xc2', # ツ + '\xef\xbe\x83':'\xc3', # テ + '\xef\xbe\x84':'\xc4', # ト + '\xef\xbe\x85':'\xc5', # ナ + '\xef\xbe\x86':'\xc6', # ニ + '\xef\xbe\x87':'\xc7', # ヌ + '\xef\xbe\x88':'\xc8', # ネ + '\xef\xbe\x89':'\xc9', # ノ + '\xef\xbe\x8a':'\xca', # ハ + '\xef\xbe\x8b':'\xcb', # ヒ + '\xef\xbe\x8c':'\xcc', # フ + '\xef\xbe\x8d':'\xcd', # ヘ + '\xef\xbe\x8e':'\xce', # ホ + '\xef\xbe\x8f':'\xcf', # マ + '\xef\xbe\x90':'\xd0', # ミ + '\xef\xbe\x91':'\xd1', # ム + '\xef\xbe\x92':'\xd2', # メ + '\xef\xbe\x93':'\xd3', # モ + '\xef\xbe\x94':'\xd4', # ヤ + '\xef\xbe\x95':'\xd5', # ユ + '\xef\xbe\x96':'\xd6', # ヨ + '\xef\xbe\x97':'\xd7', # ラ + '\xef\xbe\x98':'\xd8', # リ + '\xef\xbe\x99':'\xd9', # ル + '\xef\xbe\x9a':'\xda', # レ + '\xef\xbe\x9b':'\xdb', # ロ + '\xef\xbe\x9c':'\xdc', # ワ + '\xef\xbe\x9d':'\xdd', # ン + + '\xef\xbe\x9e':'\xde', # ゙ + '\xef\xbe\x9f':'\xdf', # ゚ +} + +# Barcod format +BARCODE_TXT_OFF = '\x1d\x48\x00' # HRI barcode chars OFF +BARCODE_TXT_ABV = '\x1d\x48\x01' # HRI barcode chars above +BARCODE_TXT_BLW = '\x1d\x48\x02' # HRI barcode chars below +BARCODE_TXT_BTH = '\x1d\x48\x03' # HRI barcode chars both above and below +BARCODE_FONT_A = '\x1d\x66\x00' # Font type A for HRI barcode chars +BARCODE_FONT_B = '\x1d\x66\x01' # Font type B for HRI barcode chars +BARCODE_HEIGHT = '\x1d\x68\x64' # Barcode Height [1-255] +BARCODE_WIDTH = '\x1d\x77\x03' # Barcode Width [2-6] +BARCODE_UPC_A = '\x1d\x6b\x00' # Barcode type UPC-A +BARCODE_UPC_E = '\x1d\x6b\x01' # Barcode type UPC-E +BARCODE_EAN13 = '\x1d\x6b\x02' # Barcode type EAN13 +BARCODE_EAN8 = '\x1d\x6b\x03' # Barcode type EAN8 +BARCODE_CODE39 = '\x1d\x6b\x04' # Barcode type CODE39 +BARCODE_ITF = '\x1d\x6b\x05' # Barcode type ITF +BARCODE_NW7 = '\x1d\x6b\x06' # Barcode type NW7 +# Image format +S_RASTER_N = '\x1d\x76\x30\x00' # Set raster image normal size +S_RASTER_2W = '\x1d\x76\x30\x01' # Set raster image double width +S_RASTER_2H = '\x1d\x76\x30\x02' # Set raster image double height +S_RASTER_Q = '\x1d\x76\x30\x03' # Set raster image quadruple diff --git a/escpos/escpos.py b/escpos/escpos.py new file mode 100644 index 0000000..fd8b205 --- /dev/null +++ b/escpos/escpos.py @@ -0,0 +1,935 @@ +# -*- coding: utf-8 -*- + +from __future__ import print_function +import base64 +import copy +import io +import math +import re +import traceback +import codecs +from hashlib import md5 + +from PIL import Image +from xml.etree import ElementTree as ET + + +try: + import jcconv +except ImportError: + jcconv = None + +try: + import qrcode +except ImportError: + qrcode = None + +from .constants import * +from .exceptions import * + +def utfstr(stuff): + """ converts stuff to string and does without failing if stuff is a utf8 string """ + if isinstance(stuff, str): + return stuff + else: + return str(stuff) + +class StyleStack: + """ + The stylestack is used by the xml receipt serializer to compute the active styles along the xml + document. Styles are just xml attributes, there is no css mechanism. But the style applied by + the attributes are inherited by deeper nodes. + """ + def __init__(self): + self.stack = [] + self.defaults = { # default style values + 'align': 'left', + 'underline': 'off', + 'bold': 'off', + 'size': 'normal', + 'font' : 'a', + 'width': 48, + 'indent': 0, + 'tabwidth': 2, + 'bullet': ' - ', + 'line-ratio':0.5, + 'color': 'black', + + 'value-decimals': 2, + 'value-symbol': '', + 'value-symbol-position': 'after', + 'value-autoint': 'off', + 'value-decimals-separator': '.', + 'value-thousands-separator': ',', + 'value-width': 0, + + } + + self.types = { # attribute types, default is string and can be ommitted + 'width': 'int', + 'indent': 'int', + 'tabwidth': 'int', + 'line-ratio': 'float', + 'value-decimals': 'int', + 'value-width': 'int', + } + + self.cmds = { + # translation from styles to escpos commands + # some style do not correspond to escpos command are used by + # the serializer instead + 'align': { + 'left': TXT_ALIGN_LT, + 'right': TXT_ALIGN_RT, + 'center': TXT_ALIGN_CT, + '_order': 1, + }, + 'underline': { + 'off': TXT_UNDERL_OFF, + 'on': TXT_UNDERL_ON, + 'double': TXT_UNDERL2_ON, + # must be issued after 'size' command + # because ESC ! resets ESC - + '_order': 10, + }, + 'bold': { + 'off': TXT_BOLD_OFF, + 'on': TXT_BOLD_ON, + # must be issued after 'size' command + # because ESC ! resets ESC - + '_order': 10, + }, + 'font': { + 'a': TXT_FONT_A, + 'b': TXT_FONT_B, + # must be issued after 'size' command + # because ESC ! resets ESC - + '_order': 10, + }, + 'size': { + 'normal': TXT_NORMAL, + 'double-height': TXT_2HEIGHT, + 'double-width': TXT_2WIDTH, + 'double': TXT_DOUBLE, + '_order': 1, + }, + 'color': { + 'black': TXT_COLOR_BLACK, + 'red': TXT_COLOR_RED, + '_order': 1, + }, + } + + self.push(self.defaults) + + def get(self,style): + """ what's the value of a style at the current stack level""" + level = len(self.stack) -1 + while level >= 0: + if style in self.stack[level]: + return self.stack[level][style] + else: + level = level - 1 + return None + + def enforce_type(self, attr, val): + """converts a value to the attribute's type""" + if not attr in self.types: + return utfstr(val) + elif self.types[attr] == 'int': + return int(float(val)) + elif self.types[attr] == 'float': + return float(val) + else: + return utfstr(val) + + def push(self, style={}): + """push a new level on the stack with a style dictionnary containing style:value pairs""" + _style = {} + for attr in style: + if attr in self.cmds and not style[attr] in self.cmds[attr]: + print('WARNING: ESC/POS PRINTING: ignoring invalid value: %s for style %s' % (style[attr], utfstr(attr))) + else: + _style[attr] = self.enforce_type(attr, style[attr]) + self.stack.append(_style) + + def set(self, style={}): + """overrides style values at the current stack level""" + _style = {} + for attr in style: + if attr in self.cmds and not style[attr] in self.cmds[attr]: + print('WARNING: ESC/POS PRINTING: ignoring invalid value: %s for style %s' % (style[attr], attr)) + else: + self.stack[-1][attr] = self.enforce_type(attr, style[attr]) + + def pop(self): + """ pop a style stack level """ + if len(self.stack) > 1 : + self.stack = self.stack[:-1] + + def to_escpos(self): + """ converts the current style to an escpos command string """ + cmd = '' + ordered_cmds = sorted(self.cmds, key=lambda x: self.cmds[x]['_order']) + for style in ordered_cmds: + cmd += self.cmds[style][self.get(style)] + return cmd + +class XmlSerializer: + """ + Converts the xml inline / block tree structure to a string, + keeping track of newlines and spacings. + The string is outputted asap to the provided escpos driver. + """ + def __init__(self,escpos): + self.escpos = escpos + self.stack = ['block'] + self.dirty = False + + def start_inline(self,stylestack=None): + """ starts an inline entity with an optional style definition """ + self.stack.append('inline') + if self.dirty: + self.escpos._raw(' ') + if stylestack: + self.style(stylestack) + + def start_block(self,stylestack=None): + """ starts a block entity with an optional style definition """ + if self.dirty: + self.escpos._raw('\n') + self.dirty = False + self.stack.append('block') + if stylestack: + self.style(stylestack) + + def end_entity(self): + """ ends the entity definition. (but does not cancel the active style!) """ + if self.stack[-1] == 'block' and self.dirty: + self.escpos._raw('\n') + self.dirty = False + if len(self.stack) > 1: + self.stack = self.stack[:-1] + + def pre(self,text): + """ puts a string of text in the entity keeping the whitespace intact """ + if text: + self.escpos.text(text) + self.dirty = True + + def text(self,text): + """ puts text in the entity. Whitespace and newlines are stripped to single spaces. """ + if text: + text = utfstr(text) + text = text.strip() + text = re.sub('\s+',' ',text) + if text: + self.dirty = True + self.escpos.text(text) + + def linebreak(self): + """ inserts a linebreak in the entity """ + self.dirty = False + self.escpos._raw('\n') + + def style(self,stylestack): + """ apply a style to the entity (only applies to content added after the definition) """ + self.raw(stylestack.to_escpos()) + + def raw(self,raw): + """ puts raw text or escpos command in the entity without affecting the state of the serializer """ + self.escpos._raw(raw) + +class XmlLineSerializer: + """ + This is used to convert a xml tree into a single line, with a left and a right part. + The content is not output to escpos directly, and is intended to be fedback to the + XmlSerializer as the content of a block entity. + """ + def __init__(self, indent=0, tabwidth=2, width=48, ratio=0.5): + self.tabwidth = tabwidth + self.indent = indent + self.width = max(0, width - int(tabwidth*indent)) + self.lwidth = int(self.width*ratio) + self.rwidth = max(0, self.width - self.lwidth) + self.clwidth = 0 + self.crwidth = 0 + self.lbuffer = '' + self.rbuffer = '' + self.left = True + + def _txt(self,txt): + if self.left: + if self.clwidth < self.lwidth: + txt = txt[:max(0, self.lwidth - self.clwidth)] + self.lbuffer += txt + self.clwidth += len(txt) + else: + if self.crwidth < self.rwidth: + txt = txt[:max(0, self.rwidth - self.crwidth)] + self.rbuffer += txt + self.crwidth += len(txt) + + def start_inline(self,stylestack=None): + if (self.left and self.clwidth) or (not self.left and self.crwidth): + self._txt(' ') + + def start_block(self,stylestack=None): + self.start_inline(stylestack) + + def end_entity(self): + pass + + def pre(self,text): + if text: + self._txt(text) + def text(self,text): + if text: + text = utfstr(text) + text = text.strip() + text = re.sub('\s+',' ',text) + if text: + self._txt(text) + + def linebreak(self): + pass + def style(self,stylestack): + pass + def raw(self,raw): + pass + + def start_right(self): + self.left = False + + def get_line(self): + return ' ' * self.indent * self.tabwidth + self.lbuffer + ' ' * (self.width - self.clwidth - self.crwidth) + self.rbuffer + + +class Escpos: + """ ESC/POS Printer object """ + device = None + encoding = None + img_cache = {} + + def _check_image_size(self, size): + """ Check and fix the size of the image to 32 bits """ + if size % 32 == 0: + return (0, 0) + else: + image_border = 32 - (size % 32) + if (image_border % 2) == 0: + return (int(image_border / 2), int(image_border / 2)) + else: + return (int(image_border / 2), int((image_border / 2) + 1)) + + def _print_image(self, line, size): + """ Print formatted image """ + i = 0 + cont = 0 + buffer = "" + + + self._raw(S_RASTER_N) + buffer = b"%02X%02X%02X%02X" % (int((size[0]/size[1])/8), 0, size[1], 0) + self._raw(codecs.decode(buffer, 'hex')) + buffer = "" + + while i < len(line): + hex_string = int(line[i:i+8],2) + buffer += "%02X" % hex_string + i += 8 + cont += 1 + if cont % 4 == 0: + self._raw(codecs.decode(buffer, "hex")) + buffer = "" + cont = 0 + + def _raw_print_image(self, line, size, output=None ): + """ Print formatted image """ + i = 0 + cont = 0 + buffer = "" + raw = b"" + + def __raw(string): + if output: + output(string) + else: + self._raw(string) + + raw += S_RASTER_N.encode('utf-8') + buffer = "%02X%02X%02X%02X" % (int((size[0]/size[1])/8), 0, size[1], 0) + raw += codecs.decode(buffer, 'hex') + buffer = "" + + while i < len(line): + hex_string = int(line[i:i+8],2) + buffer += "%02X" % hex_string + i += 8 + cont += 1 + if cont % 4 == 0: + raw += codecs.decode(buffer, 'hex') + buffer = "" + cont = 0 + + return raw + + def _convert_image(self, im): + """ Parse image and prepare it to a printable format """ + pixels = [] + pix_line = "" + im_left = "" + im_right = "" + switch = 0 + img_size = [ 0, 0 ] + + + if im.size[0] > 512: + print("WARNING: Image is wider than 512 and could be truncated at print time ") + if im.size[1] > 255: + raise ImageSizeError() + + im_border = self._check_image_size(im.size[0]) + for i in range(im_border[0]): + im_left += "0" + for i in range(im_border[1]): + im_right += "0" + + for y in range(im.size[1]): + img_size[1] += 1 + pix_line += im_left + img_size[0] += im_border[0] + for x in range(im.size[0]): + img_size[0] += 1 + RGB = im.getpixel((x, y)) + im_color = (RGB[0] + RGB[1] + RGB[2]) + im_pattern = "1X0" + pattern_len = len(im_pattern) + switch = (switch - 1 ) * (-1) + for x in range(pattern_len): + if im_color <= (255 * 3 / pattern_len * (x+1)): + if im_pattern[x] == "X": + pix_line += "%d" % switch + else: + pix_line += im_pattern[x] + break + elif im_color > (255 * 3 / pattern_len * pattern_len) and im_color <= (255 * 3): + pix_line += im_pattern[-1] + break + pix_line += im_right + img_size[0] += im_border[1] + + return (pix_line, img_size) + + def image(self,path_img): + """ Open image file """ + im_open = Image.open(path_img) + im = im_open.convert("RGB") + # Convert the RGB image in printable image + pix_line, img_size = self._convert_image(im) + self._print_image(pix_line, img_size) + + def print_base64_image(self,img): + + print('print_b64_img') + + id = md5(img).digest() + + if id not in self.img_cache: + print('not in cache') + + img = img[img.find(b',')+1:] + f = io.BytesIO(b'img') + f.write(base64.decodebytes(img)) + f.seek(0) + img_rgba = Image.open(f) + img = Image.new('RGB', img_rgba.size, (255,255,255)) + channels = img_rgba.split() + if len(channels) > 3: + # use alpha channel as mask + img.paste(img_rgba, mask=channels[3]) + else: + img.paste(img_rgba) + + print('convert image') + + pix_line, img_size = self._convert_image(img) + + print('print image') + + buffer = self._raw_print_image(pix_line, img_size) + self.img_cache[id] = buffer + + print('raw image') + + self._raw(self.img_cache[id]) + + def qr(self,text): + """ Print QR Code for the provided string """ + qr_code = qrcode.QRCode(version=4, box_size=4, border=1) + qr_code.add_data(text) + qr_code.make(fit=True) + qr_img = qr_code.make_image() + im = qr_img._img.convert("RGB") + # Convert the RGB image in printable image + self._convert_image(im) + + def barcode(self, code, bc, width=255, height=2, pos='below', font='a'): + """ Print Barcode """ + # Align Bar Code() + self._raw(TXT_ALIGN_CT) + # Height + if height >=2 or height <=6: + self._raw(BARCODE_HEIGHT) + else: + raise BarcodeSizeError() + # Width + if width >= 1 or width <=255: + self._raw(BARCODE_WIDTH) + else: + raise BarcodeSizeError() + # Font + if font.upper() == "B": + self._raw(BARCODE_FONT_B) + else: # DEFAULT FONT: A + self._raw(BARCODE_FONT_A) + # Position + if pos.upper() == "OFF": + self._raw(BARCODE_TXT_OFF) + elif pos.upper() == "BOTH": + self._raw(BARCODE_TXT_BTH) + elif pos.upper() == "ABOVE": + self._raw(BARCODE_TXT_ABV) + else: # DEFAULT POSITION: BELOW + self._raw(BARCODE_TXT_BLW) + # Type + if bc.upper() == "UPC-A": + self._raw(BARCODE_UPC_A) + elif bc.upper() == "UPC-E": + self._raw(BARCODE_UPC_E) + elif bc.upper() == "EAN13": + self._raw(BARCODE_EAN13) + elif bc.upper() == "EAN8": + self._raw(BARCODE_EAN8) + elif bc.upper() == "CODE39": + self._raw(BARCODE_CODE39) + elif bc.upper() == "ITF": + self._raw(BARCODE_ITF) + elif bc.upper() == "NW7": + self._raw(BARCODE_NW7) + else: + raise BarcodeTypeError() + # Print Code + if code: + self._raw(code) + # We are using type A commands + # So we need to add the 'NULL' character + # https://github.com/python-escpos/python-escpos/pull/98/files#diff-a0b1df12c7c67e38915adbe469051e2dR444 + self._raw('\x00') + else: + raise BarcodeCodeError() + + def receipt(self,xml): + """ + Prints an xml based receipt definition + """ + + def strclean(string): + if not string: + string = '' + string = string.strip() + string = re.sub('\s+',' ',string) + return string + + def format_value(value, decimals=3, width=0, decimals_separator='.', thousands_separator=',', autoint=False, symbol='', position='after'): + decimals = max(0,int(decimals)) + width = max(0,int(width)) + value = float(value) + + if autoint and math.floor(value) == value: + decimals = 0 + if width == 0: + width = '' + + if thousands_separator: + formatstr = "{:"+str(width)+",."+str(decimals)+"f}" + else: + formatstr = "{:"+str(width)+"."+str(decimals)+"f}" + + + ret = formatstr.format(value) + ret = ret.replace(',','COMMA') + ret = ret.replace('.','DOT') + ret = ret.replace('COMMA',thousands_separator) + ret = ret.replace('DOT',decimals_separator) + + if symbol: + if position == 'after': + ret = ret + symbol + else: + ret = symbol + ret + return ret + + def print_elem(stylestack, serializer, elem, indent=0): + + elem_styles = { + 'h1': {'bold': 'on', 'size':'double'}, + 'h2': {'size':'double'}, + 'h3': {'bold': 'on', 'size':'double-height'}, + 'h4': {'size': 'double-height'}, + 'h5': {'bold': 'on'}, + 'em': {'font': 'b'}, + 'b': {'bold': 'on'}, + } + + stylestack.push() + if elem.tag in elem_styles: + stylestack.set(elem_styles[elem.tag]) + stylestack.set(elem.attrib) + + if elem.tag in ('p','div','section','article','receipt','header','footer','li','h1','h2','h3','h4','h5'): + serializer.start_block(stylestack) + serializer.text(elem.text) + for child in elem: + print_elem(stylestack,serializer,child) + serializer.start_inline(stylestack) + serializer.text(child.tail) + serializer.end_entity() + serializer.end_entity() + + elif elem.tag in ('span','em','b','left','right'): + serializer.start_inline(stylestack) + serializer.text(elem.text) + for child in elem: + print_elem(stylestack,serializer,child) + serializer.start_inline(stylestack) + serializer.text(child.tail) + serializer.end_entity() + serializer.end_entity() + + elif elem.tag == 'value': + serializer.start_inline(stylestack) + serializer.pre(format_value( + elem.text, + decimals=stylestack.get('value-decimals'), + width=stylestack.get('value-width'), + decimals_separator=stylestack.get('value-decimals-separator'), + thousands_separator=stylestack.get('value-thousands-separator'), + autoint=(stylestack.get('value-autoint') == 'on'), + symbol=stylestack.get('value-symbol'), + position=stylestack.get('value-symbol-position') + )) + serializer.end_entity() + + elif elem.tag == 'line': + width = stylestack.get('width') + if stylestack.get('size') in ('double', 'double-width'): + width = width / 2 + + lineserializer = XmlLineSerializer(stylestack.get('indent')+indent,stylestack.get('tabwidth'),width,stylestack.get('line-ratio')) + serializer.start_block(stylestack) + for child in elem: + if child.tag == 'left': + print_elem(stylestack,lineserializer,child,indent=indent) + elif child.tag == 'right': + lineserializer.start_right() + print_elem(stylestack,lineserializer,child,indent=indent) + serializer.pre(lineserializer.get_line()) + serializer.end_entity() + + elif elem.tag == 'ul': + serializer.start_block(stylestack) + bullet = stylestack.get('bullet') + for child in elem: + if child.tag == 'li': + serializer.style(stylestack) + serializer.raw(' ' * indent * stylestack.get('tabwidth') + bullet) + print_elem(stylestack,serializer,child,indent=indent+1) + serializer.end_entity() + + elif elem.tag == 'ol': + cwidth = len(str(len(elem))) + 2 + i = 1 + serializer.start_block(stylestack) + for child in elem: + if child.tag == 'li': + serializer.style(stylestack) + serializer.raw(' ' * indent * stylestack.get('tabwidth') + ' ' + (str(i)+')').ljust(cwidth)) + i = i + 1 + print_elem(stylestack,serializer,child,indent=indent+1) + serializer.end_entity() + + elif elem.tag == 'pre': + serializer.start_block(stylestack) + serializer.pre(elem.text) + serializer.end_entity() + + elif elem.tag == 'hr': + width = stylestack.get('width') + if stylestack.get('size') in ('double', 'double-width'): + width = width / 2 + serializer.start_block(stylestack) + serializer.text('-'*width) + serializer.end_entity() + + elif elem.tag == 'br': + serializer.linebreak() + + elif elem.tag == 'img': + if 'src' in elem.attrib and 'data:' in elem.attrib['src']: + self.print_base64_image(bytes(elem.attrib['src'], 'utf-8')) + + elif elem.tag == 'barcode' and 'encoding' in elem.attrib: + serializer.start_block(stylestack) + self.barcode(strclean(elem.text),elem.attrib['encoding']) + serializer.end_entity() + + elif elem.tag == 'cut': + self.cut() + elif elem.tag == 'partialcut': + self.cut(mode='part') + elif elem.tag == 'cashdraw': + self.cashdraw(2) + self.cashdraw(5) + + stylestack.pop() + + try: + stylestack = StyleStack() + serializer = XmlSerializer(self) + root = ET.fromstring(xml.encode('utf-8')) + + self._raw(stylestack.to_escpos()) + + print_elem(stylestack,serializer,root) + + if 'open-cashdrawer' in root.attrib and root.attrib['open-cashdrawer'] == 'true': + self.cashdraw(2) + self.cashdraw(5) + if not 'cut' in root.attrib or root.attrib['cut'] == 'true' : + self.cut() + + except Exception as e: + errmsg = str(e)+'\n'+'-'*48+'\n'+traceback.format_exc() + '-'*48+'\n' + self.text(errmsg) + self.cut() + + raise e + + def text(self,txt): + """ Print Utf8 encoded alpha-numeric text """ + if not txt: + return + try: + txt = txt.decode('utf-8') + except: + try: + txt = txt.decode('utf-16') + except: + pass + + self.extra_chars = 0 + + def encode_char(char): + """ + Encodes a single utf-8 character into a sequence of + esc-pos code page change instructions and character declarations + """ + char_utf8 = char.encode('utf-8') + encoded = '' + encoding = self.encoding # we reuse the last encoding to prevent code page switches at every character + encodings = { + # TODO use ordering to prevent useless switches + # TODO Support other encodings not natively supported by python ( Thai, Khazakh, Kanjis ) + 'cp437': TXT_ENC_PC437, + 'cp850': TXT_ENC_PC850, + 'cp852': TXT_ENC_PC852, + 'cp857': TXT_ENC_PC857, + 'cp858': TXT_ENC_PC858, + 'cp860': TXT_ENC_PC860, + 'cp863': TXT_ENC_PC863, + 'cp865': TXT_ENC_PC865, + 'cp1251': TXT_ENC_WPC1251, # win-1251 covers more cyrillic symbols than cp866 + 'cp866': TXT_ENC_PC866, + 'cp862': TXT_ENC_PC862, + 'cp720': TXT_ENC_PC720, + 'cp936': TXT_ENC_PC936, + 'iso8859_2': TXT_ENC_8859_2, + 'iso8859_7': TXT_ENC_8859_7, + 'iso8859_9': TXT_ENC_8859_9, + 'cp1254' : TXT_ENC_WPC1254, + 'cp1255' : TXT_ENC_WPC1255, + 'cp1256' : TXT_ENC_WPC1256, + 'cp1257' : TXT_ENC_WPC1257, + 'cp1258' : TXT_ENC_WPC1258, + 'katakana' : TXT_ENC_KATAKANA, + } + remaining = copy.copy(encodings) + + if not encoding : + encoding = 'cp437' + + while True: # Trying all encoding until one succeeds + try: + if encoding == 'katakana': # Japanese characters + if jcconv: + # try to convert japanese text to a half-katakanas + kata = jcconv.kata2half(jcconv.hira2kata(char_utf8)) + if kata != char_utf8: + self.extra_chars += len(kata.decode('utf-8')) - 1 + # the conversion may result in multiple characters + return encode_str(kata.decode('utf-8')) + else: + kata = char_utf8 + + if kata in TXT_ENC_KATAKANA_MAP: + encoded = TXT_ENC_KATAKANA_MAP[kata] + break + else: + raise ValueError() + else: + # First 127 symbols are covered by cp437. + # Extended range is covered by different encodings. + encoded = char.encode(encoding) + if ord(encoded) <= 127: + encoding = 'cp437' + break + + except (UnicodeEncodeError, UnicodeWarning, TypeError, ValueError): + #the encoding failed, select another one and retry + if encoding in remaining: + del remaining[encoding] + if len(remaining) >= 1: + (encoding, _) = remaining.popitem() + else: + encoding = 'cp437' + encoded = b'\xb1' # could not encode, output error character + break + + if encoding != self.encoding: + # if the encoding changed, remember it and prefix the character with + # the esc-pos encoding change sequence + self.encoding = encoding + encoded = bytes(encodings[encoding], 'utf-8') + encoded + + return encoded + + def encode_str(txt): + buffer = b'' + for c in txt: + buffer += encode_char(c) + return buffer + + txt = encode_str(txt) + + # if the utf-8 -> codepage conversion inserted extra characters, + # remove double spaces to try to restore the original string length + # and prevent printing alignment issues + while self.extra_chars > 0: + dspace = txt.find(' ') + if dspace > 0: + txt = txt[:dspace] + txt[dspace+1:] + self.extra_chars -= 1 + else: + break + + self._raw(txt) + + def set(self, align='left', font='a', type='normal', width=1, height=1): + """ Set text properties """ + # Align + if align.upper() == "CENTER": + self._raw(TXT_ALIGN_CT) + elif align.upper() == "RIGHT": + self._raw(TXT_ALIGN_RT) + elif align.upper() == "LEFT": + self._raw(TXT_ALIGN_LT) + # Font + if font.upper() == "B": + self._raw(TXT_FONT_B) + else: # DEFAULT FONT: A + self._raw(TXT_FONT_A) + # Type + if type.upper() == "B": + self._raw(TXT_BOLD_ON) + self._raw(TXT_UNDERL_OFF) + elif type.upper() == "U": + self._raw(TXT_BOLD_OFF) + self._raw(TXT_UNDERL_ON) + elif type.upper() == "U2": + self._raw(TXT_BOLD_OFF) + self._raw(TXT_UNDERL2_ON) + elif type.upper() == "BU": + self._raw(TXT_BOLD_ON) + self._raw(TXT_UNDERL_ON) + elif type.upper() == "BU2": + self._raw(TXT_BOLD_ON) + self._raw(TXT_UNDERL2_ON) + elif type.upper == "NORMAL": + self._raw(TXT_BOLD_OFF) + self._raw(TXT_UNDERL_OFF) + # Width + if width == 2 and height != 2: + self._raw(TXT_NORMAL) + self._raw(TXT_2WIDTH) + elif height == 2 and width != 2: + self._raw(TXT_NORMAL) + self._raw(TXT_2HEIGHT) + elif height == 2 and width == 2: + self._raw(TXT_2WIDTH) + self._raw(TXT_2HEIGHT) + else: # DEFAULT SIZE: NORMAL + self._raw(TXT_NORMAL) + + + def cut(self, mode=''): + """ Cut paper """ + # Fix the size between last line and cut + # TODO: handle this with a line feed + self._raw("\n\n\n\n\n\n") + if mode.upper() == "PART": + self._raw(PAPER_PART_CUT) + else: # DEFAULT MODE: FULL CUT + self._raw(PAPER_FULL_CUT) + + + def cashdraw(self, pin): + """ Send pulse to kick the cash drawer + + For some reason, with some printers (ex: Epson TM-m30), the cash drawer + only opens 50% of the time if you just send the pulse. But if you read + the status afterwards, it opens all the time. + """ + if pin == 2: + self._raw(CD_KICK_2) + elif pin == 5: + self._raw(CD_KICK_5) + else: + raise CashDrawerError() + + self.get_printer_status() + + def hw(self, hw): + """ Hardware operations """ + if hw.upper() == "INIT": + self._raw(HW_INIT) + elif hw.upper() == "SELECT": + self._raw(HW_SELECT) + elif hw.upper() == "RESET": + self._raw(HW_RESET) + else: # DEFAULT: DOES NOTHING + pass + + + def control(self, ctl): + """ Feed control sequences """ + if ctl.upper() == "LF": + self._raw(CTL_LF) + elif ctl.upper() == "FF": + self._raw(CTL_FF) + elif ctl.upper() == "CR": + self._raw(CTL_CR) + elif ctl.upper() == "HT": + self._raw(CTL_HT) + elif ctl.upper() == "VT": + self._raw(CTL_VT) diff --git a/escpos/exceptions.py b/escpos/exceptions.py new file mode 100644 index 0000000..a56bd17 --- /dev/null +++ b/escpos/exceptions.py @@ -0,0 +1,115 @@ +""" ESC/POS Exceptions classes """ + + +class Error(Exception): + """ Base class for ESC/POS errors """ + def __init__(self, msg, status=None): + Exception.__init__(self) + self.msg = msg + self.resultcode = 1 + if status is not None: + self.resultcode = status + + def __str__(self): + return self.msg + +# Result/Exit codes +# 0 = success +# 10 = No Barcode type defined +# 20 = Barcode size values are out of range +# 30 = Barcode text not supplied +# 40 = Image height is too large +# 50 = No string supplied to be printed +# 60 = Invalid pin to send Cash Drawer pulse + + +class BarcodeTypeError(Error): + def __init__(self, msg=""): + Error.__init__(self, msg) + self.msg = msg + self.resultcode = 10 + + def __str__(self): + return "No Barcode type is defined" + +class BarcodeSizeError(Error): + def __init__(self, msg=""): + Error.__init__(self, msg) + self.msg = msg + self.resultcode = 20 + + def __str__(self): + return "Barcode size is out of range" + +class BarcodeCodeError(Error): + def __init__(self, msg=""): + Error.__init__(self, msg) + self.msg = msg + self.resultcode = 30 + + def __str__(self): + return "Code was not supplied" + +class ImageSizeError(Error): + def __init__(self, msg=""): + Error.__init__(self, msg) + self.msg = msg + self.resultcode = 40 + + def __str__(self): + return "Image height is longer than 255px and can't be printed" + +class TextError(Error): + def __init__(self, msg=""): + Error.__init__(self, msg) + self.msg = msg + self.resultcode = 50 + + def __str__(self): + return "Text string must be supplied to the text() method" + + +class CashDrawerError(Error): + def __init__(self, msg=""): + Error.__init__(self, msg) + self.msg = msg + self.resultcode = 60 + + def __str__(self): + return "Valid pin must be set to send pulse" + +class NoStatusError(Error): + def __init__(self, msg=""): + Error.__init__(self, msg) + self.msg = msg + self.resultcode = 70 + + def __str__(self): + return "Impossible to get status from the printer: " + str(self.msg) + +class TicketNotPrinted(Error): + def __init__(self, msg=""): + Error.__init__(self, msg) + self.msg = msg + self.resultcode = 80 + + def __str__(self): + return "A part of the ticket was not been printed: " + str(self.msg) + +class NoDeviceError(Error): + def __init__(self, msg=""): + Error.__init__(self, msg) + self.msg = msg + self.resultcode = 90 + + def __str__(self): + return str(self.msg) + +class HandleDeviceError(Error): + def __init__(self, msg=""): + Error.__init__(self, msg) + self.msg = msg + self.resultcode = 100 + + def __str__(self): + return str(self.msg) diff --git a/escpos/printer.py b/escpos/printer.py new file mode 100644 index 0000000..3aee55d --- /dev/null +++ b/escpos/printer.py @@ -0,0 +1,227 @@ +#!/usr/bin/python + +from __future__ import print_function +import serial +import socket +import usb.core +import usb.util + +from .escpos import * +from .constants import * +from .exceptions import * +from time import sleep + +class Usb(Escpos): + """ Define USB printer """ + + def __init__(self, idVendor, idProduct, interface=0, in_ep=None, out_ep=None): + """ + @param idVendor : Vendor ID + @param idProduct : Product ID + @param interface : USB device interface + @param in_ep : Input end point + @param out_ep : Output end point + """ + + self.errorText = "ERROR PRINTER\n\n\n\n\n\n"+PAPER_FULL_CUT + + self.idVendor = idVendor + self.idProduct = idProduct + self.interface = interface + self.in_ep = in_ep + self.out_ep = out_ep + + # pyusb dropped the 'interface' parameter from usb.Device.write() at 1.0.0b2 + # https://github.com/pyusb/pyusb/commit/20cd8c1f79b24082ec999c022b56c3febedc0964#diff-b5a4f98a864952f0f55d569dd14695b7L293 + if usb.version_info < (1, 0, 0) or (usb.version_info == (1, 0, 0) and usb.version_info[3] in ("a1", "a2", "a3", "b1")): + self.write_kwargs = dict(interface=self.interface) + else: + self.write_kwargs = {} + + self.open() + + def open(self): + """ Search device on USB tree and set is as escpos device """ + + self.device = usb.core.find(idVendor=self.idVendor, idProduct=self.idProduct) + if self.device is None: + raise NoDeviceError() + try: + if self.device.is_kernel_driver_active(self.interface): + self.device.detach_kernel_driver(self.interface) + self.device.set_configuration() + usb.util.claim_interface(self.device, self.interface) + + cfg = self.device.get_active_configuration() + intf = cfg[(0,0)] # first interface + if self.in_ep is None: + # Attempt to detect IN/OUT endpoint addresses + try: + is_IN = lambda e: usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_IN + is_OUT = lambda e: usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_OUT + endpoint_in = usb.util.find_descriptor(intf, custom_match=is_IN) + endpoint_out = usb.util.find_descriptor(intf, custom_match=is_OUT) + self.in_ep = endpoint_in.bEndpointAddress + self.out_ep = endpoint_out.bEndpointAddress + except usb.core.USBError: + # default values for officially supported printers + self.in_ep = 0x82 + self.out_ep = 0x01 + + except usb.core.USBError as e: + raise HandleDeviceError(e) + + def close(self): + i = 0 + while True: + try: + if not self.device.is_kernel_driver_active(self.interface): + usb.util.release_interface(self.device, self.interface) + self.device.attach_kernel_driver(self.interface) + usb.util.dispose_resources(self.device) + else: + self.device = None + return True + except usb.core.USBError as e: + i += 1 + if i > 10: + return False + + sleep(0.1) + + def _raw(self, msg): + """ Print any command sent in raw format """ + if len(msg) != self.device.write(self.out_ep, msg, timeout=5000, **self.write_kwargs): + self.device.write(self.out_ep, self.errorText, **self.write_kwargs) + raise TicketNotPrinted() + + def __extract_status(self): + maxiterate = 0 + rep = None + while rep == None: + maxiterate += 1 + if maxiterate > 10000: + raise NoStatusError() + r = self.device.read(self.in_ep, 20, self.interface).tolist() + while len(r): + rep = r.pop() + return rep + + def get_printer_status(self): + status = { + 'printer': {}, + 'offline': {}, + 'error' : {}, + 'paper' : {}, + } + + self.device.write(self.out_ep, DLE_EOT_PRINTER, **self.write_kwargs) + printer = self.__extract_status() + self.device.write(self.out_ep, DLE_EOT_OFFLINE, **self.write_kwargs) + offline = self.__extract_status() + self.device.write(self.out_ep, DLE_EOT_ERROR, **self.write_kwargs) + error = self.__extract_status() + self.device.write(self.out_ep, DLE_EOT_PAPER, **self.write_kwargs) + paper = self.__extract_status() + + status['printer']['status_code'] = printer + status['printer']['status_error'] = not ((printer & 147) == 18) + status['printer']['online'] = not bool(printer & 8) + status['printer']['recovery'] = bool(printer & 32) + status['printer']['paper_feed_on'] = bool(printer & 64) + status['printer']['drawer_pin_high'] = bool(printer & 4) + status['offline']['status_code'] = offline + status['offline']['status_error'] = not ((offline & 147) == 18) + status['offline']['cover_open'] = bool(offline & 4) + status['offline']['paper_feed_on'] = bool(offline & 8) + status['offline']['paper'] = not bool(offline & 32) + status['offline']['error'] = bool(offline & 64) + status['error']['status_code'] = error + status['error']['status_error'] = not ((error & 147) == 18) + status['error']['recoverable'] = bool(error & 4) + status['error']['autocutter'] = bool(error & 8) + status['error']['unrecoverable'] = bool(error & 32) + status['error']['auto_recoverable'] = not bool(error & 64) + status['paper']['status_code'] = paper + status['paper']['status_error'] = not ((paper & 147) == 18) + status['paper']['near_end'] = bool(paper & 12) + status['paper']['present'] = not bool(paper & 96) + + return status + + def __del__(self): + """ Release USB interface """ + if self.device: + self.close() + self.device = None + + + +class Serial(Escpos): + """ Define Serial printer """ + + def __init__(self, devfile="/dev/ttyS0", baudrate=9600, bytesize=8, timeout=1): + """ + @param devfile : Device file under dev filesystem + @param baudrate : Baud rate for serial transmission + @param bytesize : Serial buffer size + @param timeout : Read/Write timeout + """ + self.devfile = devfile + self.baudrate = baudrate + self.bytesize = bytesize + self.timeout = timeout + self.open() + + + def open(self): + """ Setup serial port and set is as escpos device """ + self.device = serial.Serial(port=self.devfile, baudrate=self.baudrate, bytesize=self.bytesize, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=self.timeout, dsrdtr=True) + + if self.device is not None: + print("Serial printer enabled") + else: + print("Unable to open serial printer on: %s" % self.devfile) + + + def _raw(self, msg): + """ Print any command sent in raw format """ + self.device.write(msg) + + + def __del__(self): + """ Close Serial interface """ + if self.device is not None: + self.device.close() + + + +class Network(Escpos): + """ Define Network printer """ + + def __init__(self,host,port=9100): + """ + @param host : Printer's hostname or IP address + @param port : Port to write to + """ + self.host = host + self.port = port + self.open() + + + def open(self): + """ Open TCP socket and set it as escpos device """ + self.device = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.device.connect((self.host, self.port)) + + if self.device is None: + print("Could not open socket for %s" % self.host) + + + def _raw(self, msg): + self.device.send(msg) + + + def __del__(self): + """ Close TCP connection """ + self.device.close() diff --git a/i18n/af.po b/i18n/af.po new file mode 100644 index 0000000..262a945 --- /dev/null +++ b/i18n/af.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-08-25 10:14+0000\n" +"Last-Translator: <>\n" +"Language-Team: Afrikaans (http://www.transifex.com/odoo/odoo-9/language/af/)\n" +"Language: af\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Subtotaal" diff --git a/i18n/ar.po b/i18n/ar.po new file mode 100644 index 0000000..60433ea --- /dev/null +++ b/i18n/ar.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:35+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Arabic (http://www.transifex.com/odoo/odoo-9/language/ar/)\n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \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: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "الخصومات" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "المجموع" diff --git a/i18n/bg.po b/i18n/bg.po new file mode 100644 index 0000000..e9f2fc3 --- /dev/null +++ b/i18n/bg.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:35+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Bulgarian (http://www.transifex.com/odoo/odoo-9/language/bg/)\n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Отстъпки" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Междинна сума" diff --git a/i18n/bs.po b/i18n/bs.po new file mode 100644 index 0000000..caa14f9 --- /dev/null +++ b/i18n/bs.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2016-06-05 13:38+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Bosnian (http://www.transifex.com/odoo/odoo-9/language/bs/)\n" +"Language: bs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \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: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Popusti" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Sub-ukupno" diff --git a/i18n/ca.po b/i18n/ca.po new file mode 100644 index 0000000..c39bcf4 --- /dev/null +++ b/i18n/ca.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:35+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Catalan (http://www.transifex.com/odoo/odoo-9/language/ca/)\n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Descomptes" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Subtotal" diff --git a/i18n/cs.po b/i18n/cs.po new file mode 100644 index 0000000..cd424a6 --- /dev/null +++ b/i18n/cs.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Chris , 2016 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2016-06-02 14:32+0000\n" +"Last-Translator: Chris \n" +"Language-Team: Czech (http://www.transifex.com/odoo/odoo-9/language/cs/)\n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "CELKEM" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Slevy" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Mezisoučet" diff --git a/i18n/da.po b/i18n/da.po new file mode 100644 index 0000000..580af78 --- /dev/null +++ b/i18n/da.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:35+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Danish (http://www.transifex.com/odoo/odoo-9/language/da/)\n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Subtotal" diff --git a/i18n/de.po b/i18n/de.po new file mode 100644 index 0000000..e65f89d --- /dev/null +++ b/i18n/de.po @@ -0,0 +1,44 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Fabian Liesch , 2015 +# Wolfgang Taferner, 2016 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2016-01-18 06:57+0000\n" +"Last-Translator: Wolfgang Taferner\n" +"Language-Team: German (http://www.transifex.com/odoo/odoo-9/language/de/)\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "GESAMTSUMME" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "WECHSELGELD" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Rabatte" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Zwischensumme" diff --git a/i18n/el.po b/i18n/el.po new file mode 100644 index 0000000..fa31379 --- /dev/null +++ b/i18n/el.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Goutoudis Kostas , 2015 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-11-20 16:47+0000\n" +"Last-Translator: Goutoudis Kostas \n" +"Language-Team: Greek (http://www.transifex.com/odoo/odoo-9/language/el/)\n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "ΣΥΝΟΛΟ" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Eκπτώσεις" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Μερικό σύνολο" diff --git a/i18n/en_GB.po b/i18n/en_GB.po new file mode 100644 index 0000000..d88763d --- /dev/null +++ b/i18n/en_GB.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:36+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: English (United Kingdom) (http://www.transifex.com/odoo/odoo-9/language/en_GB/)\n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Subtotal" diff --git a/i18n/es.po b/i18n/es.po new file mode 100644 index 0000000..2733279 --- /dev/null +++ b/i18n/es.po @@ -0,0 +1,44 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Carlos rodriguez , 2016 +# Oihane Crucelaegui , 2015 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2016-01-03 20:30+0000\n" +"Last-Translator: Carlos rodriguez \n" +"Language-Team: Spanish (http://www.transifex.com/odoo/odoo-9/language/es/)\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr " TOTAL" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "Cambio" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Descuentos" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Subtotal" diff --git a/i18n/es_BO.po b/i18n/es_BO.po new file mode 100644 index 0000000..260ab90 --- /dev/null +++ b/i18n/es_BO.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-08-25 10:14+0000\n" +"Last-Translator: <>\n" +"Language-Team: Spanish (Bolivia) (http://www.transifex.com/odoo/odoo-9/language/es_BO/)\n" +"Language: es_BO\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Descuentos" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Subtotal" diff --git a/i18n/es_CL.po b/i18n/es_CL.po new file mode 100644 index 0000000..f348d9b --- /dev/null +++ b/i18n/es_CL.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:37+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Spanish (Chile) (http://www.transifex.com/odoo/odoo-9/language/es_CL/)\n" +"Language: es_CL\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Subtotal" diff --git a/i18n/es_CO.po b/i18n/es_CO.po new file mode 100644 index 0000000..c3b3b67 --- /dev/null +++ b/i18n/es_CO.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Mateo Tibaquirá , 2015 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-10-24 06:51+0000\n" +"Last-Translator: Mateo Tibaquirá \n" +"Language-Team: Spanish (Colombia) (http://www.transifex.com/odoo/odoo-9/language/es_CO/)\n" +"Language: es_CO\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "TOTAL" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "CHANGE" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Descuentos" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Subtotal" diff --git a/i18n/es_CR.po b/i18n/es_CR.po new file mode 100644 index 0000000..280c180 --- /dev/null +++ b/i18n/es_CR.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:37+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Spanish (Costa Rica) (http://www.transifex.com/odoo/odoo-9/language/es_CR/)\n" +"Language: es_CR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Subtotal" diff --git a/i18n/es_DO.po b/i18n/es_DO.po new file mode 100644 index 0000000..85d6601 --- /dev/null +++ b/i18n/es_DO.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Juliano Henriquez , 2016 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2016-05-19 05:09+0000\n" +"Last-Translator: Juliano Henriquez \n" +"Language-Team: Spanish (Dominican Republic) (http://www.transifex.com/odoo/odoo-9/language/es_DO/)\n" +"Language: es_DO\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "TOTAL" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "CAMBIO" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Descuentos" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Subtotal" diff --git a/i18n/es_EC.po b/i18n/es_EC.po new file mode 100644 index 0000000..a5bb564 --- /dev/null +++ b/i18n/es_EC.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Rick Hunter , 2015 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-12-07 04:23+0000\n" +"Last-Translator: Rick Hunter \n" +"Language-Team: Spanish (Ecuador) (http://www.transifex.com/odoo/odoo-9/language/es_EC/)\n" +"Language: es_EC\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "TOTAL" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "CAMBIO" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Descuentos" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Subtotal" diff --git a/i18n/es_PE.po b/i18n/es_PE.po new file mode 100644 index 0000000..913b413 --- /dev/null +++ b/i18n/es_PE.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Carlos Eduardo Rodriguez Rossi , 2016 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2016-06-13 15:49+0000\n" +"Last-Translator: Carlos Eduardo Rodriguez Rossi \n" +"Language-Team: Spanish (Peru) (http://www.transifex.com/odoo/odoo-9/language/es_PE/)\n" +"Language: es_PE\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "TOTAL" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "VUELTO" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Descuentos" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Subtotal" diff --git a/i18n/es_PY.po b/i18n/es_PY.po new file mode 100644 index 0000000..b7051ce --- /dev/null +++ b/i18n/es_PY.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:38+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Spanish (Paraguay) (http://www.transifex.com/odoo/odoo-9/language/es_PY/)\n" +"Language: es_PY\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Sub-Total" diff --git a/i18n/es_VE.po b/i18n/es_VE.po new file mode 100644 index 0000000..c757eee --- /dev/null +++ b/i18n/es_VE.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:38+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Spanish (Venezuela) (http://www.transifex.com/odoo/odoo-9/language/es_VE/)\n" +"Language: es_VE\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Subtotal" diff --git a/i18n/et.po b/i18n/et.po new file mode 100644 index 0000000..3a9cb2f --- /dev/null +++ b/i18n/et.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:36+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Estonian (http://www.transifex.com/odoo/odoo-9/language/et/)\n" +"Language: et\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Soodustused" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Vahesumma" diff --git a/i18n/eu.po b/i18n/eu.po new file mode 100644 index 0000000..d5e22d4 --- /dev/null +++ b/i18n/eu.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-10-21 11:17+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Basque (http://www.transifex.com/odoo/odoo-9/language/eu/)\n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Deskontuak" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Batura partziala" diff --git a/i18n/fa.po b/i18n/fa.po new file mode 100644 index 0000000..345c2a9 --- /dev/null +++ b/i18n/fa.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:37+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Persian (http://www.transifex.com/odoo/odoo-9/language/fa/)\n" +"Language: fa\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "جمع جزء" diff --git a/i18n/fi.po b/i18n/fi.po new file mode 100644 index 0000000..f3d2e5d --- /dev/null +++ b/i18n/fi.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Tuomo Aura , 2016 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2016-04-19 15:31+0000\n" +"Last-Translator: Tuomo Aura \n" +"Language-Team: Finnish (http://www.transifex.com/odoo/odoo-9/language/fi/)\n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "YHTEENSÄ" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "TAKAISIN" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Alennukset" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Välisumma" diff --git a/i18n/fr.po b/i18n/fr.po new file mode 100644 index 0000000..7fa051c --- /dev/null +++ b/i18n/fr.po @@ -0,0 +1,45 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Lucas Deliege , 2015 +# Maxime Chambreuil , 2015 +# Sylvain GROS-DESORMEAUX , 2015 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-10-01 23:16+0000\n" +"Last-Translator: Maxime Chambreuil \n" +"Language-Team: French (http://www.transifex.com/odoo/odoo-9/language/fr/)\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "TOTAL" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "MONNAIE" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Remises" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Sous-total" diff --git a/i18n/gu.po b/i18n/gu.po new file mode 100644 index 0000000..8fed0da --- /dev/null +++ b/i18n/gu.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Ranjit Pillai , 2015 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:36+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Gujarati (http://www.transifex.com/odoo/odoo-9/language/gu/)\n" +"Language: gu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "કુલ" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "ફેરફાર" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "ડિસ્કાઉન્ટ" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "" diff --git a/i18n/he.po b/i18n/he.po new file mode 100644 index 0000000..05ea1ed --- /dev/null +++ b/i18n/he.po @@ -0,0 +1,56 @@ +# #-#-#-#-# he.po (Odoo 9.0) #-#-#-#-# +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Moshe Fam , 2016 +# yizhaq agronov , 2016 +# #-#-#-#-# he.po (Odoo 9.0) #-#-#-#-# +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# yizhaq agronov , 2016 +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2016-02-27 04:30+0000\n" +"Last-Translator: yizhaq agronov \n" +"Language-Team: Hebrew (http://www.transifex.com/odoo/odoo-9/language/he/)\n" +"Language: he\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"#-#-#-#-# he.po (Odoo 9.0) #-#-#-#-#\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"#-#-#-#-# he.po (Odoo 9.0) #-#-#-#-#\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "סה\"כ" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "מזומן" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "הנחות" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "סיכום ביניים" diff --git a/i18n/hi.po b/i18n/hi.po new file mode 100644 index 0000000..4846b78 --- /dev/null +++ b/i18n/hi.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:36+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Hindi (http://www.transifex.com/odoo/odoo-9/language/hi/)\n" +"Language: hi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "उप कुल" diff --git a/i18n/hr.po b/i18n/hr.po new file mode 100644 index 0000000..6e4bc52 --- /dev/null +++ b/i18n/hr.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:35+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Croatian (http://www.transifex.com/odoo/odoo-9/language/hr/)\n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \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: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Popusti" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Podzbroj" diff --git a/i18n/hu.po b/i18n/hu.po new file mode 100644 index 0000000..58bf48d --- /dev/null +++ b/i18n/hu.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Kris Krnacs, 2015 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-11-11 22:25+0000\n" +"Last-Translator: Kris Krnacs\n" +"Language-Team: Hungarian (http://www.transifex.com/odoo/odoo-9/language/hu/)\n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr " ÖSSZESEN" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr " VISSZAJÁRÓ" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Árengedmények" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Nettó érték" diff --git a/i18n/hw_escpos.pot b/i18n/hw_escpos.pot new file mode 100644 index 0000000..6143656 --- /dev/null +++ b/i18n/hw_escpos.pot @@ -0,0 +1,41 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 14:39+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: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "" + diff --git a/i18n/id.po b/i18n/id.po new file mode 100644 index 0000000..7a75362 --- /dev/null +++ b/i18n/id.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:36+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Indonesian (http://www.transifex.com/odoo/odoo-9/language/id/)\n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Diskon" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Sub Total" diff --git a/i18n/it.po b/i18n/it.po new file mode 100644 index 0000000..ab7da93 --- /dev/null +++ b/i18n/it.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:36+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Italian (http://www.transifex.com/odoo/odoo-9/language/it/)\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Sconti" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Subtotale" diff --git a/i18n/ja.po b/i18n/ja.po new file mode 100644 index 0000000..a65f0d8 --- /dev/null +++ b/i18n/ja.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Yoshi Tashiro , 2016 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2016-07-14 08:45+0000\n" +"Last-Translator: Yoshi Tashiro \n" +"Language-Team: Japanese (http://www.transifex.com/odoo/odoo-9/language/ja/)\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "値引" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "小計" diff --git a/i18n/kab.po b/i18n/kab.po new file mode 100644 index 0000000..d614439 --- /dev/null +++ b/i18n/kab.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:36+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Kabyle (http://www.transifex.com/odoo/odoo-9/language/kab/)\n" +"Language: kab\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Tuǧǧiyin" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Ad-asemday" diff --git a/i18n/ko.po b/i18n/ko.po new file mode 100644 index 0000000..a153a8a --- /dev/null +++ b/i18n/ko.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:36+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Korean (http://www.transifex.com/odoo/odoo-9/language/ko/)\n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "할인" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "소계" diff --git a/i18n/lt.po b/i18n/lt.po new file mode 100644 index 0000000..da572d6 --- /dev/null +++ b/i18n/lt.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:37+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Lithuanian (http://www.transifex.com/odoo/odoo-9/language/lt/)\n" +"Language: lt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Nuolaidos" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Suma" diff --git a/i18n/lv.po b/i18n/lv.po new file mode 100644 index 0000000..8a14cf7 --- /dev/null +++ b/i18n/lv.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:36+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Latvian (http://www.transifex.com/odoo/odoo-9/language/lv/)\n" +"Language: lv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Apakšsumma kopā" diff --git a/i18n/mk.po b/i18n/mk.po new file mode 100644 index 0000000..0974bb2 --- /dev/null +++ b/i18n/mk.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Aleksandar Vangelovski , 2016 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2016-06-10 12:29+0000\n" +"Last-Translator: Aleksandar Vangelovski \n" +"Language-Team: Macedonian (http://www.transifex.com/odoo/odoo-9/language/mk/)\n" +"Language: mk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "ВКУПНО" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Попусти" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Вкупно" diff --git a/i18n/mn.po b/i18n/mn.po new file mode 100644 index 0000000..9f05131 --- /dev/null +++ b/i18n/mn.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:37+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Mongolian (http://www.transifex.com/odoo/odoo-9/language/mn/)\n" +"Language: mn\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Дэд дүн" diff --git a/i18n/nb.po b/i18n/nb.po new file mode 100644 index 0000000..4f50bb5 --- /dev/null +++ b/i18n/nb.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:37+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Norwegian Bokmål (http://www.transifex.com/odoo/odoo-9/language/nb/)\n" +"Language: nb\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Subtotal" diff --git a/i18n/nl.po b/i18n/nl.po new file mode 100644 index 0000000..a3fee47 --- /dev/null +++ b/i18n/nl.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Yenthe Van Ginneken , 2015 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-10 07:35+0000\n" +"Last-Translator: Yenthe Van Ginneken \n" +"Language-Team: Dutch (http://www.transifex.com/odoo/odoo-9/language/nl/)\n" +"Language: nl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "TOTAAL" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "WISSELGELD" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Kortingen" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Subtotaal" diff --git a/i18n/pl.po b/i18n/pl.po new file mode 100644 index 0000000..6815081 --- /dev/null +++ b/i18n/pl.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Piotr Szlązak , 2016 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2016-06-09 07:31+0000\n" +"Last-Translator: Piotr Szlązak \n" +"Language-Team: Polish (http://www.transifex.com/odoo/odoo-9/language/pl/)\n" +"Language: pl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "SUMA" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "ZMIANA" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Upusty" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Suma częściowa" diff --git a/i18n/pt.po b/i18n/pt.po new file mode 100644 index 0000000..d3d3b4e --- /dev/null +++ b/i18n/pt.po @@ -0,0 +1,54 @@ +# #-#-#-#-# pt.po (Odoo 9.0) #-#-#-#-# +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Dawilson Daio , 2016 +# #-#-#-#-# pt.po (Odoo 9.0) #-#-#-#-# +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:37+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Portuguese (http://www.transifex.com/odoo/odoo-9/language/pt/)\n" +"Language: pt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"#-#-#-#-# pt.po (Odoo 9.0) #-#-#-#-#\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"#-#-#-#-# pt.po (Odoo 9.0) #-#-#-#-#\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "TOTAL" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "TROCO" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Descontos:" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Subtotal" diff --git a/i18n/pt_BR.po b/i18n/pt_BR.po new file mode 100644 index 0000000..80f0110 --- /dev/null +++ b/i18n/pt_BR.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Grazziano Duarte , 2015 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-12-08 15:29+0000\n" +"Last-Translator: Grazziano Duarte \n" +"Language-Team: Portuguese (Brazil) (http://www.transifex.com/odoo/odoo-9/language/pt_BR/)\n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr " TOTAL" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "ALTERAR" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Descontos" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Subtotal" diff --git a/i18n/ro.po b/i18n/ro.po new file mode 100644 index 0000000..f0875c4 --- /dev/null +++ b/i18n/ro.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Sorin Trifu , 2015 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-10-20 07:19+0000\n" +"Last-Translator: Sorin Trifu \n" +"Language-Team: Romanian (http://www.transifex.com/odoo/odoo-9/language/ro/)\n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "TOTAL" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "REST" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Reduceri:" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Subtotal" diff --git a/i18n/ru.po b/i18n/ru.po new file mode 100644 index 0000000..56571e5 --- /dev/null +++ b/i18n/ru.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Gennady Marchenko , 2016 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2016-01-15 19:41+0000\n" +"Last-Translator: Gennady Marchenko \n" +"Language-Team: Russian (http://www.transifex.com/odoo/odoo-9/language/ru/)\n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \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: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "ИТОГО" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Скидки" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Подитог" diff --git a/i18n/sk.po b/i18n/sk.po new file mode 100644 index 0000000..026f091 --- /dev/null +++ b/i18n/sk.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Jaroslav Bosansky , 2016 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2016-01-29 22:54+0000\n" +"Last-Translator: Pavol Krnáč \n" +"Language-Team: Slovak (http://www.transifex.com/odoo/odoo-9/language/sk/)\n" +"Language: sk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "CELKOVO" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "VÝDAVOK" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Zľavy" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Medzisúčet" diff --git a/i18n/sl.po b/i18n/sl.po new file mode 100644 index 0000000..6595dfd --- /dev/null +++ b/i18n/sl.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:37+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Slovenian (http://www.transifex.com/odoo/odoo-9/language/sl/)\n" +"Language: sl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Popusti" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Skupaj" diff --git a/i18n/sq.po b/i18n/sq.po new file mode 100644 index 0000000..2919ed3 --- /dev/null +++ b/i18n/sq.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-08-25 10:14+0000\n" +"Last-Translator: <>\n" +"Language-Team: Albanian (http://www.transifex.com/odoo/odoo-9/language/sq/)\n" +"Language: sq\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Zbritjet" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "" diff --git a/i18n/sr.po b/i18n/sr.po new file mode 100644 index 0000000..e74ad48 --- /dev/null +++ b/i18n/sr.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:37+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Serbian (http://www.transifex.com/odoo/odoo-9/language/sr/)\n" +"Language: sr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \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: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Ukupno" diff --git a/i18n/sr@latin.po b/i18n/sr@latin.po new file mode 100644 index 0000000..6a06a31 --- /dev/null +++ b/i18n/sr@latin.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:37+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Serbian (Latin) (http://www.transifex.com/odoo/odoo-9/language/sr@latin/)\n" +"Language: sr@latin\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \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: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Ukupno" diff --git a/i18n/sv.po b/i18n/sv.po new file mode 100644 index 0000000..b994ad1 --- /dev/null +++ b/i18n/sv.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Kristoffer Grundström , 2015 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:38+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Swedish (http://www.transifex.com/odoo/odoo-9/language/sv/)\n" +"Language: sv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "TOTAL" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "FÖRÄNDRING" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Deltotal" diff --git a/i18n/th.po b/i18n/th.po new file mode 100644 index 0000000..c40ab55 --- /dev/null +++ b/i18n/th.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Khwunchai Jaengsawang , 2016 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2016-03-30 21:40+0000\n" +"Last-Translator: Khwunchai Jaengsawang \n" +"Language-Team: Thai (http://www.transifex.com/odoo/odoo-9/language/th/)\n" +"Language: th\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "ทั้งหมด" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "เปลี่ยนแปลง" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "ลดราคา" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "รวม" diff --git a/i18n/tr.po b/i18n/tr.po new file mode 100644 index 0000000..4a4cb63 --- /dev/null +++ b/i18n/tr.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Ramiz Deniz Öner , 2016 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2016-03-01 11:32+0000\n" +"Last-Translator: Ramiz Deniz Öner \n" +"Language-Team: Turkish (http://www.transifex.com/odoo/odoo-9/language/tr/)\n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "TOPLAM" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "DEĞİŞTİR" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "İndirimler" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Ara Toplam" diff --git a/i18n/uk.po b/i18n/uk.po new file mode 100644 index 0000000..df13644 --- /dev/null +++ b/i18n/uk.po @@ -0,0 +1,44 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# Bohdan Lisnenko, 2015 +# Bohdan Lisnenko, 2016 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2016-04-27 16:53+0000\n" +"Last-Translator: Bohdan Lisnenko\n" +"Language-Team: Ukrainian (http://www.transifex.com/odoo/odoo-9/language/uk/)\n" +"Language: uk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \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: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "РАЗОМ" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "Знижки" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Підсумок" diff --git a/i18n/vi.po b/i18n/vi.po new file mode 100644 index 0000000..593b94a --- /dev/null +++ b/i18n/vi.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:38+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Vietnamese (http://www.transifex.com/odoo/odoo-9/language/vi/)\n" +"Language: vi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "Tổng phụ" diff --git a/i18n/zh_CN.po b/i18n/zh_CN.po new file mode 100644 index 0000000..56715c5 --- /dev/null +++ b/i18n/zh_CN.po @@ -0,0 +1,45 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +# fausthuang, 2016 +# jeffery9, 2015 +# 珠海-老天 , 2015 +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2016-01-11 20:15+0000\n" +"Last-Translator: fausthuang\n" +"Language-Team: Chinese (China) (http://www.transifex.com/odoo/odoo-9/language/zh_CN/)\n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "总计" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "找零" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "折扣" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "小计" diff --git a/i18n/zh_HK.po b/i18n/zh_HK.po new file mode 100644 index 0000000..9868d38 --- /dev/null +++ b/i18n/zh_HK.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:35+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Chinese (Hong Kong) (http://www.transifex.com/odoo/odoo-9/language/zh_HK/)\n" +"Language: zh_HK\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "小計" diff --git a/i18n/zh_TW.po b/i18n/zh_TW.po new file mode 100644 index 0000000..5579973 --- /dev/null +++ b/i18n/zh_TW.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hw_escpos +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Odoo 9.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-07 14:39+0000\n" +"PO-Revision-Date: 2015-09-07 21:35+0000\n" +"Last-Translator: Martin Trigaux\n" +"Language-Team: Chinese (Taiwan) (http://www.transifex.com/odoo/odoo-9/language/zh_TW/)\n" +"Language: zh_TW\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:302 +#, python-format +msgid " TOTAL" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:312 +#, python-format +msgid " CHANGE" +msgstr "" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:318 +#, python-format +msgid "Discounts" +msgstr "折扣" + +#. module: hw_escpos +#: code:addons/hw_escpos/controllers/main.py:293 +#, python-format +msgid "Subtotal" +msgstr "小計"