Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

version_1.1 #1

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,24 @@

Перечень поддерживаемых товарных групп:

### version 1.0
* Обувь ([ППР №860 от 05.07.2019](https://xn--80ajghhoc2aj1c8b.xn--p1ai/upload/860.pdf))
* Товары лёгкой промышленности ([ППР №1956 от 31.12.2019](https://xn--80ajghhoc2aj1c8b.xn--p1ai/upload/1956.pdf))
* Духи и туалетная вода ([ППР №1957 от 31.12.2019](https://xn--80ajghhoc2aj1c8b.xn--p1ai/upload/%D0%9F%D0%BE%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%9F%D1%80%D0%B0%D0%B2%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D1%82%D0%B2%D0%B0_%D0%A0%D0%A4_%D0%BE%D1%82_31_12_2019_N_1957_%D1%80%D0%B5%D0%B4_%D0%BE%D1%82_20_11.pdf))
* Молочная продукция ([ППР №2099 от 15.12.2020](https://xn--80ajghhoc2aj1c8b.xn--p1ai/upload/%D0%9F%D0%BE%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%9F%D1%80%D0%B0%D0%B2%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D1%82%D0%B2%D0%B0_%D0%A0%D0%A4_%D0%BE%D1%82_15_12_2020_N_2099_%D1%80%D0%B5%D0%B4_%D0%BE%D1%82_22_04.pdf))
* Пиво и слабоалкогольные напитки ([ППР №2173 от 30.11.2022](https://xn--80ajghhoc2aj1c8b.xn--p1ai/upload/%D0%9F%D0%BE%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%9F%D1%80%D0%B0%D0%B2%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D1%82%D0%B2%D0%B0%20%E2%84%962173.pdf))
* Упакованная вода ([ППР №841 от 31.05.2021](https://xn--80ajghhoc2aj1c8b.xn--p1ai/upload/%D0%9F%D0%BE%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%9F%D1%80%D0%B0%D0%B2%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D1%82%D0%B2%D0%B0_%D0%A0%D0%A4_%D0%BE%D1%82_31_05_2021_N_841_%D1%80%D0%B5%D0%B4_%D0%BE%D1%82_26_03.pdf))

### version 1.1
* Одежда ([ППР № 1956 от 31.12.2019г.](https://xn--80ajghhoc2aj1c8b.xn--p1ai/upload/%D0%9F%D0%BE%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%9F%D1%80%D0%B0%D0%B2%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D1%82%D0%B2%D0%B0_%D0%A0%D0%A4_%D0%BE%D1%82_31_05_2021_N_841_%D1%80%D0%B5%D0%B4_%D0%BE%D1%82_26_03.pdf))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Ссылка на упакованную воду
  2. одежда не входит уже в легкую промышленность?

* Шины ([ППР № 1958 от 31.12.2019г.](https://xn--80ajghhoc2aj1c8b.xn--p1ai/upload/%D0%9F%D0%BE%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%9F%D1%80%D0%B0%D0%B2%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D1%82%D0%B2%D0%B0_%D0%A0%D0%A4_%D0%BE%D1%82_31_05_2021_N_841_%D1%80%D0%B5%D0%B4_%D0%BE%D1%82_26_03.pdf))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Ссылка на упакованную воду
  2. Лучше ссылаться единообразно на честныйзнак.рф

* Велосипеды ([Метод рекомен от 05.11.2019г.](https://честныйзнак.рф/upload/iblock/a1e/Metodicheskie_rekomendatsii_dlya_TG_Velosipedy.pdf))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ссылка 404

* Мед.изделия ([Метод.рекомен от 27.11.2019г.](https://честныйзнак.рф/upload/iblock/4f6/Методические%20рекомендации.pdf))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Описание - это только кресло-коляски? Лучше ссылаться единообразно на честныйзнак.рф

* Фотоаппараты ([ППР № 1953 от 21.12.2019г.](https://xn--80ajghhoc2aj1c8b.xn--p1ai/upload/%D0%9F%D0%BE%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%9F%D1%80%D0%B0%D0%B2%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D1%82%D0%B2%D0%B0_%D0%A0%D0%A4_%D0%BE%D1%82_31_05_2021_N_841_%D1%80%D0%B5%D0%B4_%D0%BE%D1%82_26_03.pdf))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Ссылка на упакованную воду
  2. Лучше ссылаться единообразно на честныйзнак.рф

* БАД ([Проект ППР](https://regulation.gov.ru/projects#npa=130322))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Лучше ссылаться единообразно на честныйзнак.рф

* Антисептики ([Проект ППР](https://regulation.gov.ru/projects#npa=130584))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Лучше ссылаться единообразно на честныйзнак.рф

* Табак,АТП*, НСП* ([ППР № 224 от 28.02.2019г.](https://base.garant.ru/72189916/))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Лучше ссылаться единообразно на честныйзнак.рф


# Даматарикс код можно валидировать

* **с указанием конкретной товарной группы**
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>ru.lamoda.datamatrix</groupId>
<artifactId>datamatrix-validator</artifactId>
<version>1.0</version>
<version>1.1</version>

<properties>
<maven.compiler.source>8</maven.compiler.source>
Expand Down
53 changes: 47 additions & 6 deletions src/main/java/ru/lamoda/datamatrix/model/AI.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ public ValidationResult getValidationResult(TradeGroup type, String value) {

@Override
public int getSize(TradeGroup type) {
if (type == NICOTINE) {
return getCode().length() + 12;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а почему укороченный вариант для табака только для группы AI_01 ?

}
return getCode().length() + 14;
}
},
Expand All @@ -40,7 +43,10 @@ public int getSize(TradeGroup type) {
case MILK:
return getCode().length() + 6;
case BEER:
case NICOTINE:
return getCode().length() + 7;
case CAMERAS:
return getCode().length() + 20;
default:
return getCode().length() + 13;
}
Expand All @@ -51,7 +57,7 @@ public int getSize(TradeGroup type) {
@Override
public ValidationResult getValidationResult(TradeGroup type, String value) {
return notBlank
.and(checkTradeGroup(type, SHOES, LP, PERFUMERY))
.and(checkTradeGroup(type, ANTISEPTIC, BICYCLES, CAMERAS, CLOTHES, DS, LP, MP, PERFUMERY, SHOES, TIRES))
.and(fixedSize(getSize(type)))
.and(checkRegex(GS1_ISO_SUBSET_FOR_CONTROL_NUMBER))
.test(value);
Expand All @@ -60,9 +66,16 @@ public ValidationResult getValidationResult(TradeGroup type, String value) {
@Override
public int getSize(TradeGroup type) {
switch (type) {
case SHOES:
case ANTISEPTIC:
case BICYCLES:
case CAMERAS:
case CLOTHES:
case DS:
case LP:
case MP:
case PERFUMERY:
case SHOES:
case TIRES:
return getCode().length() + 4;
default:
return 0;
Expand All @@ -74,7 +87,7 @@ public int getSize(TradeGroup type) {
@Override
public ValidationResult getValidationResult(TradeGroup type, String value) {
return notBlank
.and(checkTradeGroup(type, BEER, WATER, MILK))
.and(checkTradeGroup(type, ANTISEPTIC, BEER, DS, WATER, MILK))
.and(fixedSize(getSize(type)))
.and(checkRegex(GS1_ISO_SUBSET_FOR_CONTROL_NUMBER))
.test(value);
Expand All @@ -83,9 +96,11 @@ public ValidationResult getValidationResult(TradeGroup type, String value) {
@Override
public int getSize(TradeGroup type) {
switch (type) {
case ANTISEPTIC:
case BEER:
case DS:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

кажется табак тоже должен здесь быть

case MILK:
case WATER:
case BEER:
return getCode().length() + 4;
default:
return 0;
Expand All @@ -97,7 +112,7 @@ public int getSize(TradeGroup type) {
@Override
public ValidationResult getValidationResult(TradeGroup type, String value) {
return notBlank
.and(checkTradeGroup(type, PERFUMERY, SHOES, LP))
.and(checkTradeGroup(type, SHOES, ANTISEPTIC, BICYCLES, CAMERAS, CLOTHES, DS, LP, MP, PERFUMERY, TIRES))
.and(fixedSize(getSize(type)))
.and(checkRegex(GS1_ISO_SUBSET_FOR_CRYPTO_TAIL))
.test(value);
Expand All @@ -108,8 +123,15 @@ public int getSize(TradeGroup type) {
switch (type) {
case SHOES:
return getCode().length() + 88;
case PERFUMERY:
case ANTISEPTIC:
case BICYCLES:
case CAMERAS:
case CLOTHES:
case DS:
case LP:
case MP:
case PERFUMERY:
case TIRES:
return getCode().length() + 44;
default:
return 0;
Expand Down Expand Up @@ -155,6 +177,25 @@ public int getSize(TradeGroup type) {
}
},

AI_8005("8005", false) {
@Override
public ValidationResult getValidationResult(TradeGroup type, String value) {
return notBlank
.and(checkTradeGroup(type, NICOTINE))
.and(fixedSize(getSize(type)))
.and(onlyNumbers())
.test(value);
}

@Override
public int getSize(TradeGroup type) {
if (type == NICOTINE) {
return getCode().length() + 6;
}
return 0;
}
},

AI_335Y("335", false) {
@Override
public ValidationResult getValidationResult(TradeGroup type, String value) {
Expand Down
46 changes: 45 additions & 1 deletion src/main/java/ru/lamoda/datamatrix/model/TradeGroup.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ru.lamoda.datamatrix.model;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static java.util.Arrays.asList;
Expand Down Expand Up @@ -38,10 +39,53 @@ public enum TradeGroup {
* Товары лёгкой промышленности
*/
LP(AI_01, AI_21, AI_91, AI_92),
/**
* Одежда
*/
CLOTHES(AI_01, AI_21, AI_91, AI_92),
/**
* Парфюмерия
*/
PERFUMERY(AI_01, AI_21, AI_91, AI_92);
PERFUMERY(AI_01, AI_21, AI_91, AI_92),
/**
* Шины
*/
TIRES(AI_01, AI_21, AI_91, AI_92),
/**
* Велосипеды
*/
BICYCLES(AI_01, AI_21, AI_91, AI_92),
/**
* Мед. изделия - Medical products
*/
MP(AI_01, AI_21, AI_91, AI_92),
/**
* Фотоаппараты
*/
CAMERAS(AI_01, AI_21, AI_91, AI_92),
/**
* БАДы - dietary supplement
*/
DS(
asList(AI_01, AI_21, AI_93),
asList(AI_01, AI_21, AI_91, AI_92)
),
/**
* Антисептики
*/
ANTISEPTIC(
asList(AI_01, AI_21, AI_93),
asList(AI_01, AI_21, AI_91, AI_92)
),
/**
* Никотин-содержащая продукция - Nicotine-containing products
*/
NICOTINE(
Collections.emptyList(),
Collections.singletonList(AI_01),
asList(AI_01, AI_21, AI_93),
asList(AI_01, AI_21, AI_8005, AI_93)
);

/**
* Список поддерживаемых форматов для каждой товарной группы
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,19 +103,23 @@ private static List<AI> splitToAis(String datamatrixCode, TradeGroup type) {
List<AI> ais = Arrays.stream(AI.values())
.filter(ai -> part.startsWith(ai.getCode()))
.collect(Collectors.toList());
if (ais.size() == 0) {
throw new DatamatrixCodeIncorrectException("unknown AI");
}
for (AI identifier : ais) {
if (!identifier.isFixedSize()) {
identifier.validateThrow(type, part);
result.add(identifier);
} else {
String begin = part.substring(0, identifier.getSize(type));
identifier.validateThrow(type, begin);
result.add(identifier);
result.addAll(splitToAis(part.substring(identifier.getSize(type)), type));
if (!ais.isEmpty()) {
for (AI identifier : ais) {
if (!identifier.isFixedSize()) {
identifier.validateThrow(type, part);
result.add(identifier);
} else {
String begin = part.substring(0, identifier.getSize(type));
identifier.validateThrow(type, begin);
result.add(identifier);
result.addAll(splitToAis(part.substring(identifier.getSize(type)), type));
}
}
} else if (datamatrixCode.length() == 29 || datamatrixCode.length() == 15) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а откуда взялись цифры 29 и 15 ?
из символов по группам 01 (14), 21 (7), 93 (4) / 01 (14), 21 (7), 8005 (6), 93 (4) вроде как не складывается?

//for short NICOTINE
return result;
} else {
throw new DatamatrixCodeIncorrectException("unknown AI");
}
}
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ public static Validation<String> notContainsDoubleGS() {
}

public static Validation<String> containsGS() {
return SimpleValidation.from((s) -> contains(s, GS), "must contain <GS>");
return SimpleValidation.from((s) -> contains(s, GS) || s.length() == 29,
"must contain <GS> or code length must be 29 characters");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а почему только 29, а 15 не может быть ?

}

public static Validation<String> onlyNumbers() {
Expand Down
70 changes: 70 additions & 0 deletions src/test/java/ru/lamoda/datamatrix/DatamatrixValidatorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ public static Object[][] badDatamatrixList() {
String beerCodeWithWrongVolumeSize = "0104610053147452215d,OiLl\u001D93dGVz\u001D335112345";
String withUnknownCode = "0104610053149777215d/wuU\u001D93dGVz\u001D88dGVz";
String withDoubleCode = "0104653820923088215GoNfWgdcBeVZ\u001D93dGVz\u001D93dGVz";
String invalidShortNicotine = "04603731175212JEIjNYDAAAAtFw";
String invalidCamerasCode = "0102900000387843215v&XqVigrspEe95cj\"jF\u001D91FFD0\u001D";

return new Object[][]{
{null},
{""},
Expand All @@ -57,6 +60,8 @@ public static Object[][] badDatamatrixList() {
{beerCodeWithWrongVolumeSize},
{withUnknownCode},
{withDoubleCode},
{invalidShortNicotine},
{invalidCamerasCode},
};
}

Expand All @@ -69,6 +74,49 @@ public static Object[][] goodDatamatrixList() {
String beerCode = "0104610053147452215d,OiLl\u001D93dGVz";
String beerCodeWithVolume = "0104610053147452215d,OiLl\u001D93dGVz\u001D3350123456";
String lpCode = "0104669000322220215t*NH>t:ngCfH\u001D91FFD0\u001D92dGVzdBL8SAtwRqhp7H9rfyI59GoJ8ec6X9GhckDf8JE=";
// Обувь
String footwear = "0104680128320356215BWOM0ip7Ns3M91FFD092testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest";
// Одежда
String clothes = "0104669000322695215YCQ?cX3bNsD<91FFD092dGVzdMXgZt5JFLIfm/gTAGFQsN1zD3MhYdOBHhprah8=";
// Молоко
String milk = "01046690003220602156BelF93dGVz";
// Духи
String perfume = "0104669000322169215GqtjhXBO%LNp91FFD092dGVzdCR1+WbFwT1f8YoWctkvZKnLEpdiMjfsYVlNFAM=";
// Вода
String water = "01046690003222372151G'OclhkkPrJ93dGVz";
// Шины
String tires = "0104669000322152215W&r<lpN0IM),91FFD092dGVzdNsM825y2Sac/e1jg39IcBq9+/85k4UzsgB4ojM=";
// Велосипеды
String bicycles = "01046690003222992153WOb5arxriF491FFD092dGVzdIGXHttcXgubMZBcXhDYKIeiYiw4zv7JMDjjFQg=";
// Мед.изделия
String medicalProducts = "0104603225022459215cI;3t1LgW_gV\u001D91EE08\u001D92IbHShLeDs+NGo3FMCq1FB7R8a6Cun/Eyra0iLou67ek=";
// Фотоаппараты
String cameras = "0104669000322275215TXpf?A.tXlJ;ZJFn'Li\u001D91FFD0\u001D92dGVzdIPiTENrtHlgbiheL880JGjG6vjQS/UWNuxQCFs=";
// Пиво
String beer = "0104680128320615215pEB7Dc93dGVz3350000020";
// Безалкогольное пиво
String nonAlcoholicBeer = "0104653820923231215gSRo9L93dGVz";
// БАД
String dietarySupplement = "0104669000322336215GmpVhJ.c':lI93dGVz";
// БАД*
String dietarySupplement2 = "0104669000322343215TNbIpAVkQlYO91FFD092dGVzdO5In+HN3/axzPXOXDTfF9RGuqkxahFtHR7xFWg=";
String dietarySupplement3 = "0104669000322312215E%hNC\"FDPJGZ\u001D91FFD0\u001D92dGVzdCjmBI8AAwc9lVRcbJObEgae5EddDoQ1iC7Q6F4=";
// Антисептики
String antiseptics = "0104607128160164215SGa:L0UJM=cE93vSFw";
// Антисептики*
String antiseptics2 = "0104607128160164215q3Ae0:jK.Gh391EE0692B5dj5RJZB7qarLvjwxl5fd+T9mM1QgVMd8edeRNUvQQ=";
// Табак,АТП*, НСП*
String tobacco = "01230000117319RzvofwbAAAAR8n8";
// АТП
String tobacco2 = "04653820923019f4WmAnbAAAAdGVz";
// Табак,НСП
String tobacco3 = "04653820923323,Uh4H>6AAAAdGVz";
String nicotine = "04603731175212JEIjNYDAAAAtFwS";
// Безалкогольное пиво
String nonAlcoholicBeer2 = "0104653820923231215gSRo9L93dGVz";
// Соковая продукция и безалкогольные напитки
String juiceAndSoftDrinks = "0104653820923170215KIDz?kLcy=rp93dGVz";

return new Object[][]{
{shortShoesCode, SHOES, LP},
{longShoesCode, SHOES, LP},
Expand All @@ -78,6 +126,28 @@ public static Object[][] goodDatamatrixList() {
{beerCode, BEER, LP},
{beerCodeWithVolume, BEER, LP},
{lpCode, LP, BEER},
{footwear, SHOES, WATER},
{clothes, CLOTHES, BEER},
{milk, MILK, DS},
{perfume, PERFUMERY, WATER},
{water, WATER, BEER},
{tires, TIRES, WATER},
{bicycles, BICYCLES, SHOES},
{medicalProducts, MP, MILK},
{cameras, CAMERAS, LP},
{beer, BEER, MP},
{nonAlcoholicBeer, BEER, SHOES},
{dietarySupplement, DS, BICYCLES},
{dietarySupplement2, DS, WATER},
{dietarySupplement3, DS, MILK},
{antiseptics, ANTISEPTIC, NICOTINE},
{antiseptics2, ANTISEPTIC, WATER},
{tobacco, NICOTINE, BEER},
{tobacco2, NICOTINE, WATER},
{tobacco3, NICOTINE, ANTISEPTIC},
{nicotine, NICOTINE, SHOES},
{nonAlcoholicBeer2, BEER, WATER},
{juiceAndSoftDrinks, WATER, MILK},
};
}
}