Compare commits

..

No commits in common. "py3" and "revert-6-preAuth" have entirely different histories.

2 changed files with 30 additions and 243 deletions

View file

@ -16,7 +16,7 @@ from ecrterm.exceptions import (
from ecrterm.packets.base_packets import (
Authorisation, CloseCardSession, Completion, DisplayText, EndOfDay, Packet,
PrintLine, ReadCard, Registration, ResetTerminal, StatusEnquiry,
StatusInformation, WriteFiles, PreAuthorisation, PartialCancellation, LogOff, Reversal)
StatusInformation, WriteFiles)
from ecrterm.packets.types import ConfigByte
from ecrterm.transmission._transmission import Transmission
from ecrterm.transmission.signals import ACK, DLE, ETX, NAK, STX, TRANSMIT_OK
@ -252,90 +252,6 @@ class ECR(object):
logger.error("transmit error?")
return False
def preauthorisation(self, amount_cent=50, listener=None):
"""
executes a preauthorisation in amount of cents.
@returns: Receipt Number, if preAuthorisation was successful, or False if it was
canceled.
throws exceptions.
"""
packet = PreAuthorisation(
amount=amount_cent, # in cents.
currency_code=978, # euro, only one that works, can be skipped.
tlv=[],
)
if listener:
packet.register_response_listener(listener)
code = self.transmit(packet=packet)
if code == 0:
# now check if the packet actually got what it wanted.
for entry in self.transmitter.last_history:
inc, paket = entry
if inc and isinstance(paket, StatusInformation):
return paket.get_receipt_number()
return False
else:
# @todo: remove this.
logger.error("transmit error?")
return False
def reversal(self, receipt, listener=None):
"""
reverts a transaction
@param receipt is the receipt number of the initial transaction
@returns True if Transaction was Reverted
throws exceptions
"""
packet = Reversal(
password=self.password,
receipt=receipt,
)
if listener:
packet.register_response_listener(listener)
code = self.transmit(packet=packet)
if code == 0:
# now check if the packet actually got what it wanted.
if self.transmitter.last.completion:
if isinstance(self.transmitter.last.completion, Completion):
return True
else:
return False
else:
# @todo: remove this.
logger.error("transmit error?")
return False
def partialcancellation(self, receipt=None, amount_cent=50, listener=None):
"""
executes a preauthorisation in amount of cents.
@returns: Receipt Number, if preAuthorisation was successful, or False if it was
canceled.
throws exceptions.
"""
packet = PartialCancellation(
receipt=receipt,
amount=amount_cent, # in cents.
currency_code=978, # euro, only one that works, can be skipped.
tlv=[],
)
if listener:
packet.register_response_listener(listener)
code = self.transmit(packet=packet)
if code == 0:
# now check if the packet actually got what it wanted.
if self.transmitter.last.completion:
if isinstance(self.transmitter.last.completion, Completion):
return True
else:
return False
else:
# @todo: remove this.
logger.error("transmit error?")
return False
def restart(self):
"""Restarts/resets the PT."""
self._state_registered = False
@ -354,11 +270,6 @@ class ECR(object):
sleep(1)
return ret
def logoff(self):
"""Log off the PT."""
self._state_registered = False
return self.transmit(LogOff())
def show_text(self, lines=None, duration=5, beeps=0):
"""
displays a text on the PT screen for duration of seconds.
@ -416,61 +327,6 @@ class ECR(object):
transmission = self.transmitter.transmit(packet)
return transmission
def request_reservation(self, amount_cent=50, listener=None):
"""
executes a reservation request in amount of cents.
@returns: True, if reservation went through, or False if it was canceled.
throws exceptions.
"""
packet = ReservationRequest(
amount=amount_cent, # in cents.
currency_code=978, # euro, only one that works, can be skipped.
tlv=[],
)
if listener:
packet.register_response_listener(listener)
code = self.transmit(packet=packet)
if code == 0:
# now check if the packet actually got what it wanted.
if self.transmitter.last.completion:
if isinstance(self.transmitter.last.completion, Completion):
return True
else:
return False
else:
# @todo: remove this.
logger.error("transmit error?")
return False
def book_reservation(self, receipt_no, amount_cent=50, listener=None):
"""
executes a reservation booking for receipt with cancel amount in cents.
@returns: True, if booking went through, or False if it was canceled.
throws exceptions.
"""
packet = ReservationBooking(
receipt=receipt_no,
amount=amount_cent,
currency_code=978,
tlv=[],
)
if listener:
packet.register_response_listener(listener)
code = self.transmit(packet=packet)
if code == 0:
# now check if the packet actually got what it wanted.
if self.transmitter.last.completion:
if isinstance(self.transmitter.last.completion, Completion):
return True
else:
return False
else:
# @todo: remove this.
logger.error("transmit error?")
return False
# dev functions.
#########################################################################

View file

@ -116,7 +116,6 @@ class EndOfDay(CommandWithPassword):
CMD_INSTR = 0x50
wait_for_completion = True
class LogOff(Packet):
"""06 02 Log Off"""
CMD_CLASS = 0x06
@ -244,11 +243,15 @@ class StatusInformation(Packet):
# bitmap 0x60 (totals) contains the required information.
# another bitmap (amount) holds the amount
## FIXME Parsing of totals in the parser
return ret
if 'totals' not in bdict.keys():
# this packet holds no detail information but an amount.
return ret
totals_list = bdict['totals']
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.
@ -256,39 +259,42 @@ class StatusInformation(Packet):
my_date = None
if 'time' in bdict.keys():
# print bdict['time'].value()
mt = str(bdict['time'])
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'])
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': BCDIntField(length=2).from_bytes(totals_list[0:2]),
'receipt-number-end': BCDIntField(length=2).from_bytes(totals_list[2:4]),
'number-ec-card': totals_list[4],
'turnover-ec-card': BCDIntField(length=3).from_bytes(totals_list[5:5 + 6]),
'number-jcb': totals_list[11],
'turnover-jcb': BCDIntField(length=3).from_bytes(totals_list[12:12 + 6]),
'number-eurocard': totals_list[18],
'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':
BCDIntField(length=3).from_bytes(totals_list[19:19 + 6]),
'number-amex': totals_list[25],
BCD.as_int(BCD.decode_bcd(totals_list[19:19 + 6])),
'number-amex': bs2hl(totals_list[25])[0],
'turnover-amex':
BCDIntField(length=3).from_bytes(totals_list[26:26 + 6]),
'number-visa': totals_list[32],
BCD.as_int(BCD.decode_bcd(totals_list[26:26 + 6])),
'number-visa': bs2hl(totals_list[32])[0],
'turnover-visa':
BCDIntField(length=3).from_bytes(totals_list[33:33 + 6]),
'number-diners': totals_list[39],
BCD.as_int(BCD.decode_bcd(totals_list[33:33 + 6])),
'number-diners': bs2hl(totals_list[39])[0],
'turnover-diners':
BCDIntField(length=3).from_bytes(totals_list[40:40 + 6]),
'number-remaining': totals_list[46],
BCD.as_int(BCD.decode_bcd(totals_list[40:40 + 6])),
'number-remaining': bs2hl(totals_list[46])[0],
'turnover-remaining':
BCDIntField(length=3).from_bytes(totals_list[47:47 + 6]),
'amount': bdict['amount'],
'turnover-amount': bdict['amount'],
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,
@ -312,14 +318,6 @@ class StatusInformation(Packet):
ret.update(float_version)
return ret
def get_receipt_number(self):
bdict = self.as_dict()
if 'receipt' not in bdict.keys():
return {}
else:
ret = bdict['receipt']
return ret
class IntermediateStatusInformation(Packet):
"""
@ -370,51 +368,6 @@ class Authorisation(Packet):
'pump_nr', 'cvv', 'additional', 'card_type', 'tlv']
class Reversal(CommandWithPassword):
"""
06 30
Reverse a payment
"""
CMD_CLASS = 0x06
CMD_INSTR = 0x30
wait_for_completion = True
ALLOWED_BITMAPS = [
'receipt', 'amount', 'currency_code', 'status_byte', 'track_1',
'card_expire', 'card_number', 'track_2', 'track_3', 'additional',
'tlv']
class PreAuthorisation(Packet):
"""
06 22
If you want to authorize a transaction, this is the packet you need
to start with. Also for reading card data in general.
"""
CMD_CLASS = 0x06
CMD_INSTR = 0x22
wait_for_completion = True
ALLOWED_BITMAPS = [
'amount', 'currency_code', 'status_byte', 'track_1', 'card_expire',
'card_number', 'track_2', 'track_3', 'timeout', 'max_status_infos',
'pump_nr', 'trace_number', 'additional', 'card_type', 'tlv']
class PartialCancellation(Packet):
"""
06 23
This command executes a Partial-Cancellation for a Pre-Authorisation to release the unused amount of the reservation.
This command is also used for the Booking of a Reservation.
"""
CMD_CLASS = 0x06
CMD_INSTR = 0x23
wait_for_completion = True
ALLOWED_BITMAPS = [
'receipt', 'amount', 'currency_code', 'trace_number', 'additional', 'aid', 'tlv']
class PrintLine(Packet):
"""
06 D1
@ -596,25 +549,3 @@ class WriteFiles(WriteFileBase):
@classmethod
def can_parse(cls, data: Union[bytes, List[int]]) -> bool:
return False
class ReservationRequest(Authorisation):
"""
06 22
If you want to request a reservation, this is the packet you need to start with.
"""
CMD_INSTR = 0x22
class ReservationBooking(Packet):
"""
06 24
If you want to book a reservation, this is the packet you need to start with.
"""
CMD_CLASS = 0x06
CMD_INSTR = 0x24
wait_for_completion = True
ALLOWED_BITMAPS = [
'receipt', 'amount', 'currency_code', 'status_byte', 'additional',
'trace_number', 'card_type', 'aid', 'tlv']