def coupon_cancel_item(self, item_id): self._check() self._check_coupon_is_opened() if not item_id in self._items: raise CancelItemError(_("There is no item with this ID (%d)") % item_id) elif self.is_coupon_totalized: raise CancelItemError(_("The coupon is already totalized, " "you can't cancel items anymore.")) self._items.pop(item_id) self.write('cancel_item %r\n' % (item_id, ))
def handle_error(self, error_value, raw): error = int(error_value[2:]) # Page 61-62 if error == 39: raise DriverError('Bad parameters: %r' % raw, error) elif error == 10: raise CouponOpenError(_("Document is already open"), error) elif error == 11: raise CouponNotOpenError(_("Coupon is not open"), error) elif error == 12: raise CouponNotOpenError(_("There's no open document to cancel"), error) elif error == 15: raise CancelItemError(_("There is no such item in " "the coupon"), error) elif error == 16: raise DriverError("Bad discount/markup parameter", error) elif error == 21: log.warning(_('Printer error %s: No paper'), error) elif error == 22: raise DriverError( "Reduce Z was already sent today, try again tomorrow", error) elif error == 23: raise PendingReduceZ elif error == 24: raise DriverError("Bad unit specified: %r" % raw, error) elif error == 42: raise DriverError("Read X has not been sent yet", error) elif error == 45: raise DriverError(_("Required field is blank"), error) else: raise DriverError("Unhandled error: %d" % error, error)
def coupon_cancel_item(self, item_id): try: item = self.items_dict[item_id] except KeyError: raise CancelItemError(_("You have specified an invalid item id " "to cancel!")) self._send_command(self.CMD_CANCEL_ITEM, item.get_packaged())
def coupon_cancel_item(self, item_id=None): """ Cancel an item added to coupon; if no item id is specified, cancel the last item added. """ last_item = self._get_last_item_id() if item_id is None: item_id = last_item elif item_id not in range(1, last_item + 2): raise CancelItemError("There is no such item with ID %r" % item_id) self._send_command(CMD_CANCEL_ITEM, "%04d" % (item_id, ))
class MP25Status(object): PENDING_REDUCE_Z = 66 st1_codes = { 128: (OutofPaperError(_("Printer is out of paper"))), # 64: (AlmostOutofPaper(_("Printer almost out of paper"))), 32: (PrinterError(_("Printer clock error"))), 16: (PrinterError(_("Printer in error state"))), 8: (CommandError(_("First data value in CMD is not ESC (1BH)"))), 4: (CommandError(_("Nonexistent command"))), # 2: (CouponOpenError(_("Printer has a coupon currently open"))), 1: (CommandError(_("Invalid number of parameters")))} st2_codes = { 128: (CommandError(_("Invalid CMD parameter"))), 64: (HardwareFailure(_("Fiscal memory is full"))), 32: (HardwareFailure(_("Error in CMOS memory"))), 16: (PrinterError(_("Given tax is not programmed on the printer"))), 8: (DriverError(_("No available tax slot"))), 4: (CancelItemError(_("The item wasn't added in the coupon or can't " "be cancelled"))), # 2: (PrinterError(_("Owner data (CGC/IE) not programmed on the printer"))), # FIXME: This shouldn't be commented. But it will break the tests. # Need to update the tests for all bematech printers #1: (CommandError(_("Command not executed"))) } st3_codes = { # 7: (CouponOpenError(_("Coupon already Open"))), # 8: (CouponNotOpenError(_("Coupon is closed"))), 13: (PrinterOfflineError(_("Printer is offline"))), 16: (DriverError(_("Surcharge or discount greater than coupon total" "value"))), 17: (DriverError(_("Coupon with no items"))), 20: (PaymentAdditionError(_("Payment method not recognized"))), 22: (PaymentAdditionError(_("Isn't possible add more payments since" "the coupon total value already was " "reached"))), 23: (DriverError(_("Coupon isn't totalized yet"))), 43: (CouponNotOpenError(_("Printer not initialized"))), 45: (PrinterError(_("Printer without serial number"))), 52: (DriverError(_("Invalid start date"))), 53: (DriverError(_("Invalid final date"))), 85: (DriverError(_("Sale with null value"))), 91: (ItemAdditionError(_("Surcharge or discount greater than item" "value"))), 100: (DriverError(_("Invalid date"))), 115: (CancelItemError(_("Item doesn't exists or already was cancelled"))), 118: (DriverError(_("Surcharge greater than item value"))), 119: (DriverError(_("Discount greater than item value"))), 129: (CouponOpenError(_("Invalid month"))), 169: (CouponTotalizeError(_("Coupon already totalized"))), 170: (PaymentAdditionError(_("Coupon not totalized yet"))), 171: (DriverError(_("Surcharge on subtotal already effected"))), 172: (DriverError(_("Discount on subtotal already effected"))), 176: (DriverError(_("Invalid date")))} def __init__(self, reply): self.st1, self.st2, self.st3 = reply[-3:] @property def open(self): return self.st1 & 2 def _check_error_in_dict(self, error_codes, value): for key in error_codes: if key & value: raise error_codes[key] def check_error(self): log.debug("status: st1=%s st2=%s st3=%s" % (self.st1, self.st2, self.st3)) if self.st1 != 0: self._check_error_in_dict(self.st1_codes, self.st1) if self.st2 != 0: self._check_error_in_dict(self.st2_codes, self.st2) # first bit means not executed, look in st3 for more if self.st2 & 1 and self.st3: if self.st3 in self.st3_codes: raise self.st3_codes[self.st3]
class Reply(object): # # Printer flags # error_codes = { '0101': (CommandError(_("Invalid command for current state."))), '0102': (CommandError(_("Invalid command for current document."))), '0203': (CommandError(_("Excess fields"))), '0204': (CommandError(_("Missing fields"))), '0205': (CommandParametersError(_("Field not optional."))), '0206': (CommandParametersError(_("Invalid alphanumeric field."))), '0207': (CommandParametersError(_("Invalid alphabetic field."))), '0208': (CommandParametersError(_("Invalid numeric field."))), '020E': (CommandParametersError(_("Fields with print invalid " "attributes."))), '0304': (OutofPaperError(_("Out of paper."))), '0305': (AlmostOutofPaper(_("Almost out of paper."))), '0801': (CommandError(_("Invalid command with closed " "fiscal journey."))), '090C': (DriverError(_("Payment method not defined."))), '090F': (ItemAdditionError(_("Tax not found."))), '0910': (ItemAdditionError(_("Invalid tax."))), '0A12': (CancelItemError( _("It was not possible cancel the last " "fiscal coupon."))), '0A15': (PrinterError(_("Requires CDC cancellation."))), '0A16': (CancelItemError(_("Invalid item number in fiscal coupon"))), '0E0A': (PrinterError(_("Last non-fiscal coupon not found."))), '0E0B': (PrinterError(_("Payment method not found."))), } 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) def check_error(self): log.debug("reply_status %s" % self.reply_status) error_code = self.reply_status # Success, do nothing if error_code == '0000': return if error_code in self.error_codes: error = self.error_codes[error_code] error.code = int(error_code, 16) raise error raise DriverError(error="unhandled driver error", code=int(error_code, 16)) def pop(self, size=1): """Remove size bites from the begining of self.string and returns it """ head = self.string[:size] self.string = self.string[size:] return head def check_printer_status(self): status = bin(self.printer_status) printer_status = status[2:] return printer_status def check_fiscal_status(self): status = bin(self.fiscal_status) fiscal_status = status[2:] return fiscal_status