Esempio n. 1
0
    def get_tax_constants(self):
        status = self._read_register(self.registers.TOTALIZERS)
        status = struct.unpack('>H', str2bytes(status))[0]

        length, data = self._send_command(CMD_READ_TAXCODES, response='b32s')

        constants = []
        for i in range(16):
            value = bcd2dec(data[i * 2:i * 2 + 2])
            if not value:
                continue

            if 1 << 15 - i & status == 0:
                tax = TaxType.CUSTOM
            else:
                tax = TaxType.SERVICE
            constants.append((tax,
                              '%02d' % (i + 1,),
                              Decimal(value) / 100))

        constants.extend([
            (TaxType.SUBSTITUTION, 'FF', None),
            (TaxType.EXEMPTION, 'II', None),
            (TaxType.NONE, 'NN', None),
        ])

        return constants
Esempio n. 2
0
    def get_tax_constants(self):
        status = self._read_register(self.registers.TOTALIZERS)
        status = struct.unpack('>H', str2bytes(status))[0]

        length, data = self._send_command(CMD_READ_TAXCODES, response='b32s')

        constants = []
        for i in range(16):
            value = bcd2dec(data[i * 2:i * 2 + 2])
            if not value:
                continue

            if 1 << 15 - i & status == 0:
                tax = TaxType.CUSTOM
            else:
                tax = TaxType.SERVICE
            constants.append((tax, '%02d' % (i + 1, ), Decimal(value) / 100))

        constants.extend([
            (TaxType.SUBSTITUTION, 'FF', None),
            (TaxType.EXEMPTION, 'II', None),
            (TaxType.NONE, 'NN', None),
        ])

        return constants
Esempio n. 3
0
    def read(self, n_bytes):
        self._check_device()
        try:
            data = self.device.recv(n_bytes)
        except (ConnectionResetError, socket.timeout):
            raise PrinterError

        return str2bytes(data)
Esempio n. 4
0
    def write(self, data):
        """Write any data to the USB printer

        :param data: Any data to be written
        :type data: bytes
        """
        if not self.device:
            self.open()
        self.device.write(self.out_ep, str2bytes(data), self.timeout)
Esempio n. 5
0
    def write(self, data):
        """Write any data to the USB printer

        :param data: Any data to be written
        :type data: bytes
        """
        if not self.device:
            self.open()
        self.device.write(self.out_ep, str2bytes(data), self.timeout)
Esempio n. 6
0
    def __init__(self, string, command_id):
        checksum = string[-4:]
        self.string = string[:-4]

        log.debug('reply %s' % repr(string))
        cs = '%04X' % sum([ord(i) for i in self.string])
        if cs != checksum:
            raise DriverError('Erro de checksum')

        self.string = unescape(self.string)

        # Verifica header & tail
        assert self.pop() == STX, 'STX'
        frame_id = self.pop()
        if frame_id == '\x80':
            self.intermediate = True
            return

        self.intermediate = False
        assert frame_id == chr(command_id), ('command_id', command_id)
        assert self.string[-1] == ETX, 'ETX'

        # Retira statuses
        self.printer_status = struct.unpack('>H', str2bytes(self.pop(2)))[0]
        assert self.pop() == FLD, 'FLD 1'
        self.fiscal_status = struct.unpack('>H', str2bytes(self.pop(2)))[0]
        assert self.pop() == FLD, 'FLD 2'

        # reserved
        self.pop()

        r = self.pop(2)
        self.reply_status = '%02X%02X' % (ord(r[0]), ord(r[1]))

        assert self.pop() == FLD, 'FLD 3'
        # reserved
        self.pop()

        # Pega dados de retorno

        fields = self.string[:-1]

        # FIXME: Maybe we need to de-escape the string
        self.fields = fields.split(FLD)
Esempio n. 7
0
    def __init__(self, string, command_id):
        checksum = string[-4:]
        self.string = string[:-4]

        log.debug('reply %s' % repr(string))
        cs = '%04X' % sum([ord(i) for i in self.string])
        if cs != checksum:
            raise DriverError('Erro de checksum')

        self.string = unescape(self.string)

        # Verifica header & tail
        assert self.pop() == STX, 'STX'
        frame_id = self.pop()
        if frame_id == '\x80':
            self.intermediate = True
            return

        self.intermediate = False
        assert frame_id == chr(command_id), ('command_id', command_id)
        assert self.string[-1] == ETX, 'ETX'

        # Retira statuses
        self.printer_status = struct.unpack('>H', str2bytes(self.pop(2)))[0]
        assert self.pop() == FLD, 'FLD 1'
        self.fiscal_status = struct.unpack('>H', str2bytes(self.pop(2)))[0]
        assert self.pop() == FLD, 'FLD 2'

        # reserved
        self.pop()

        r = self.pop(2)
        self.reply_status = '%02X%02X' % (ord(r[0]), ord(r[1]))

        assert self.pop() == FLD, 'FLD 3'
        # reserved
        self.pop()

        # Pega dados de retorno

        fields = self.string[:-1]

        # FIXME: Maybe we need to de-escape the string
        self.fields = fields.split(FLD)
Esempio n. 8
0
    def get_sintegra(self):
        opening_date = self._read_register(self.registers.EMISSION_DATE)
        cro = self._read_register(self.registers.CRO)
        # FIXME: This is being fetched before the actual reduction, so the value will be wrong by
        # -1
        crz = self._read_register(self.registers.NUMBER_REDUCTIONS_Z)
        coo = self._get_coupon_number()
        total_cancelations = self._read_register(
            self.registers.TOTAL_CANCELATIONS)
        total_discount = self._read_register(self.registers.TOTAL_DISCOUNT)

        # Avbr function TACBrECFBematech.GetVendaBruta
        registers = self._send_command(62, 55, response='308s')
        coupon_end = int(bcd2hex(registers)[568:568 + 6])

        grande_total = self._read_register(self.registers.TOTAL)
        grande_total = grande_total / Decimal(100)
        total_bruto = bcd2dec(registers[1:10]) / Decimal(100)

        length, names = self._send_command(CMD_READ_TAXCODES, response='b32s')
        status = self._read_register(self.registers.TOTALIZERS)
        status = struct.unpack('>H', str2bytes(status))[0]
        values = self._send_command(CMD_READ_TOTALIZERS, response='219s')

        taxes = []
        for i in range(length):
            if 1 << 15 - i & status != 0:
                type = 'ISS'
            else:
                type = 'ICMS'

            name = bcd2hex(names[i * 2:i * 2 + 2])
            value = bcd2dec(values[i * 7:i * 7 + 7])
            taxes.append((name, value / Decimal(100), type))

        taxes.append(('CANC', total_cancelations / Decimal(100), 'ICMS'))
        taxes.append(('DESC', total_discount / Decimal(100), 'ICMS'))
        taxes.append(('I', bcd2dec(values[112:119]) / Decimal(100), 'ICMS'))
        taxes.append(('N', bcd2dec(values[119:126]) / Decimal(100), 'ICMS'))
        taxes.append(('F', bcd2dec(values[126:133]) / Decimal(100), 'ICMS'))
        date = bcd2hex(opening_date[:6])

        return Settable(opening_date=datetime.date(year=2000 + int(date[4:6]),
                                                   month=int(date[2:4]),
                                                   day=int(date[:2])),
                        serial=self.get_serial(),
                        serial_id='%03d' %
                        self._read_register(self.registers.NUMBER_TILL),
                        coupon_start=0,
                        coupon_end=coupon_end,
                        cro=cro,
                        crz=crz,
                        coo=coo,
                        period_total=grande_total - total_bruto,
                        total=grande_total,
                        taxes=taxes)
Esempio n. 9
0
    def get_sintegra(self):
        opening_date = self._read_register(self.registers.EMISSION_DATE)
        cro = self._read_register(self.registers.CRO)
        # FIXME: This is being fetched before the actual reduction, so the value will be wrong by
        # -1
        crz = self._read_register(self.registers.NUMBER_REDUCTIONS_Z)
        coo = self._get_coupon_number()
        total_cancelations = self._read_register(self.registers.TOTAL_CANCELATIONS)
        total_discount = self._read_register(self.registers.TOTAL_DISCOUNT)

        # Avbr function TACBrECFBematech.GetVendaBruta
        registers = self._send_command(62, 55, response='308s')
        coupon_end = int(bcd2hex(registers)[568:568 + 6])

        grande_total = self._read_register(self.registers.TOTAL)
        grande_total = grande_total / Decimal(100)
        total_bruto = bcd2dec(registers[1:10]) / Decimal(100)

        length, names = self._send_command(CMD_READ_TAXCODES, response='b32s')
        status = self._read_register(self.registers.TOTALIZERS)
        status = struct.unpack('>H', str2bytes(status))[0]
        values = self._send_command(CMD_READ_TOTALIZERS, response='219s')

        taxes = []
        for i in range(length):
            if 1 << 15 - i & status != 0:
                type = 'ISS'
            else:
                type = 'ICMS'

            name = bcd2hex(names[i * 2:i * 2 + 2])
            value = bcd2dec(values[i * 7:i * 7 + 7])
            taxes.append((name, value / Decimal(100), type))

        taxes.append(('CANC', total_cancelations / Decimal(100), 'ICMS'))
        taxes.append(('DESC', total_discount / Decimal(100), 'ICMS'))
        taxes.append(('I', bcd2dec(values[112:119]) / Decimal(100), 'ICMS'))
        taxes.append(('N', bcd2dec(values[119:126]) / Decimal(100), 'ICMS'))
        taxes.append(('F', bcd2dec(values[126:133]) / Decimal(100), 'ICMS'))
        date = bcd2hex(opening_date[:6])

        return Settable(
            opening_date=datetime.date(year=2000 + int(date[4:6]),
                                       month=int(date[2:4]),
                                       day=int(date[:2])),
            serial=self.get_serial(),
            serial_id='%03d' % self._read_register(self.registers.NUMBER_TILL),
            coupon_start=0,
            coupon_end=coupon_end,
            cro=cro,
            crz=crz,
            coo=coo,
            period_total=grande_total - total_bruto,
            total=grande_total,
            taxes=taxes)
Esempio n. 10
0
    def _create_packet(self, command):
        """
        Create a 'pre-package' (command + params, basically) and involves
        it around STX, NB and CS::
           1     2           n           2
        +-----+------+-----------------+----+
        | STX |  NB  | 0x1C + command  | CS |
        +-----+------+-----------------+----+

        Where:

        STX: 'Transmission Start' indicator byte
        NB: 2 bytes, big endian length of command + CS (2 bytes)
        CS: 2 bytes, big endian checksum for command
        """

        command = chr(self.CMD_PROTO) + command
        packet = struct.pack('<bH%dsH' % len(command), STX,
                             len(command) + 2, str2bytes(command),
                             sum([ord(i) for i in command]))
        return bytes2str(packet)
Esempio n. 11
0
    def _send_command(self, command, *args, **kwargs):
        fmt = ''
        if 'response' in kwargs:
            fmt = kwargs.pop('response')

        raw = False
        if 'raw' in kwargs:
            raw = kwargs.pop('raw')

        if kwargs:
            raise TypeError("Invalid kwargs: %r" % (kwargs,))

        cmd = chr(command)
        for arg in args:
            if isinstance(arg, int):
                cmd += chr(arg)
            elif isinstance(arg, str):
                cmd += arg
            else:
                raise NotImplementedError(type(arg))

        data = self._create_packet(cmd)
        self.write(data)

        format = self.reply_format % fmt
        reply = self._read_reply(struct.calcsize(format))
        retval = _rbytes2str(struct.unpack(format, str2bytes(reply)))

        if raw:
            return retval

        self._check_error(retval)

        response = retval[1:-self.status_size]
        if len(response) == 1:
            response = response[0]
        return response
Esempio n. 12
0
    def _send_command(self, command, *args, **kwargs):
        fmt = ''
        if 'response' in kwargs:
            fmt = kwargs.pop('response')

        raw = False
        if 'raw' in kwargs:
            raw = kwargs.pop('raw')

        if kwargs:
            raise TypeError("Invalid kwargs: %r" % (kwargs, ))

        cmd = chr(command)
        for arg in args:
            if isinstance(arg, int):
                cmd += chr(arg)
            elif isinstance(arg, str):
                cmd += arg
            else:
                raise NotImplementedError(type(arg))

        data = self._create_packet(cmd)
        self.write(data)

        format = self.reply_format % fmt
        reply = self._read_reply(struct.calcsize(format))
        retval = _rbytes2str(struct.unpack(format, str2bytes(reply)))

        if raw:
            return retval

        self._check_error(retval)

        response = retval[1:-self.status_size]
        if len(response) == 1:
            response = response[0]
        return response
Esempio n. 13
0
    def _create_packet(self, command):
        """
        Create a 'pre-package' (command + params, basically) and involves
        it around STX, NB and CS::
           1     2           n           2
        +-----+------+-----------------+----+
        | STX |  NB  | 0x1C + command  | CS |
        +-----+------+-----------------+----+

        Where:

        STX: 'Transmission Start' indicator byte
        NB: 2 bytes, big endian length of command + CS (2 bytes)
        CS: 2 bytes, big endian checksum for command
        """

        command = chr(self.CMD_PROTO) + command
        packet = struct.pack(
            '<bH%dsH' % len(command),
            STX,
            len(command) + 2,
            str2bytes(command),
            sum([ord(i) for i in command]))
        return bytes2str(packet)
Esempio n. 14
0
 def write(self, data):
     # pyserial is expecting bytes but we work with str in stoqdrivers
     data = str2bytes(data)
     log.debug(">>> %r (%d bytes)" % (data, len(data)))
     self._port.write(data)