Публичное пространство

SetMark ◾️ API для интеграции с ERP

Загрузка списка марок из внешней системы


Рекомендация

Рекомендуемый размер одного пакета - не более 5000 марок. 

Марки для всех типов товаров (кроме акцизного алкоголя) загружаются без криптохвостов.

URL/erp/add_mark
МетодPOST
Входящие данные

JSON пакет с марками для загрузки и удаления в SetMark

{  “id” : <id пакета>, “version”: <версия API>, "inn": <ИНН>, “shop” : <номер магазина>, “operationType” : <тип операции>,  “productType” : <тип товара>, “data” : [ ... ] }

Выходные данные

HTTP код 200 при успешной приеме пакета, в противном случае ошибка:

400(большая часть ошибок, включая невалидный запрос), 422(внутренняя ошибка сервиса)

Заголовок пакета

НазваниеТипОписаниеПример
idчисло (long)Уникальный идентификатор пакета

{
    "id": 101,
    "version": 1,
    "inn": "0000000000",
    "shop": 10000,
    "operationType": 1,
    "productType": 1,
    "data": [...]
}
versionчислоВерсия протокола, на текущий момент "1"
shopчисло (long)

Номер магазина - всегда обязательно при продаже акцизного алкоголя

Поле необязательное только для SetMark Centrum и исключительно для модулей "Продовольственные товары" и "Непродовольственные товары"

innстрока

ИНН владельца КМ

Обязательность зависит от настройки check.inn

operationTypeчисло

Тип операции

1 - добавление марок
2 - удаление марок

productTypeчисло

Тип товара

1 - Акцизный алкоголь
2 - Табак
3 - Обувь
4 - Парфюмерия
5 - Легкая промышленность
6 - Шины
7 - Фото
8 - Молоко
10 - Упакованная вода в групповой и индивидуальной (потребительской) упаковке
11 - Велосипеды
16 - БАДы
17 - Антисептики
18 - Разливное пиво (в кегах)


datajsonМассив марок определенного полем "productType" типа

Марка для Акцизного алкоголя

НазваниеТипОписаниеПример
excise

строка

обязательное

Алкогольная марка
{
    "excise": "22N000003GDBDAMBBIW09QV6...",
    "alcocode": "0012631000001797400",
    "barcode": "4650067391939",
    "item": "2201"
}
alcocode 

строка

Алкокод

Необязательное поле

barсode строка

Штрихкод

Необязательное поле

itemстрока

Артикул (код товара)

Необязательное поле

Марка для обуви

НазваниеТипОписаниеПример
mark

строка

Марка
{
    "mark": "01046300740926092109470cde931542406401",
    "barcode": "4630074092609",
    "item": "2201",
    "gtd": "1234567",
    "rccw": "654",
    "country": "Россия"
}
barсode

строка

Штрихкод

Необязательное поле

 itemстрока

Артикул (код товара)

Необязательное поле

gtdстрока

Номер ГТД

Необязательное поле

rccwстрока

Код страны-производителя

Необязательное поле

countryстрока

Наименование страны-производителя

Необязательное поле

Марка для Молока

НазваниеТипОписаниеПример
mark

строка

Марка
{
    "mark": "0104607026551200215",
    "barcode": "4607026551200",
    "item": "2201",
    "gtd": "1234567",
    "rccw": "654",
    "country": "Россия"
}
barсode

строка

Штрихкод

Необязательное поле

 itemстрока

Артикул (код товара)

Необязательное поле

gtdстрока

Номер ГТД

Необязательное поле

rccwстрока

Код страны-производителя

Необязательное поле

countryстрока

Наименование страны-производителя

Необязательное поле

Марка для табака

НазваниеТипОписаниеПример
mark

строка

Марка
 {
      "mark": "04606203086627IOHop6ZAC68",
      "barcode": "4606203086627",
      "item": "2201",
      "gtd": "1234567",
      "rccw": "654",
      "country": "Россия"
  }


barсode

строка

Штрихкод

Необязательное поле

 itemстрока

Артикул (код товара)

Необязательное поле

gtdстрока

Номер ГТД

Необязательное поле

rccwстрока

Код страны-производителя

Необязательное поле

countryстрока

Наименование страны-производителя

Необязательное поле

Марка для блока табака с пачками

НазваниеТипОписаниеПример
mark

строка

Марка
{
      "mark": "014606203086627IOHop6ZAC68",
      "barcode": "4606203086627",
      "item": "2222",
      "gtd": "1234567",
      "rccw": "654",
      "country": "Россия",
      "child": [
        {
          "mark": "04606203086627IOHop61AC68",
          "barcode": "4606203086627",
          "item": "2201"
        },
        {
          "mark": "04606203086627IOHop62AC68",
          "barcode": "4606203086627",
          "item": "2201"
        },
        {
          "mark": "04606203086627IOHop63ZAC68",
          "barcode": "4606203086627",
          "item": "2201"
        },
        {
          "mark": "04606203086627IOHop64AC68",
          "barcode": "4606203086627",
          "item": "2201"
        },
        {
          "mark": "04606203086627IOHop65AC68",
          "barcode": "4606203086627",
          "item": "2201"
        },
        {
          "mark": "04606203086627IOHop66AC68",
          "barcode": "4606203086627",
          "item": "2201"
        },
        {
          "mark": "04606203086627IOHop67AC68",
          "barcode": "4606203086627",
          "item": "2201"
        },
        {
          "mark": "04606203086627IOHop68AC68",
          "barcode": "4606203086627",
          "item": "2201"
        },
        {
          "mark": "04606203086627IOHop69AC68",
          "barcode": "4606203086627",
          "item": "2201"
        },
        {
          "mark": "04606203086627IOHop70AC68",
          "barcode": "4606203086627",
          "item": "2201"
        }
      ]
    }


barсode

строка

Штрихкод

Необязательное поле

 itemстрока

Артикул (код товара)

Необязательное поле

gtdстрока

Номер ГТД

Необязательное поле

rccwстрока

Код страны-производителя

Необязательное поле

countryстрока

Наименование страны-производителя

Необязательное поле

Марка для разливного пива

НазваниеТипОписаниеПример
markстрокаМарка
{
            "mark": "010899222324252621jhtg2tr",
            "item": "2201",
			"barcode": "8992223242526",
    	    "gtd": "1234567",
      		"rccw": "654",
			"country": "Россия"
            "initialVolume": 30000     
}

barcode

строка

Штрихкод

Необязательное поле

itemстрока

Артикул (код товара)

Необязательное поле

gtdстрока

Номер ГТД

Необязательное поле

rccwстрока

Код страны-производителя

Необязательное поле

countryстрока

Наименование страны-производителя

Необязательное поле

initialVolumeчислоОбъем кега, в мл

Пример загрузки алкогольных марок

{
    "id": 101,
    "version": 1,
    "shop": 10000,
    "operationType": 1,
    "productType": 1,
    "data": [{
            "excise": "22N000003GDBDAMBBIW09QV61219001018174654WDWE6T8CFGBR7D3533QKUTMSWLDZ",
            "alcocode": "0012631000001797400",
            "barcode": "4650067391939",
            "item": "2201"
        }, {
            "excise": "101100000000010118001D5CCFC794963898C1B13E41231CKY42T7UDIJJY2AWLHS7HPGINLMY7PQPDNJALVS42WNCHYRCO257SPCSCF4ASM37BZNTLIASYRVGFUTCXDXDJPML5MMVLEEHZWPWJVI",
            "alcocode": "0012631000001797400",
            "barcode": "4650067391939",
            "item": "101010"
        }
    ]
}


Пример загрузки обувной марки

{
    "id": 102,
    "version": 1,
    "shop": 10000,
    "operationType": 1,
    "productType": 3,
    "data": [{
            "mark": "01046300740926092109470cde931542406401",
            "barcode": "4630074092609",
            "item": "2201",
            "gtd": "1234567",
            "rccw": "654",
            "country": "Россия"
        }
    ]
}


Пример удаления обувной марки

{
    "id": 103,
    "version": 1,
    "shop": 10000,
    "operationType": 2,
    "productType": 3,
    "data": [{
            "mark": "01046300740926092109470cde931542406401"
        }
    ]
}


Пример загрузки молочной марки

{
    "id": 102,
    "version": 1,
    "shop": 10000,
    "operationType": 1,
    "productType": 8,
    "data": [{
                "mark": "0104607026551200215",
                "barcode": "4607026551200",
                "item": "2201",
                "gtd": "1234567",
                "rccw": "654",
                "country": "Россия"
        }
    ]
}


Пример загрузки марки разливного пива

{
    "id": 102,
    "version": 1,
    "shop": 10000,
    "operationType": 1,
    "productType": 18,
	"data": [{
            "mark": "010899222324252621jhtg2tr",
            "item": "2201",
            "initialVolume": 30000
        }
    ]
}

Пример удаления молочной марки

{
    "id": 103,
    "version": 1,
    "shop": 10000,
    "operationType": 2,
    "productType": 8,
    "data": [{
            "mark": "0104607026551200215"
        }
    ]
}


Пример загрузки табачных марок

{
  "id": 102,
  "version": 1,
  "shop": 10000,
  "operationType": 1,
  "productType": 2,
  "data": [
    {
      "mark": "04606203086627IOHop6ZAC68",
      "barcode": "4606203086627",
      "item": "2201",
      "gtd": "1234567",
      "rccw": "654",
      "country": "Россия"
    },
    {
      "mark": "04606203086627db1&p,\"AC68uB9+",
      "barcode": "4606203086627",
      "item": "2201",
      "gtd": "1234567",
      "rccw": "654",
      "country": "Россия"
    }
  ]
}


Пример загрузки марки блока с пачками

{
  "id": 102,
  "version": 1,
  "shop": 10000,
  "operationType": 1,
  "productType": 2,
  "data": [
    {
      "mark": "014606203086627IOHop6ZAC68",
      "barcode": "4606203086627",
      "item": "2222",
      "gtd": "1234567",
      "rccw": "654",
      "country": "Россия",
      "child": [
        {
          "mark": "04606203086627IOHop61AC68",
          "barcode": "4606203086627",
          "item": "2201"
        },
        {
          "mark": "04606203086627IOHop62AC68",
          "barcode": "4606203086627",
          "item": "2201"
        },
        {
          "mark": "04606203086627IOHop63ZAC68",
          "barcode": "4606203086627",
          "item": "2201"
        },
        {
          "mark": "04606203086627IOHop64AC68",
          "barcode": "4606203086627",
          "item": "2201"
        },
        {
          "mark": "04606203086627IOHop65AC68",
          "barcode": "4606203086627",
          "item": "2201"
        },
        {
          "mark": "04606203086627IOHop66AC68",
          "barcode": "4606203086627",
          "item": "2201"
        },
        {
          "mark": "04606203086627IOHop67AC68",
          "barcode": "4606203086627",
          "item": "2201"
        },
        {
          "mark": "04606203086627IOHop68AC68",
          "barcode": "4606203086627",
          "item": "2201"
        },
        {
          "mark": "04606203086627IOHop69AC68",
          "barcode": "4606203086627",
          "item": "2201"
        },
        {
          "mark": "04606203086627IOHop70AC68",
          "barcode": "4606203086627",
          "item": "2201"
        }
      ]
    }
  ]
}

Пример удаления марки блока

{
  "id": 102,
  "version": 1,
  "shop": 10000,
  "operationType": 2,
  "productType": 2,
  "data": [
    {
      "mark": "014606203086627IOHop6ZAC68",
      "barcode": "4606203086627",
      "item": "2222",
      "gtd": "1234567",
      "rccw": "654",
      "country": "Россия"
    }
  ]
}


Загрузка RFID метки к марке (с версии 2.5.0)


URL/erp/add_rfid
МетодPOST
Входящие данные

JSON пакет с RFID+марка для загрузки и удаления в SetMark

{  “id” : <id пакета>, “version”: <версия API>, “operationType” : <тип операции>,  “productType” : <тип товара>, “data” : [ ... ] }

Выходные данные

HTTP код 200 при успешной приеме пакета и JSON в теле ответа

в противном случае ошибка:
400
(большая часть ошибок, включая невалидный запрос), 422(внутренняя ошибка сервиса), в противном случае ошибка:

Заголовок пакета

НазваниеТипОписаниеПример
idчисло (long)Уникальный идентификатор пакета
{
    "id": 1,
    "version": 1,
    "operationType": 1,
    "productType": 3,
    "data": [...]
}
versionчислоВерсия протокола, на текущий момент "1"
operationTypeчисло

Тип операции

1 - добавление кодов товаров
2 - удаление кодов товаров

productTypeчисло

Тип товара

1 - Акцизный алкоголь
2 - Табак
3 - Обувь
4 - Парфюмерия
5 - Легкая промышленность
6 - Шины
7 - Фото
8 - Молоко

datajsonМассив RFID+марка определенного полем "productType" типа

RFID+Марка

НазваниеТипОписаниеПример
mark

строка

Марка
{
    "mark": "0103608429802815210123456789012911234921234567890123456789012345678901234567890123456789012345678901234567890123456789012345678",
            "rfid": "]e0010360842980281521000000708145"
}
rfid

строка

RFID

обязательное поле

Пример добавления

{
    "id": 1,
    "version": 1,
    "operationType": 1,
    "productType": 3,
    "data": [
        {
            "mark": "0103608429802815210123456789012911234921234567890123456789012345678901234567890123456789012345678901234567890123456789012345678",
            "rfid": "]e0010360842980281521000000708145"
        }
    ]
}

Пример удаления

{
    "id": 1,
    "version": 1,
    "operationType": 2,
    "productType": 3,
    "data": [
        {
            "mark": "0103608429802815210123456789012911234921234567890123456789012345678901234567890123456789012345678901234567890123456789012345678",
            "rfid": "]e0010360842980281521000000708145"
        }
    ]
}

Загрузка списка товаров-исключений для проверки на остатках

URL/erp/add_excludes
МетодPOST
Входящие данные

JSON пакет с товарами-исключениями для загрузки и удаления в SetMark

{  “id” : <id пакета>, “version”: <версия API>, "inn": <ИНН>, “shop” : <номер магазина>, “operationType” : <тип операции>,  “productType” : <тип товара>, “data” : [ ... ] }

Выходные данные

HTTP код 200 при успешной приеме пакета и JSON в теле ответа

в противном случае ошибка:
400
(большая часть ошибок, включая невалидный запрос), 422(внутренняя ошибка сервиса), в противном случае ошибка:

Заголовок пакета

НазваниеТипОписаниеПример
idчисло (long)Уникальный идентификатор пакета
{
    "id": 101,
    "version": 1,
    "inn": "0000000000",
    "shop": 10000,
    "operationType": 1,
    "productType": 1,
    "data": [...]
}
versionчислоВерсия протокола, на текущий момент "1"
innстрока

ИНН владельца КМ

Обязательность зависит от настройки check.inn

shopчисло (long)

Номер магазина

Поле необязательное только для SetMark Centrum.

operationTypeчисло

Тип операции

1 - добавление кодов товаров
2 - удаление кодов товаров

productTypeчисло

Тип товара

1 - Акцизный алкоголь
2 - Табак
3 - Обувь
4 - Парфюмерия
5 - Легкая промышленность
6 - Шины
7 - Фото
8 - Молоко

datajsonМассив марок определенного полем "productType" типа

Товар-исключение

НазваниеТипОписаниеПример
itemстрока

Артикул (код) товара

{
    "item": "394175901982"
}


Пример загрузки товаров-исключения для обуви

{
    "id": 104,
    "version": 1,
    "shop": 10000,
    "operationType": 1,
    "productType": 3,
    "data": [{
            "item": "010463007409"
        }, {
            "item": "4435235666"
        }
    ]
}


Пример удаления товаров-исключения для обуви

{
    "id": 104,
    "version": 1,
    "shop": 10000,
    "operationType": 2,
    "productType": 3,
    "data": [{
            "item": "010463007409"
        }
    ]
}


Загрузка и выгрузка дополнительной информации для алкоголя

Загрузка списка МРЦ из ERP

Доступно начиная с версии 1.0.0

Имя: erp/alco/add_mrc

Метод: POST

Входящий:

{  “id” : <id пакета>, “version”: <версия API>, “shop” : <номер магазина>, “operationType” : <тип операции>,   “data” : [ { “barcode” : <ШК товара>, “item” : <код товара>, "codeAP": <код АП>, "volume": <объем>, "AbV": <% алкоголя>, "mrc": [ {"beginDate": <дата начала>, "endDate": <дата окончания>,  "price": <МРЦ>}, ... ] }, ... ] }

Значения:

  • id - число, обязательное поле (long) идентификатор пакета, должен быть уникальным
  • version - число, обязательное поле (значения -  {1})
  • shop - число, обязательное поле (long)
  • operationType - число, обязательное поле (значения - {1 - вставить, 2 - удалить})
  • data - массив с мрц для товаров
    • barcode - строка, штрихкод товара
    • item - строка, код/артикул товара (не обязательное поле)
    • codeAP - целое число, кода алкогольной продукции (не обязательное поле, Integer)
    • volume - число с плавающей точкой, объем бутылки (не обязательное поле, Double)
    • AbV - "Alcohol by Volume", число с плавающей точкой, процент содержания алкоголя (не обязательное поле, Double)
    • mrc - массив с МРЦ для данного товара с разными (не пересекающимися) периодами действия
      • beginDate - строка (формат dd.MM.yyyy), дата начала действия цены (включительно)
      • endDate - строка (формат dd.MM.yyyy), дата окончания действия цены (включительно)
      • price - число с двумя знаками после запятой, значение МРЦ в рублях

Пример:

{
	"id": 1,
	"version": 1,
	"shop": 2,
	"operationType": 1,
	"data": [{
			"barcode": "4607032194941",
			"item": "19191",
			"codeAP": 100,
			"volume": 0.75,
			"AbV": 40,
			"mrc": [{
					"beginDate": "01.06.2017",
					"endDate": "31.12.2017",
					"price": 250.00
				}, {
					"beginDate": "01.01.2018",
					"endDate": "31.12.2018",
					"price": 250.00
				}
			]
		}
	]
}



Загрузка Артикулов и Алкокодов в локальную базу

Доступно начиная с версии 1.5.0

Имя: erp/alco/add_alcocodes

Метод: POST

Входящий:

{  “id” : <id пакета>, “version”: <версия API>, “shop” : <номер магазина>, “operationType” : <тип операции>,   “data” : [ { “item” : <код товара>, "alcocodes": [<алкокод товара>, ... ] }

Значения:

  • id - число, обязательное поле (long) идентификатор пакета, должен быть уникальным
  • version - число, обязательное поле (значения -  {1})
  • shop - число, обязательное поле (long)
  • operationType - число, обязательное поле (значения - {1 - вставить, 2 - удалить})
  • data - массив со списком артикулов и соответствующих алкокодов:
    • item - строка, код/артикул товара (обязательное поле)
    • alcocodes - массив с алкокодами для данного артикула

Пример:

{
	"id": 101,
	"version": 1,
	"shop": 10000,
	"operationType": 1,
	"data": [
		{
			"item": "2201",
			"alcoCodes": [
				"0012631000001797400",
				"0012631000001797401"
			]
		},
		{
			"item": "101010",
			"alcoCodes": [
				"0012631000001797402"
			]
		}
	]
}


Выгрузка списка МРЦ в ERP для сверки

Доступно начиная с версии 1.1.0

Сверка МРЦ с товароучетной системой позволяет дополнительно контролировать актуальность загруженных МРЦ в SetMark.

В случае необходимости такого контроля, SetMark можно настроить для выгрузки МРЦ в товароучетную систему. Сама сверка должна быть реализована в товароучетной системе.

Выгрузка МРЦ выполняется с заданной периодичностью и настраивается конфигурационном файле (в application.properties --> setmark.alco.minprice.report.cron в соответствии с Crontab pattern, значение по умолчанию - каждые сутки в 2:00 часа ночи).

 Краткое описание шаблона cron

Шаблон представляет собой список из шести разделенных пробелом полей: представляющих секунду, минуту, час, день, месяц, день недели.

Месяц и название дней недели могут быть указаны как первые три буквы английских названий.

Примеры:

  • "0 0 * * * *" = начало каждого часа каждый день.
  • "*/10 * * * * *" = каждые 10 секунд.
  • "0 0 8-10 * * *" = 8, 9 и 10 часов каждый день.
  • "0 0 6,19 * * *" = 6:00 и 19:00 каждый день.
  • "0 0/30 8-10 * * *" = 8:00, 8:30, 9:00, 9:30, 10:00 и 10:30 каждый день.
  • "0 0 9-17 * * MON-FRI" = каждый час с 9:00 до 17:00 по будням.
  • "0 0 0 25 12 ?" = каждое рождество в полночь.

Выгрузка данных осуществляется с помощью POST запроса по URL, указанному в конфигурационном файле.

Метод: POST

Исходящие:

{"id":<id>,"version":<версия API>, “shop” : <номер магазина>,"packageNumber":<номер пакета в очереди>,"packageCount":<всего пакетов в очереди>,"data":[{"barcode":"<ШК товара>","item":"<код товара>","codeAP":<код АП>,"volume":<объем>,"AbV":<% алкоголя>,"mrc":[{"beginDate":"<дата начала>","endDate":"<дата окончания>","price":<МРЦ>}, ...]}, ...]}


Значения:

  • id - число, обязательное поле (long) идентификатор пакета, должен быть уникальным
  • version - число, обязательное поле (значения -  {1})
  • shop - число, обязательное поле (long)
  • packageNumber - число, обязательное поле
  • packageCount - число, обязательное поле
  • data - массив с мрц для товаров
    • barcode - строка, штрихкод товара
    • item - строка, код/артикул товара товара (не обязательное поле)
    • codeAP - целое число, кода алкогольной продукции (не обязательное поле, Integer)
    • volume - число с плавающей точкой, объем бутылки (не обязательное поле, Double)
    • AbV - "Alcohol by Volume", число с плавающей точкой, процент содержания алкоголя (не обязательное поле, Double)
    • mrc - массив с МРЦ для данного товара с разными (не пересекающимися) периодами действия
      • beginDate - строка (формат dd.MM.yyyy), дата начала действия цены (включительно)
      • endDate - строка (формат dd.MM.yyyy), дата окончания действия цены (включительно)
      • price - число с двумя знаками после запятой, значение МРЦ в рублях


Пример запроса от сервиса к ERP:

{
	"id":-1035917930,
	"version":1,
	"shop":10000,
	"packageNumber":1,
	"packageCount":1,
	"data":[{
		"barcode":"4607032194941",
		"item":"19191",
		"codeAP":123,
		"volume":0.5,
		"AbV":40.0,
		"mrc":[{
			"beginDate":"31.12.2017",
			"endDate":"09.01.2018",
			"price":250.00
		}]
	}]
}

Постановка на резерв, снятие с резерва

Имя: /external/reserve

Метод: POST

HTTP POST - Марки добавляются к имеющемуся резерву

HTTP PUT - Резерв перезаписывается

  • id - число, обязательное поле

  • version - число, обязательное поле (значения -  {1})

  • orderNumber – строка, обязательное поле

  • tillDate – число, дата и время(Unix-time) окончания резерва, не обязательное поле

  • data - json с данными по марке, обязательное поле

  • mark – строка, Код маркировки, обязательное поле

  • productType – число, тип маркировки, обязательное поле Тип товара

  Запрос

{
   "id":101,
   "version":1,
   "orderNumber":"GM_10012345678",
   "tillDate":1625850336,
   "data":[
      {
         "mark":"mark1",
         "productType":2
      },
      {
         "mark":"mark2",
         "productType":3
      }
   ]
}

 Дополнительно:

  1. Можно использовать для снятия с резерва, указав “” в "orderNumber".


Ответ:

{
   "id":101,
   "success":"true",
   "message":"OK" - текст ошибки, если запрос не выполнился, то список проблемных марок с причинами.
}

Если ошибка будет касаться проблем с марками, то в message будет сообщение "Ошибки при валидации марок" и появится атрибут data со списком марок:

{

    "id": 1628686444,
    "success": false,
    "message": "Ошибки при валидации марок",
    "data": [
       {
  "mark": "82N000000HM5B96KYYP01DP810120021220690U1KIH3I9D60WPY6Y8N2S6AX8JP4C0O",
  "errorCode": 210,
  "errorMessage": "Марка была зарезервирована под другим номером заказа"
       },
       {
  "mark": "82N00002NUNG4NPJVHS7IEO71018002009581FDBCJY3WXJZZHY3G6QPCVCLXIDHXA21",
  "errorCode": 210,
  "errorMessage": "Марка была зарезервирована под другим номером заказа"
       }
    ]
}


 Если ошибка не относится к самим маркам, то останется как есть, только message:

{
    "id": 1628686881,
    "success": false,
    "message": "Срок жизни резерва 19.01.1970 11:24:56 меньше текущей даты."
}

Снятие с резерва по номеру заказа


Имя: /external/cancel_reserve

Метод: POST

Значения:

  • id - число, обязательное поле

  • version - число, обязательное поле (значения -  {1})

  • orderNumber – строка, обязательное поле


Запрос:

{
  "id":101,
  "version":1,
  "orderNumber":"LO123211123"
}


Ответ:

{
  "id":101,
  "success":"true",
  "message":"OK" - текст ошибки
}


Подтверждение резерва (продажа марки)

Имя: /external/save

Метод: POST

Значения:

  • id - число, обязательное поле

  • version - число, обязательное поле (значения -  {1})

  • inn - строка, Обязательность зависит от настройки check.inn
  • shop - число, обязательное поле

  • cash - число, обязательное поле

  • checkNumber - строка, номер чека, обязательное поле

  • operationType - число, обязательное поле {0 - продажа, 1 - возврат}

  • data - json с данными по марке (необязателен, если есть orderNumbers):

    • Алкоголь:

      • excise - строка (обязательное, не пустое)

      • barcode - строка (необязательное поле)

      • promoBarcode - строка (необязательное поле)

      • item - строка (необязательное поле)
      • productType - число, обязательное поле  (значение - 1 - алкоголь)
    • Остальные:
      • mark - строка (обязательное, не пустое)
      • barcode - строка (необязательное поле)
      • item - строка (необязательное поле)
      • productType - число, обязательное поле  (значение -  2 - табак)
  • orderNumbers  - json, номера резервов (необязателен, если есть data)

  • creationDate - число, дата создания чека

Запрос


Дополнительно:

  1. Если поле “data” отсутствует, то в проданные попадут все марки, в указанных резервах

  2. Возвращать марки по номеру резерва нельзя

  3. Если отсутствуют поля “data” и “orderNumbers” - вернется ошибка

  4. Если есть и “data” и “orderNumbers”, то в проданные попадут только марки из data. Марки которых нет в “data”, но они есть в указанных резервах будут сняты с резерва (вернутся в оборот).


Ответ:

Стандартный HTTP-пакет с кодом ответа. В теле:

Всегда присылается что все «ОК».


Запрос статуса марки

Имя: cash/validate

Метод: POST

Входящий:

JSON, состоящий из полей, общих для всех типов товаров, а так же из полей определяемых конкретным типом товара (определяется на основе "productType").

  • Общая часть:

{ “id” <ID>, “version”: <версия API>, "inn": <ИНН>, “shop” : <номер магазина> , “cash” : <номер кассы>, “operationType” : <тип операции>,  “productType” : <тип товара>, “barcode” : <ШК товара>, "item":<артикул товара>, “deletionType” : <тип удаления> }

  • Полный JSON для алкоголя(подчеркнута общая часть):

{ “id” <ID>, “version”: <версия API>, “shop” : <номер магазина> , “cash” : <номер кассы>, “operationType” : <тип операции>,  “productType” : <тип товара>, “barcode” : <ШК товара>, "item":<артикул товара>, “deletionType” : <тип удаления>, “excise” : <АМ>, “alcocode” : [<алкокод>, ...], “promoBarcode” : <ШК товара>, strictСheck” : <признак проверки на остатках>, "price" : <цена товара>, “promoComponents” : [ { “alcocode” : [<алкокод>, ...],  “price” : <цена в копейках>, “barcode” :[ <ШК товара>, ... ], "item":<артикул компонента>}, ...]  }

  • Полный JSON для табака(подчеркнута общая часть):

{ “id” <ID>, “version”: <версия API>, "inn": <ИНН>, “shop” : <номер магазина> , “cash” : <номер кассы>, “operationType” : <тип операции>,  “productType” : <тип товара>, “barcode” : <ШК товара>, "item":<артикул товара>,  “mark” : <код маркировки> }

Значения:

Общие:

  • id - число, идентификатор запроса, обязательное поле
  • version - число, версия API, обязательное поле (значения -  {1})
  • inn - строка, 
  • shop - число, номер магазина, обязательное поле
  • cash - число, номер кассы, обязательное поле
  • operationType -число, тип операции, обязательное поле {0 - продажа, 1 - возврат}
  • productType - число, тип товара, обязательное поле  (значения - {1 - алкоголь, 2 - табак, ... })
  • barcode - строка, штрихкод, необязательное поле (если не включена проверка ШК)
  • item - строка, артикул, необязательное поле (если не включена проверка по артикулу)

Алкоголь:

  • excise - строка, акцизная марка, обязательное поле
  • alcocode - массив строк, алкокод, необязательное поле (если не включена проверка алкокодов)
  • promoBarcode - строка, штрихкод промонабора, необязательное поле (если не включена проверка ШК) [если присутствует значения, в и случае возникнования ошибки, то поле будет добавлено в таблицу с описанием ошибок]
  • strictСheck - boolean, признак строгой проверки АМ (true / false)
  • price - число, цена товара в копейках
  • promoComponents - массив компонентов , компонент состоит из списка алкокодов (поле "alcocode"), цены компонента (поле "price"), списка штрихкодов (поле "barcode") и артикула (поле "item")

Табак:

  • mark - строка, обязательное поле

Исходящий:

стандартный HTTP-пакет с кодом ответа. В теле:

{ “id”: < ID > , “result”: < результат проверки > , “message”: < сообщение > , “barcode”: < ШК товара > , “alcocode”: < алкокод товара > , "amrc": < МРЦ в копейках > }

Значения:

  • Id - число
  • result - true / false
  • message - строка, текстовое описание ошибки(или “OK” если ошибок нет).
  • barcode - строка, необязательное поле. Добавляется если проверка успешна и barccode загружен в базу.
  • alcoCode - строка, только для алкогольного товара, необязательное поле. Добавляется если проверка успешна и alcocode загружен в базу.
  • amrc - целое число, только для алкогольного товара, необязательное поле. Минимальная розничная цена (в копейках).

Пример запроса:

{ "id": 101, "version": 1, "shop": 10000, "cash": "5", "operationType": 0, "productType": 1, "excise": "excise12340000101003", "alcocode": [], "barcode": "", "strictCheck": true }


Пример ответа:

{ "id": 101, "result": true, "message": "OK", "alcocode": "alcocode12340000101003", "barcode": "012340000101003", "amrc": 50000 }

Обратная связь для ERP (статусы по пакетам)

Имя: erp/status

Метод: POST

Входящие:

{ “id” : [<id пакета>, ...], “version”: <версия API>, “shop” : <номер магазина>}

Значения:

  • id - массив чисел, обязательное поле (тип long)
  • version - число, обязательное поле (значения -  {1})
  • shop - число, обязательное поле (long)


Исходящие:

{ “version”: <версия API>, “shop” : <номер магазина>,  “errorCode” : <код ошибки входящего запроса>, “message” : <сообщение по входящему запросу>, “packets”:[{“id”: <id пакета>, “status”: <статус обработки пакета>, “errorCode”: <код ошибки пакета>, “message”: <сообщение по пакету>, “data” : [ { “field” : “<Имя поля с ошибкой>”, “value”: ”<Содержимое поля>”, “errorCode” : <код ошибки>, “message” : <сообщение>}, ... ]}, ...}


Значения:

  • version - число(значения -  {1})
  • shop - число
  • errorCode - число, код ошибки при обработке текущего входящего запроса:

    Код ошибкиТекст ошибкиОписание ошибки
    0OKБез ошибок.

    504

    Не корректное значение поляОшибка в текущем запросе: отсутствует обязательное поле, недопустимое значения поля.
    1000Внутренняя ошибка сервисаВнутренняя ошибка сервиса.
  • message - строка, описание ошибок во всем запросе
  • packets - массив json:
    • id - число
    • status - число:
      • 0 - Документ не существует;
      • 1 - Документ не прошел проверку валидности структуры;
      • 2 - Документ обрабатывается;
      • 3 - Документ обработан полностью;
      • 4 - Документ обработан, но некоторые сущности не прошли валидацию;
      • 5 - Произошла внутренняя критическая ошибка сервиса
    • errorCode - число, код ошибки при обработке пакета с заданным id, на уровне всего пакета:

      Код ошибкиТекст ошибкиОписание ошибки
      0OKБез ошибок.
      502Неизвестный идентификатор (id) пакетаПакет с запрашиваемым id не найден в системе (Получение статуса обработки пакета)

      504

      Не корректное значение поляОшибки в запрашиваемом пакете: отсутствует обязательное поле, недопустимое значения поля. Запрашиваемый пакет не был обработан.
      506Ошибка при обработке марки

      Ошибки в процессе обработки запрашиваемого пакета. Пакет обработан частично.

      Пример: если в запросе на выгрузку из ERP списка активных АМ, одна АМ из списка пустая, а другая уже проданная, то пакет получит код ошибки 506, а конкретные АМ(поле "data") errorCode 501 и 507 соответственно. Остальные АМ из пакета будут обработаны в стандартном режиме.

      1000Внутренняя ошибка сервисаВнутренняя ошибка сервиса.
    • message - строка, описание ошибок связанных с конкретным пакетом
    • data - массив json, может быть пустым или отсутствовать если ошибок нет:
      • field - строка
      • value - строка
      • errorCode - число, код ошибки для конкретной записи в пакете с заданным выше Id (см. таблицу "Коды ошибок (статусы по пакетам)" ниже).
      • message - строка

Массив “data“ может быть пустым. Содержит описание полей с ошибками, если они есть, или ошибки в обработке вложенных сущностей, например одна из списка загружаемых в запрашиваемом пакете акцизных марок уже числится в проданных.


Пример запроса:

{
	"id": [101, 102],
	"version": 1,
	"shop": 10000
}


Пример ответа:

{
	"version": 1,
	"shop": 10000,
	"errorCode": 0,
	"message": "OK",
	"packets": [{
			"id": 101,
			"status": 3,
			"errorCode": 0,
			"message": "OK"
		}, {
			"id": 102,
			"status": 1,
			"errorCode": 504,
			"message": "Неожиданное значение поля",
			"data": [{
					"field": "productType",
					"value": "2",
					"errorCode": 504,
					"message": "должно быть между 1 и 1"
				}
			]
		}
	]
}

Коды ошибок (статусы по пакетам):

Код ошибкиТекст ошибкиОписание ошибки
Ошибки при добавлении алкогольной МРЦ
201Пустой штрихкодВ запросе на добавление АМРЦ у продукта отсутствует обязательный параметр штрихкод

202

Пустой список МРЦВ запросе на добавление АМРЦ у продукта нет ни одной АМРЦ
203Остутствует значение МРЦВ запросе на добавление АМРЦ не менее чем у одной АМРЦ из списка для продукта не задано значение цены
204Пересечение дат действия МРЦВ запросе на добавление АМРЦ не менее чем у одной АМРЦ из списка для продукта пересекаются даты действия
205Дата окончания раньше даты началаВ запросе на добавление АМРЦ не менее чем у одной АМРЦ из списка для продукта дата окончания раньше даты начала
Прочие ошибки
501Не указан код маркировки

В запросе отсутствует марка (Запрос на выгрузку/удаление активных марок)

503Не поддерживаемый тип операцииУказанный в запросе тип операции не поддерживается
504Не корректное значение поляЗапрос не прошел базовую валидацию допустимых значений полей(отсутствует обязательное поле, недопустимое значения поля). Указывается и на уровне всего пакета, и на уровне 'data'(список полей с ошибками и их подробное описание)
507По данной марке уже зарегистрирована продажаМарка из пакета на добавление активных уже числится в проданных
1000Внутренняя ошибка сервиса Внутренняя ошибка сервиса

Журнал нарушений - обратная связь по проблемным АМ/КМ (сервис на стороне ERP)

Отправляем данные по проблемным АМ с периодичностью 10 мин (настраивается в application.properties --> setmark.error.report.timer в мс).

Метод: POST

Исходящие:

{ “id” : <id>, “version”: <версия API>, “data” : [ {“packetId” : <id пакета>, “productType” : <тип товара>, “shop” : <номер магазина>, “cash” : <номер кассы>, “excise” : “ <АМ>”, “barcode” : “ <ШК>”, “promoBarcode” : “ <ШК>”, “timestamp” : “<дата и время>”, “errorCode” : <код ошибки>, “message” : <сообщение> }, ...  ] }


Значения:

  • id - число, генерируется сервисом
  • version - число(значения -  {1})
  • data - массив json:
    • packetId - число
    • productType - число, обязательное поле  (значения - {1 - алкоголь, 2 - табак, ... })
    • inn - строка
    • shop - число
    • cash - число
    • excise - строка
    • barcode - строка
    • promoBarcode - строка
    • timestamp - дата (формат дата регулируется в конфигурации SetMark - параметр "spring.jackson.date-format" в aplication.properties)
    • errorCode - число
    • message - строка


Пример запроса от сервиса к ERP:

{
	"id": -2025307452,
	"version": 1,
	"data": [
		{
			"packetId": 0,
			"productType": 1,
            "inn": "0000000000",
			"shop": 10000,
			"cash": 25,
			"excise": "excise12340000101004",
			"barcode": null,
			"promoBarcode": null,
			"timestamp": "2021-11-23T14:17:35+0300",
			"errorCode": 3,
			"message": "Продажа АМ без запаса"
		}, {
			"packetId": 0,
			"productType": 1,
            "inn": "0000000000",
			"shop": 10000,
			"cash": 26,
			"excise": "excise12340000101005",
			"barcode": null,
			"promoBarcode": null,
			"timestamp": "2021-11-23T14:17:35+0300",
			"errorCode": 3,
			"message": "Продажа АМ без запаса"
		}
	]
}

Пример запроса от сервиса к ERP (ошибка проверки КМ в ОИСМ):

Значения

  • errorCode - 17, код ошибки, переданной кассой в SM. В дальнейшем, при появлении новых типов ошибок передаваемых кассой, "errorCode" сохранит свое значение как 17.
  • properties - структура, содержит информацию о конкретном значении конкретного параметра связанного с ошибкой, полученной кассой из внешней системы (в данном случае ОИСМ). 
  • message - "Ошибка проверки КМ в ОИСМ". Для данного нарушения является константой.
  • externalErrorCode - 18, цифровой идентификатор ошибки, возникающей при проверке КМ в ОИСМ (соответствует тексту "Ошибка проверки КМ в ОИСМ").
  • TAG_2106 - ФФД1.2, тег "результат проверки сведений о товаре" в который записывается и в дальнейшем передается в ОФД, результат проверки кода маркировки в ОИСМ.
{
	"id": -2025307452,
	"version": 1,
	"data": [
		{
			"shop": 10000,
			"packetId": 0,
			"productType": 3,
			"cash": 25,
			"excise": "01066000000000092163c6724594ba4240640191ffd092Hncw1Ydy8EmpvyzbeyqEe9/aiw8cG7op8LPwU03vLPbn+G0dZNRQQu6cDqlCYQWPtBxY+3cqJgd2caC1VuStIg==",
			"barcode": "6600000000009",
			"timestamp": "2021-11-23T13:17:35+0300",
			"errorCode": 17,
			"message": "Ошибка проверки КМ в ОИСМ",
			"externalErrorCode": 18,
			"properties": {
				"TAG_2106": "11"
			}
		}
	]
}


Список кодов ошибок

начиная с версии 1.3

Код ошибкиТекст ошибкиОписаниеТип товара
Ошибки, возникающие на этапе добавления товара в чек
1

Марка не соответствует товару по алкокоду. Продажа невозможна. Передача товара покупателю запрещена!

Не пройдена проверка соответствия АМ и товара по алкокодуалкоголь
2Товар с этой маркой был продан ранее. Продажа невозможна. Передача товара покупателю запрещена!Попытка повторной продажи уже проданной маркой.все
3

Товара с такой маркой нет на остатках магазина. Продажа невозможна. Передача товара покупателю запрещена!

Марка при продаже не найдена в активных для заданного магазина (неизвестная АМ или неверный номер магазина).все
4

Чек не зарегистрирован в системе ЕГАИС. Передача товара покупателю запрещена!

Касса не смогла продать АМ из-за ошибки ЕГАИС.алкоголь
5

Товар с такой маркой в этом магазине не продавался. Возврат не возможен.

Попытка возврата марки, которой нет в проданных.все
6Марка не соответствует товару по штрихкоду. Продажа невозможна. Передача товара покупателю запрещена!Не пройдена проверка соответствия АМ и товара по штрихкодуалкоголь
7Цена товара ниже установленной МРЦ. Продажа невозможна. Передача товара покупателю запрещена!Цена товара ниже загруженной АМРЦ.алкоголь
8На товар не установлена МРЦ. Продажа невозможна. Передача товара покупателю запрещена!Не найдена АМРЦ для товара.алкоголь
9Невозможно определить компонент по АМ. Сканируйте сначала ШК с бутылки.Не удалось определить компонент промонабора на основе АМ (ШК не был передан вместе с товаром).алкоголь

10

Товар не найден в составе промонабора. Продажа невозможна. Передача товара покупателю запрещена!

Не удалось определить компонент промонабора по переданному ШК.алкоголь
11Введена не корректная марка. Продажа невозможна. Передача товара покупателю запрещена!АМ не прошла проверку на корректность (формато-логический контроль) по регулярному выражению.алкоголь
12Марка не соответствует товару по артикулу. Продажа невозможна. Передача товара покупателю запрещена!Не пройдена проверка соответствия АМ и товара по артикулуалкоголь

13

Блок с этой пачкой был продан ранее. Продажа невозможна. Передача товара покупателю запрещена!

Попытка продажи пачки, которая уже была продана в составе блока

табак

14

Пачка из этого блока была продана ранее.
Продажа невозможна. Передача товара покупателю запрещена!

Попытка продажи блока, который уже был расформирован

табак

15

Пачка продавалась в составе блока. Возврат товара не возможен.

Попытка вернуть пачку, которая была продана в составе блока.

табак

16

Блок был расформирован.
Возврат товара не возможен.

Попытка вернуть блок, который был расформирован

табак

17Получено сообщение об ошибке от кассовой системыЗапись в журнал нарушений по запросу из кассовой системыкроме Алко
18Товара с такой маркой нет на остатках Юр.лица. Продажа невозможна. Передача товара покупателю запрещена!

Проверка доступной для продажи марки на остатках при условии:

  • setmark.check.inn=true. Контроль ИНН включен
  • setmark.check.inn=false. ИНН передан в запросе и сохранен к марке
кроме Алко
19Товар с такой маркой продан другим юрлицом. Возврат невозможен.

Проверка возвращаемой марки в списке поданных при условии:

  • setmark.check.inn=true. Контроль ИНН включен
  • setmark.check.inn=false. ИНН передан в запросе и сохранен к марке
кроме Алко
Ошибки, возникающие на этапе проверки чека перед регистрацией (начиная в версии 1.4)
2В чеке есть товар с маркой, который был продан ранее. Продажа невозможна. Передача покупателю товара запрещена!

201В чеке есть товар с маркой, который был возвращен ранее. Возврат не возможен.

202В чеке есть товар с маркой, которая не продавалась в магазине. Возврат не возможен.

203В чеке есть товар с маркой, которая зарезервирована для продажи на кассе №Х. Продажа невозможна. Передача покупателю товара запрещена!

204В чеке есть товар с маркой, которая зарезервирована для возврата на кассе №Х. Продажа невозможна. Передача покупателю товара запрещена!

205

В чеке есть блок и пачка из этого блока.
Продажа невозможна. Передача покупателю товара запрещена!

В чеке есть блок и пачка из этого блока.
Продажа невозможна. Передача покупателю товара запрещена!

табак

206

В чеке есть блок и пачка из этого блока.
Возврат не возможен.

В чеке есть блок и пачка из этого блока.
Возврат не возможен.

табак

Ошибки, возникающие на этапе регистрации чека в SetMark
100С кассы получен чек продажи с маркой, которая ранее была зарегистрирована как проданная в другом чекеИз кассы пришел чек с маркой, которая числится в SetMark как проданная по другому чекувсе
101С кассы получен дубликат чека продажи, в котором есть марка, которая отсутствует в оригинальном чеке продажи в SetMarkИз кассы пришел чек продажи. В SetMark уже зарегистрированы марки по чеку продажи с таким же номером, однако чек полученный с кассы не является полным дубликатом: в новом чеке есть марка, которой не было в ранее зарегистрированном чеке SetMark.все
102С кассы получен дубликат чека продажи, в котором отсутствует марка, которая есть в оригинальном чеке продажи в SetMarkИз кассы пришел чек продажи. В SetMark уже зарегистрированы марки по чеку продажи с таким же номером, однако чек полученный с кассы не является полным дубликатом: в новом чеке, пришедшем с кассы не хватает марка, которая есть в ранее зарегистрированном чеке в SetMark.все
103С кассы получен чек возврата с маркой, которая ранее была зарегистрирована как возвращеннаяИз кассы пришел чек с марка, которая числится в SetMark как возвращеннаявсе
104С кассы получен чек возврата с маркой, которой в SetMark нет в списке проданныхИз кассы пришел чек возврата с маркой, которой нет ни в списке проданных, ни в списке активныхвсе
105С кассы получен чек с маркой, статус которой в SetMark не однозначенИз кассы пришел чек с маркой, которая в SetMark числится как возвращенная и проданная одновременно (реализовано только для чека возврата)все

106

С кассы получен чек продажи с маркой пачки, которая была продана ранее в составе блока

Из кассы пришел чек продажи с маркой пачки, которая числится в SetMark проданной в составе блока

табак

107

С кассы получен чек продажи с маркой блока, который был расформирован

Из кассы пришел чек продажи с маркой блока, который числится в SetMark расформированным

табак

108

С кассы получен чек возврат с маркой пачки, которая была продана ранее в составе блока

Из кассы пришел чек возврата с маркой пачки, которая числится в SetMark проданной в составе блока

табак

109

С кассы получен чек возврата с маркой блока, который был расформирован

Из кассы пришел чек возврата с маркой блока, который числится в SetMark расформированным

табак

110Товар с маркой был продан на кассе в офлайн режиме. Проданная марка отсутствует на остатках
все
Другие ошибки
1000Внутренняя ошибка сервисаНеизвестная ошибка. Внутренняя ошибка сервиса.

до версии 1.3

Код ошибкиТекст ошибкиОписание
Ошибки, возникающие на этапе добавления товара в чек
1АМ не соответствует товаруНе пройдена проверка соответствия АМ и товара по алкокоду
2Повторная продажаПопытка продажи или загрузки из ERP уже проданной АМ.
3Продажа АМ без запасаАМ при продаже не найдена в активных для заданного магазина (неизвестная АМ или неверный номер магазина).
4Отказ ЕГАИСКасса не смогла продать АМ из-за ошибки ЕГАИС.
5Возврат ранее не проданной АМПопытка возврата АМ которой нет в проданных.
6АМ не соответствует товаруНе пройдена проверка соответствия АМ и товара по штрихкоду
7Товар запрещен к продаже (Цена ниже МРЦ)Цена товара ниже загруженной АМРЦ.
8Товар запрещен к продаже (Отсутствует МРЦ)Не найдена АМРЦ для товара.
9Невозможно определить компонент по АМНе удалось определить компонент промонабора на основе АМ (ШК не был передан вместе с товаром).

10

Товар не найден в составе промонабораНе удалось определить компонент промонабора по переданному ШК.
11Введена не корректная АМАМ не прошла проверку на корректность (формато-логический контроль) по регулярному выражению.
12АМ не соответствует артикулу товара, продажа запрещенаНе пройдена проверка соответствия АМ и товара по артикулу
Ошибки, возникающие на этапе регистрации чека в SetMark
100Из кассы получен чек продажи с АМ, которая ранее была зарегистрирована как проданная в другом чекеИз кассы пришел чек с АМ, которая числится в SetMark как проданная по другому чеку
101Из кассы получен дубликат чека продажи, в котором есть АМ, которая отсутствует в оригинальном чеке продажи в SetMarkИз кассы пришел чек продажи. В SetMark уже зарегистрированы АМ по чеку продажи с таким же номером, однако чек полученный с кассы не является полным дубликатом: в новом чеке есть АМ, которой не было в ранее зарегистрированном чеке SetMark.
102Из кассы получен дубликат чека продажи, в котором отсутствует АМ, которая есть в оригинальном чеке продажи в SetMarkИз кассы пришел чек продажи. В SetMark уже зарегистрированы АМ по чеку продажи с таким же номером, однако чек полученный с кассы не является полным дубликатом: в новом чеке, пришедшем с кассы не хватает АМ, которая есть в ранее зарегистрированном чеке в SetMark.
103Из кассы получен чек возврата с АМ, которая ранее была зарегистрирована как возвращеннаяИз кассы пришел чек с АМ, которая числится в SetMark как возвращенная
104Из кассы получен чек возврата с АМ, которой в SetMark нет в списке проданныхИз кассы пришел чек возврата с АМ, которой нет ни в списке проданных, ни в списке активных
105Из кассы получен чек с АМ, статус которой в SetMark не однозначенИз кассы пришел чек с АМ, которая в SetMark числится как возвращенная и проданная одновременно (реализовано только для чека возврата)
Другие ошибки
1000Внутренняя ошибка сервисаНеизвестная ошибка. Внутренняя ошибка сервиса.

© 1994-2023, ООО «Кристалл Сервис Интеграция».
Все права защищены..

Политика обработки персональных данных