def test_bmp(self): """ test if the classmethods in bmp work """ bignum = 4321056789 fcd_seq = [0xf4, 0xf3, 0xf2, 0xf1, 0xf0, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9] self.assertEqual( BCD.encode_fcd(bignum), fcd_seq) self.assertEqual( BCD.decode_fcd(fcd_seq), bignum)
def register(self, config_byte, **kwargs): """ registers this ECR at the PT, locking menus for real world conditions. """ kwargs = dict(kwargs) if self.password: kwargs['password'] = self.password if config_byte is not None: kwargs['config_byte'] = config_byte ret = self.transmit(Registration(**kwargs)) if ret == TRANSMIT_OK: # get the terminal-id if its there. for inc, packet in self.transmitter.last_history: if inc and isinstance(packet, Completion): if 'tid' in packet.bitmaps_as_dict().keys(): self.terminal_id = packet.bitmaps_as_dict()\ .get('tid', BCD(0)).value() # remember this. self._state_registered = True return ret
def get_end_of_day_information(self): """ if this status information is sent in an end of day cycle, it contains the end of day information, making it a type of subpacket of itself. @returns: a dictionary holding end-of-day information. - returns an empty dictionary if there is no total amount - returns total amount at least in key 'amount' - tries to decipher credit card data into following format: number-<creditcard>, turnover-<creditcard> creditcard being [ec-card, jcb, eurocard, amex, visa, diners, remaining] - receipt-number-start, receipt-number-end contain the range of receipts """ ret = {} # create a dictionary of bitmaps: bdict = self.bitmaps_as_dict() # at least amount should be present: if 'amount' not in bdict.keys(): return {} else: ret = { 'amount': int(bdict['amount'].value()), } # bitmap 0x60 (totals) contains the required information. # another bitmap (amount) holds the amount if 'totals' not in bdict.keys(): # this packet holds no detail information but an amount. return ret totals = bdict['totals'] totals_list = totals.value() # totals_list = str(bdict['totals']) # now we build our real data our of it. # rebuild date and time. my_time = None my_date = None if 'time' in bdict.keys(): # print bdict['time'].value() mt = str(bdict['time'].value()) my_time = datetime.time(hour=int(mt[0:2]), minute=int(mt[2:4]), second=int(mt[4:6])) if 'date_day' in bdict.keys(): # print bdict['date'].value() md = str(bdict['date_day'].value()) my_date = datetime.date(year=datetime.datetime.now().year, month=int(md[0:2]), day=int(md[2:4])) ret = { 'receipt-number-start': BCD.as_int(BCD.decode_bcd(totals_list[0:2])), 'receipt-number-end': BCD.as_int(BCD.decode_bcd(totals_list[2:4])), 'number-ec-card': bs2hl(totals_list[4])[0], 'turnover-ec-card': BCD.as_int(BCD.decode_bcd(totals_list[5:5 + 6])), 'number-jcb': bs2hl(totals_list[11])[0], 'turnover-jcb': BCD.as_int(BCD.decode_bcd(totals_list[12:12 + 6])), 'number-eurocard': bs2hl(totals_list[18])[0], 'turnover-eurocard': BCD.as_int(BCD.decode_bcd(totals_list[19:19 + 6])), 'number-amex': bs2hl(totals_list[25])[0], 'turnover-amex': BCD.as_int(BCD.decode_bcd(totals_list[26:26 + 6])), 'number-visa': bs2hl(totals_list[32])[0], 'turnover-visa': BCD.as_int(BCD.decode_bcd(totals_list[33:33 + 6])), 'number-diners': bs2hl(totals_list[39])[0], 'turnover-diners': BCD.as_int(BCD.decode_bcd(totals_list[40:40 + 6])), 'number-remaining': bs2hl(totals_list[46])[0], 'turnover-remaining': BCD.as_int(BCD.decode_bcd(totals_list[47:47 + 6])), 'amount': int(bdict['amount'].value()), 'turnover-amount': int(bdict['amount'].value()), 'date': my_date, 'time': my_time, 'number-total': 0, } # time holds simply HHMMSS (BCD) # date holds simply mmdd (BCD) # adding a formatted version tn = 0 float_version = {} for key, value in ret.items(): if key.startswith('turnover-'): key_id = key.replace('turnover-', '') # add a key with a formatted representation. v = float(value) / 100.0 float_version['float-%s' % key_id] = v elif key.startswith('number-'): # add total numbers. tn += int(value) ret['number-total'] = tn ret.update(float_version) return ret
def get_end_of_day_information(self): """ if this status information is sent in an end of day cycle, it contains the end of day information, making it a type of subpacket of itself. @returns: a dictionary holding end-of-day information. - returns an empty dictionary if there is no total amount - returns total amount at least in key 'amount' - tries to decipher credit card data into following format: number-<creditcard>, turnover-<creditcard> creditcard being [ec-card, jcb, eurocard, amex, visa, diners, remaining] - receipt-number-start, receipt-number-end contain the range of receipts """ ret = {} # create a dictionary of bitmaps: bdict = self.bitmaps_as_dict() # at least amount should be present: if not 'amount' in bdict.keys(): return {} else: ret = {'amount': int(bdict['amount'].value()),} # bitmap 0x60 (totals) contains the required information. # another bitmap (amount) holds the amount if not 'totals' in bdict.keys(): # this packet holds no detail information but an amount. return ret totals = bdict['totals'] totals_list = totals.value() #totals_list = str(bdict['totals']) # now we build our real data our of it. # rebuild date and time. my_time = None my_date = None if 'time' in bdict.keys(): #print bdict['time'].value() mt = str(bdict['time'].value()) my_time = datetime.time( hour=int(mt[0:2]), minute=int(mt[2:4]), second=int(mt[4:6]), ) if 'date_day' in bdict.keys(): #print bdict['date'].value() md = str(bdict['date_day'].value()) my_date = datetime.date( year=datetime.datetime.now().year, month=int(md[0:2]), day=int(md[2:4]), ) ret = {'receipt-number-start': BCD.as_int( BCD.decode_bcd( totals_list[0:2] ) ), 'receipt-number-end': BCD.as_int( BCD.decode_bcd( totals_list[2:4] ) ), 'number-ec-card': conv.bs2hl( totals_list[4] )[0], 'turnover-ec-card': BCD.as_int( BCD.decode_bcd( totals_list[5:5+6] ) ), 'number-jcb': conv.bs2hl(totals_list[11])[0], 'turnover-jcb': BCD.as_int( BCD.decode_bcd( totals_list[12:12+6] ) ), 'number-eurocard': conv.bs2hl(totals_list[18])[0], 'turnover-eurocard': BCD.as_int( BCD.decode_bcd( totals_list[19:19+6] ) ), 'number-amex': conv.bs2hl(totals_list[25])[0], 'turnover-amex': BCD.as_int( BCD.decode_bcd( totals_list[26:26+6] ) ), 'number-visa': conv.bs2hl(totals_list[32])[0], 'turnover-visa': BCD.as_int( BCD.decode_bcd( totals_list[33:33+6] ) ), 'number-diners': conv.bs2hl(totals_list[39])[0], 'turnover-diners': BCD.as_int( BCD.decode_bcd( totals_list[40:40+6] ) ), 'number-remaining': conv.bs2hl(totals_list[46])[0], 'turnover-remaining': BCD.as_int( BCD.decode_bcd( totals_list[47:47+6] ) ), 'amount': int(bdict['amount'].value()), 'turnover-amount': int(bdict['amount'].value()), 'date': my_date, 'time': my_time, 'number-total': 0, } # time holds simply HHMMSS (BCD) # date holds simply mmdd (BCD) # adding a formatted version tn = 0 for key, value in ret.items(): if key.startswith('turnover-'): key_id = key.replace('turnover-', '') # add a key with a formatted representation. v = float(value) / 100.0 ret['float-%s' % key_id] = v elif key.startswith('number-'): # add total numbers. tn += int(value) ret['number-total'] = tn return ret
def test_bcd(self): """ small test for bcds """ n1, n2 = 4, 5 bcd_n = 0x45 # bcd_split should create two numbers out of bcd. self.assertEqual(BCD.bcd_split(bcd_n), (n1, n2)) # bcd unite however should create one bcd byte out of two numbers self.assertEqual(BCD.bcd_unite((n1, n2)), bcd_n) # now test the full ones password = '******' bcd_pass = [0x12, 0x34, 0x56] password_nums = [int(x) for x in password] self.assertEqual(BCD.encode_bcd(password), bcd_pass) self.assertEqual(BCD.decode_bcd(bcd_pass), password_nums) # test instantiation: b = BCD(password) b._length = 3 # print b.values() self.assertEqual(b.value(), password) # test dumping b = BCD(1) b._length = 3 b._id = 666 # this is actually impossible, but manually valid. d = b.dump() self.assertEqual(d, [666, 0, 0, 1])