Поиск чеков из SetRetail10 в SetCentrum5 и правила декодирования штрих-кода

Включение механизма передачи чеков из SetRetail10 в SetRetail5

Для того, чтобы произвести поиск чеков в БД SetCentrum5 или SetRetail5, в SetRetail10 включите такую возможность во внешних системах:

1. Интеграция → Внешние процессинги → кликните .

2. Установите флажок Протокол Set Retail 5 → кликните .

3. Кликните Протокол Set Retail 5.

4. Перейдите на вкладку ЭКСПОРТ ДАННЫХ → установите необходимые типы данных для экспорта.

5. Перейдите на вкладку НАСТРОЙКИ СЕРВЕРА → установите настройки подключения → кликните .


Поиск чека

Поиск чека в SetRetail5 осуществляется только через поле [Штрих-код] посредством сканирования штрих-кода чека.

Примеры форматов штрих-кода для сканирования чеков

Правило 1. Сканирование текущей версии штрих-кода чека (чеки SetRetail5 и SetRetail10, начиная с середины 2014 года)

Пример: 009ZWDS.1JBY41

  • Формат: закодированный набор данных в 36-ричной системе исчисления, номер магазина, кассы, смены, чека и даты.
  • Кассовый модуль SetRetail10 печатает на чеке штрих-код, содержащий: номер документа, номер смены, номер кассы, номер магазина и дату документа в виде количества дней с начала десятилетия.
  • Штрих-код имеет длину 14 символов (7-значное 36-ричное число, точка, 6-значное 36-ричное число).
    Штрих-код печатается в формате Code39 или Code128 (или другом, поддерживающем цифры, латинские буквы и точку), с расшифровкой в понятном человеку виде.
  • Например: штрих-код 002QSW0.02NIM8 будет иметь расшифровку 101.0034.240914.0001.

Логика декодирования штрих-кода в формате Java

import org.joda.time.DateTimeConstants;
import org.joda.time.LocalDate;

public class SetRetail10DocumentBarcode {
    public static void main(String[] args) {
        parseDocumentBarcode();
    }

    public static void parseDocumentBarcode() {

        // Исходный штрихкод (в нем закодирован документ №2, касса 10, смена 43, магазин 2380, дата 28.03.2014)
        String documentBarcode = "0050PHO.03CUOC";

        // разбивается по точке на строки
        String[] splittedDocumentBarcode = documentBarcode.split("\\.");
        // Первая (0050PHO) и вторая (03CUOC) части
        String firstPartBase36String = splittedDocumentBarcode[0];
        String secondPartBase36String = splittedDocumentBarcode[1];

        // Конвертируем полученные строки в long, используя 36-ричную систему:
        // первая (8431116) и вторая (5638476) части
        long firstPart = Long.parseLong(firstPartBase36String, 36);
        long secondPart = Long.parseLong(secondPartBase36String, 36);

        // Извлекаем нужные данные с помощью битовых операций: сдвиг вправо (>>) и побитовое И (&)

        // Номер документа (2)
        long documentNumber = (firstPart >> 22) & (0x1000 - 1);

        // Номер кассы (10)
        long cashNumber = (firstPart >> 12) & (0x400 - 1);

        // Номер смены (43)
        long shiftNumber = (secondPart >> 17) & (0x2000 - 1);

        // Номер магазина (2380)
        long shopNumber = secondPart & (0x20000 - 1);

        // Дата документа в виде количества дней, прошедших с начала текущего десятилетия (1548)
        long documentDayOfDecade = (firstPart) & (0x1000 - 1);

        // При необходимости использования даты, восстанавливаем полную дату (28.03.2014 при условии, что на дворе 2010-2019 годы)
        LocalDate fullDocumentDate = calculateFullDocumentDate((int) documentDayOfDecade);
    }

    protected static LocalDate calculateFullDocumentDate(int dayOfDecade) {
        // Текущая дата (без времени или со временем в полночь - 00:00:00.0000)
        LocalDate currentDate = LocalDate.now();

        // Вычисляем первый год десятилетия (2010)
        int firstYearOfDecade = currentDate.getYear() / 10 * 10;

        // Создаем дату первого дня десятилетия (1 января 2010) (без времени или со временем в полночь 00:00:00.0000)
        LocalDate firstDayOfDecade = new LocalDate().withYear(firstYearOfDecade).withMonthOfYear(DateTimeConstants.JANUARY).withDayOfMonth(1);

        // Прибавляем к дате первого дня десятилетия количество дней из документа и получаем дату документа (28.03.2014)
        LocalDate fullDocumentDate = firstDayOfDecade.plusDays(dayOfDecade - 1);

        // Если получилось, что дата из будущего (более чем на один день)
        if (fullDocumentDate.isAfter(currentDate.plusDays(1))) {
            // значит, этот документ из прошлого десятилетия и нужно скорректировать год на 10 лет назад
            fullDocumentDate = fullDocumentDate.minusYears(10);
        }
        return fullDocumentDate;
    }
}

Правило 2. Сканирование старого формата штрих-кода чеков SetRetail10

Пример: 003.1190.130715.0007

В данном ШК через точку указаны следующие поля: номер кассы.номер смены.день.номер чека

Правило 3. Сканирование старого формата штрих-кода чеков SetRetail5

Пример: 00311900000700280000

  • Самый сложный вариант, без даты, и чек может быть не уникальный:
  • Касса 1-3 символы (всего 3 символа).
  • Смена 4-7 символы (всего 4 символа).
  • Чек 8-12 символы (всего 5 символов) - если номер чека больше 99999 то остаются только 5 правых младших разрядов номера чека, и дальнейший поиск осуществляется по сумме.
  • Сумма в копейках 13-20 (всего 8 символов)
  • Ввод номера чека вручную - должен осуществляться строго по правилу 2, т.е. указывать через точку: номер кассы . номер смены . день . номер чека
  • Gри некорректном вводе ШК (номера чека) по которому не возможно будет определить ни дату чека, ни другие поля (касса, смена, чек) система должна выдать сообщение "Не корректный формат".