# Path: stoqdrivers/exceptions.py
# class CloseCouponError(DriverError):
#     "Could not close the coupon."
# 
# class PaymentAdditionError(DriverError):
#     "Error while adding a payment."
# 
# class AlreadyTotalized(DriverError):
#     "The coupon is already totalized"
# 
# class InvalidValue(DriverError):
#     "The value specified is invalid or is not in the expected range"
# 
# Path: stoqdrivers/enum.py
# class TaxType(IntEnum):
#     """
#     Enum for taxes
#     """
#     (ICMS,
#      SUBSTITUTION,
#      EXEMPTION,
#      NONE,
#      SERVICE,
#      CUSTOM) = range(40, 46)
# 
# class UnitType(IntEnum):
#     """
#     Enum for units
#     """
#     (WEIGHT,
#      METERS,
#      LITERS,
#      EMPTY,
#      CUSTOM) = range(20, 25)
# 
# Path: stoqdrivers/printers/base.py
# class BasePrinter(BaseDevice):
#     device_dirname = "printers"
#     device_type = DeviceType.PRINTER
# 
#     def check_interfaces(self):
#         driver_interfaces = providedBy(self._driver)
#         if (ICouponPrinter not in driver_interfaces
#                 and IChequePrinter not in driver_interfaces
#                 and INonFiscalPrinter not in driver_interfaces):
#             raise TypeError("The driver `%r' doesn't implements a valid "
#                             "interface" % self._driver)
# 
#     def get_constants(self):
#         return self._driver.get_constants()
# 
#     def get_tax_constant(self, item):
#         for enum, constant, value in self.get_tax_constants():
#             if enum == item:
#                 return constant
# 
#     def get_model_name(self):
#         return self._driver.model_name
# 
# Path: stoqdrivers/utils.py
# def encode_text(text, encoding):
#     """ Converts the string 'text' to encoding 'encoding' and optionally
#     normalizes the string (currently only for ascii)
# 
#     @param text:       text to convert
#     @type text:        str
#     @param encoding:   encoding to use
#     @type text:        str
#     @returns:          converted text
#     """
#     if encoding == "ascii":
#         text = unicodedata.normalize("NFKD", text)
#     # If we use text.encode we will get this sometimes:
#     # TypeError: 'abicomp' encoder returned 'str' instead of 'bytes';
#     #   use codecs.encode() to encode to arbitrary types
#     text = codecs.encode(text, encoding, "ignore")
#     # Only do the bellow conversion if the encoding above worked
#     if isinstance(text, bytes):
#         # Use bytes2str instead of decode or otherwise we would encode
#         # the bytes in unicode. This way we will still keep them in the
#         # encoding that we want (since SerialBase.write will do the reversal
#         # operation, str2bytes) even though we will get some strange
#         # characters in the "unicode version" of the string
#         text = bytes2str(text)
#     return text
# 
# Path: stoqdrivers/translation.py
# def stoqdrivers_gettext(message):
#     return gettext.dgettext('stoqdrivers', message)


from collections import namedtuple
from decimal import Decimal
from numbers import Real
from stoqdrivers.exceptions import (CloseCouponError, PaymentAdditionError,
                                    AlreadyTotalized, InvalidValue)
from stoqdrivers.enum import TaxType, UnitType
from stoqdrivers.printers.base import BasePrinter
from stoqdrivers.utils import encode_text
from stoqdrivers.translation import stoqdrivers_gettext
import datetime
import logging
import traceback
import sys
    def _format_text(self, text):
        return encode_text(text, self._charset)

    def setup(self):
        log.info('setup()')
        self._driver.setup()

    def identify_customer(self, customer_name: str, customer_address: str, customer_id: str):
        log.info('identify_customer(customer_name=%r, '
                 'customer_address=%r, customer_id=%r)' % (
                     customer_name, customer_address, customer_id))

        self._driver.coupon_identify_customer(
            self._format_text(customer_name),
            self._format_text(customer_address),
            self._format_text(customer_id))

    def coupon_is_customer_identified(self):
        return self._driver.coupon_is_customer_identified()

    def has_open_coupon(self):
        log.info('has_open_coupon()')
        return self._driver.has_open_coupon()

    def open(self):
        log.info('coupon_open()')

        return self._driver.coupon_open()

    def add_item(self, item_code: str, item_description: str, item_price: Real, taxcode: TaxType,

# Path: stoqdrivers/exceptions.py
# class CloseCouponError(DriverError):
#     "Could not close the coupon."
# 
# class PaymentAdditionError(DriverError):
#     "Error while adding a payment."
# 
# class AlreadyTotalized(DriverError):
#     "The coupon is already totalized"
# 
# class InvalidValue(DriverError):
#     "The value specified is invalid or is not in the expected range"
# 
# Path: stoqdrivers/enum.py
# class TaxType(IntEnum):
#     """
#     Enum for taxes
#     """
#     (ICMS,
#      SUBSTITUTION,
#      EXEMPTION,
#      NONE,
#      SERVICE,
#      CUSTOM) = range(40, 46)
# 
# class UnitType(IntEnum):
#     """
#     Enum for units
#     """
#     (WEIGHT,
#      METERS,
#      LITERS,
#      EMPTY,
#      CUSTOM) = range(20, 25)
# 
# Path: stoqdrivers/printers/base.py
# class BasePrinter(BaseDevice):
#     device_dirname = "printers"
#     device_type = DeviceType.PRINTER
# 
#     def check_interfaces(self):
#         driver_interfaces = providedBy(self._driver)
#         if (ICouponPrinter not in driver_interfaces
#                 and IChequePrinter not in driver_interfaces
#                 and INonFiscalPrinter not in driver_interfaces):
#             raise TypeError("The driver `%r' doesn't implements a valid "
#                             "interface" % self._driver)
# 
#     def get_constants(self):
#         return self._driver.get_constants()
# 
#     def get_tax_constant(self, item):
#         for enum, constant, value in self.get_tax_constants():
#             if enum == item:
#                 return constant
# 
#     def get_model_name(self):
#         return self._driver.model_name
# 
# Path: stoqdrivers/utils.py
# def encode_text(text, encoding):
#     """ Converts the string 'text' to encoding 'encoding' and optionally
#     normalizes the string (currently only for ascii)
# 
#     @param text:       text to convert
#     @type text:        str
#     @param encoding:   encoding to use
#     @type text:        str
#     @returns:          converted text
#     """
#     if encoding == "ascii":
#         text = unicodedata.normalize("NFKD", text)
#     # If we use text.encode we will get this sometimes:
#     # TypeError: 'abicomp' encoder returned 'str' instead of 'bytes';
#     #   use codecs.encode() to encode to arbitrary types
#     text = codecs.encode(text, encoding, "ignore")
#     # Only do the bellow conversion if the encoding above worked
#     if isinstance(text, bytes):
#         # Use bytes2str instead of decode or otherwise we would encode
#         # the bytes in unicode. This way we will still keep them in the
#         # encoding that we want (since SerialBase.write will do the reversal
#         # operation, str2bytes) even though we will get some strange
#         # characters in the "unicode version" of the string
#         text = bytes2str(text)
#     return text
# 
# Path: stoqdrivers/translation.py
# def stoqdrivers_gettext(message):
#     return gettext.dgettext('stoqdrivers', message)


# Path: stoqdrivers/printers/fiscal.py
from collections import namedtuple
from decimal import Decimal
from numbers import Real
from stoqdrivers.exceptions import (CloseCouponError, PaymentAdditionError,
                                    AlreadyTotalized, InvalidValue)
from stoqdrivers.enum import TaxType, UnitType
from stoqdrivers.printers.base import BasePrinter
from stoqdrivers.utils import encode_text
from stoqdrivers.translation import stoqdrivers_gettext
import datetime
import logging
import traceback
import sys

    def _format_text(self, text):
        return encode_text(text, self._charset)

    def setup(self):
        log.info('setup()')
        self._driver.setup()

    def identify_customer(self, customer_name: str, customer_address: str, customer_id: str):
        log.info('identify_customer(customer_name=%r, '
                 'customer_address=%r, customer_id=%r)' % (
                     customer_name, customer_address, customer_id))

        self._driver.coupon_identify_customer(
            self._format_text(customer_name),
            self._format_text(customer_address),
            self._format_text(customer_id))

    def coupon_is_customer_identified(self):
        return self._driver.coupon_is_customer_identified()

    def has_open_coupon(self):
        log.info('has_open_coupon()')
        return self._driver.has_open_coupon()

    def open(self):
        log.info('coupon_open()')

        return self._driver.coupon_open()

    def add_item(self, item_code: str, item_description: str, item_price: Real, taxcode: TaxType,

                 items_quantity=Decimal("1.0"), unit=UnitType.EMPTY,