shtrih-m / javapos_shtrih

Реализация JavaPOS драйвера принтера фискального регистратора для устройств Штрих-М
http://www.shtrih-m.ru
MIT License
33 stars 16 forks source link

Как получить данные по последнему напечатанному чеку из ФР? #121

Open gevorg95 opened 3 years ago

gevorg95 commented 3 years ago

@nyxiscoo1 Добрый день, не могли бы помочь? Мне нужно получить данные по последнему напечатанному чеку для решения проблемы с повторными запросами на печать

nyxiscoo1 commented 3 years ago

Добрый день. Это достаточно расплывчатый вопрос, что конкретно хочется получить? Для печати дубликата последнего чека есть команда отдельная. Из ККТ же можно получить краткую информацию о последнем документе и TLV последнего докумета. Есть еще механизм СКЛ в драйвере, но я бы крайне настоятельно не рекомендовал его использовать(субъективная оценка).

gevorg95 commented 3 years ago

@nyxiscoo1, я думаю это именно то, что мне нужно: Из ККТ же можно получить краткую информацию о последнем документе и TLV последнего документа.

Не подскажите код для получения этой информации?

nyxiscoo1 commented 3 years ago

fsReadDocumentTLV - чтение TLV. fsFindDocument - чтение краткой информации о документе.

nyxiscoo1 commented 3 years ago

fsFindDocument достаточно специфично работает он возвращает документ, который надо будет кастовать в зависимости от типа, чтобы получить всю информацию. Вот пример на Котлине:

val cmd = FSFindDocument(printer.sysPassword, docNumber)
printer.fsFindDocument(cmd)
val doc = Unchecked.cast<FSDocumentReceipt>(cmd.document!!)

В случае с TLV его нужно будет парсить. Вот примерный код который это делает в какой-то степени:

private TLVItems getDocumentTlvItems(ShtrihFiscalPrinter printer, long docNumebr) throws Exception {
    byte[] tlv = printer.fsReadDocumentTLV((int) docNumebr).getTLV();
    return getTlvItems(tlv);
}

private TLVItems getTlvItems(byte[] tlv) throws Exception {
    TLVParser parser = new TLVParser();
    parser.read(tlv);
    return parser.getItems();
}

private boolean getBoolean(TLVItems tlvItems, int tag) {
    TLVItem item = tlvItems.itemById(tag);

    if (item == null)
        return false;

    return item.toInt() != 0;
}

private long getUInt32(TLVItems tlvItems, int tag) {
    TLVItem item = tlvItems.itemById(tag);

    if (item == null)
        return 0;

    return item.toInt();
}

private BigDecimal getVLN(TLVItems tlvItems, int tag) {
    TLVItem item = tlvItems.itemById(tag);

    if (item == null)
        return BigDecimal.ZERO;

    return item.toVLN();
}
gevorg95 commented 3 years ago

@nyxiscoo1, А как получить номер последнего документа? val cmd = FSFindDocument(printer.sysPassword, docNumber)

nyxiscoo1 commented 3 years ago

Если бить чеки через команды напрямую, то это одно из возвращаемых значений в ответе на команду закрытии чека. Еще его вроде в последних версиях можно получить через DirectIO. Можно получить из статуса ФН printer.fsReadStatus().docNumber.