Commit 5c3dadd8 authored by Xenia Ulyanova's avatar Xenia Ulyanova
Browse files

Добавлены тесты проверок добавления для ФВ, тест для запроса на поиск пломб.

parent 8e6e5e46
Showing with 210 additions and 39 deletions
+210 -39
......@@ -82,7 +82,7 @@ public interface DocumentDAO{
* @param returnListUuid идентификатор Возвратной Ведомости
* @return список всех найденных Пломб (номеров)
*/
List<String> findAllReturnFormationSeals(String returnListUuid);
List<String> findReturnFormationSealsByReturnList(String returnListUuid);
/**
* Находит все связи между Документом и Грузоместом
......
......@@ -76,8 +76,8 @@ public class DocumentDAOImpl implements DocumentDAO {
}
@Override
public List<String> findAllReturnFormationSeals(String returnListUuid) {
return documentMapper.findAllReturnFormationSeals(returnListUuid);
public List<String> findReturnFormationSealsByReturnList(String returnListUuid) {
return documentMapper.findReturnFormationSealsByReturnList(returnListUuid);
}
@Override
......
......@@ -31,7 +31,7 @@ public interface DocumentMapper {
List<String> findSeals(@Param("documentUuid") String documentUuid);
List<String> findAllReturnFormationSeals(@Param("returnListUuid")String returnListUuid);
List<String> findReturnFormationSealsByReturnList(@Param("returnListUuid")String returnListUuid);
DocumentRef findByUuid(@Param("documentUuid") String documentUuid);
......
......@@ -104,10 +104,11 @@
SELECT seal_number FROM document_seal_lnk seals WHERE seals.document_uuid = #{documentUuid} order by seals.seal_number
</select>
<select id="findAllReturnFormationSeals" parameterType="String" resultType="String">
SELECT seal_number FROM document_seal_lnk seals join
<select id="findReturnFormationSealsByReturnList" parameterType="String" resultType="String">
SELECT seal_number FROM document_seal_lnk seals JOIN
document_return_formation rf on rf.uuid = seals.document_uuid
WHERE rf.return_list_uuid = #{returnListUuid} and rf.deleted is FALSE
JOIN document d on d.uuid = rf.uuid
WHERE rf.return_list_uuid = #{returnListUuid} and d.deleted is FALSE
</select>
<update id="close" parameterType="map">
......
package com.cdek.warehouse.dao.document;
import com.cdek.transport.model.cargoplace.CargoPlace;
import com.cdek.transport.model.document.DocumentCargoPlaceLnk;
import com.cdek.transport.model.document.DocumentRef;
import com.cdek.transport.model.document.DocumentType;
import com.cdek.transport.model.document.PrimeIncome;
import com.cdek.transport.model.document.*;
import com.cdek.warehouse.dao.BaseDAOTest;
import com.cdek.warehouse.dao.CargoPlaceDAO;
import com.cdek.warehouse.dao.randomizer.CommonEnhancedRandomBuilder;
import com.cdek.warehouse.dao.randomizer.SealRandomizer;
import io.github.benas.randombeans.api.EnhancedRandom;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.IntStream;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.beans.HasPropertyWithValue.hasProperty;
import static org.hamcrest.beans.PropertyUtil.propertyDescriptorsFor;
import static org.junit.Assert.*;
......@@ -37,15 +38,20 @@ public class DocumentDAOTest extends BaseDAOTest {
@Autowired
private PrimeIncomeDAO primeIncomeDAO;
@Autowired
private ReturnFormationDAO returnFormationDAO;
@Autowired
private CargoPlaceDAO cargoPlaceDAO;
private SealRandomizer sealRandomizer = new SealRandomizer();
private static EnhancedRandom returnFormationRandom;
@BeforeClass
public static void init() {
enhancedRandom = CommonEnhancedRandomBuilder.getPrimeIncomeRandom();
returnFormationRandom = CommonEnhancedRandomBuilder.getReturnFormationRandom();
}
......@@ -172,9 +178,53 @@ public class DocumentDAOTest extends BaseDAOTest {
assertTrue(result.isDeleted());
}
/**
* Проверка списка пломб у документов ФВ в рамках одной и той же Возвратной ведомости.
*
*/
@Test
public void testFindReturnFormationSealsByReturnList(){
String returnListUuid = UUID.randomUUID().toString();
List<String> expectedSeals = new ArrayList<>();
IntStream.range(0, 3).forEach(i -> {
String seal = getSealNumber();
createSealedReturnFormation(returnListUuid, seal);
expectedSeals.add(seal);
});
List<String> seals = documentDAO.findReturnFormationSealsByReturnList(returnListUuid);
assertThat(seals, hasSize(3));
assertThat(seals, containsInAnyOrder(expectedSeals.toArray()));
}
@Test
public void testFindReturnFormationSealsByReturnListSkipDeleted(){
String returnListUuid = UUID.randomUUID().toString();
List<String> expectedSeals = new ArrayList<>();
IntStream.range(0, 4).forEach(i -> {
String seal = getSealNumber();
ReturnFormation document = createSealedReturnFormation(returnListUuid, seal);
if (i < 3 ) {
expectedSeals.add(seal);
} else {
//удаляем один документ
documentDAO.delete(document.getUuid());
}
});
List<String> seals = documentDAO.findReturnFormationSealsByReturnList(returnListUuid);
assertThat(seals, hasSize(3));
assertThat(seals, containsInAnyOrder(expectedSeals.toArray()));
}
private ReturnFormation createSealedReturnFormation(String returnListUuid, String seal){
ReturnFormation rf = getReturnFormationSaved(returnListUuid);
documentDAO.attachSeal(rf,seal );
return rf;
}
private PrimeIncome getPrimeIncome() {
PrimeIncome primeIncome = enhancedRandom.nextObject(PrimeIncome.class, "uuid", "dateCreated", "dateUpdated");
......@@ -182,6 +232,18 @@ public class DocumentDAOTest extends BaseDAOTest {
return primeIncome;
}
private ReturnFormation getReturnFormation() {
ReturnFormation returnFormation = returnFormationRandom.nextObject(ReturnFormation.class, "uuid", "dateCreated", "dateUpdated");
return returnFormation;
}
private ReturnFormation getReturnFormationSaved(String returnListUuid) {
ReturnFormation returnFormation = getReturnFormation();
returnFormation.setReturnListUuid(returnListUuid);
returnFormationDAO.save(returnFormation);
return returnFormation;
}
private String getSealNumber() {
String sealNumber = sealRandomizer.getRandomValue();
assertTrue(sealNumber.length() == 10);
......
......@@ -7,7 +7,7 @@ import io.github.benas.randombeans.randomizers.range.LongRangeRandomizer;
*
*/
public class SealRandomizer implements Randomizer<String> {
private LongRangeRandomizer rangeRandomizer = new LongRangeRandomizer(1000000000L,9999999999L );
private LongRangeRandomizer rangeRandomizer = new LongRangeRandomizer(1100000000L,9999999999L );
@Override
public String getRandomValue() {
return rangeRandomizer.getRandomValue().toString();
......
......@@ -133,7 +133,7 @@ public class DocumentServiceImpl implements DocumentService, InitializingBean {
@Override
public List<String> findReturnFormationSealsByReturnList(String returnListUuid) {
Assert.notNull(returnListUuid);
return documentDAO.findAllReturnFormationSeals(returnListUuid);
return documentDAO.findReturnFormationSealsByReturnList(returnListUuid);
}
@Override
......
package com.cdek.warehouse.services.operation;
import com.cdek.transport.auth.Roles;
import com.cdek.transport.model.document.DocumentType;
import com.cdek.transport.model.operation.DocumentSealOperation;
import com.cdek.transport.model.operation.OperationError;
import com.cdek.warehouse.services.interceptors.SkedSealSyncHandler;
import org.springframework.security.access.annotation.Secured;
......@@ -10,18 +12,21 @@ import org.springframework.security.access.annotation.Secured;
*/
public interface DocumentSealService {
/**
* Добавляет/удаляет печать к Документу.
* Основная проверка:
* Филиал пользователя, который добавляет пломбу к документу должен совпадать с филиалом документа. {@link com.cdek.transport.model.operation.OperationError#DOCUMENT_BELONGS_OTHER_BRANCH}
* Проверка для Добавления Пломбы:
* Валидный Номер Пломбы. Проверку производим по маске. Если номер не корректен, то возвращаем ошибку {@link com.cdek.transport.model.operation.OperationError#NOT_VALID_SEAL}
*
* Синхронизирует добавление/удаление Печати к Описи {@link SkedSealSyncHandler }
*
* @return обновленная операция со статусом и кодом ошибки (если есть)
*/
@Secured(Roles.PREFIX+Roles.ROLE_WAREHOUSE_5_UPDATE)
/**
* Добавляет/удаляет печать к Документу.
* Основная проверка:
* Филиал пользователя, который добавляет пломбу к документу должен совпадать с филиалом документа. {@link OperationError#DOCUMENT_BELONGS_OTHER_BRANCH}
* Проверка для Добавления Пломбы:
* Валидный Номер Пломбы. Проверку производим по маске. Если номер не корректен, то возвращаем ошибку {@link OperationError#NOT_VALID_SEAL}
* <p/>
* Для документа {@link DocumentType#RETURN_FORMATION} дополнительные проверки: <br/>
* 1)К документу ФВ может быть добавлена только одна пломба <br/>
* 2) Внутри одной ВВ номер пломбы должен быть уникальным <br/>
* Синхронизирует добавление/удаление Печати к Описи {@link SkedSealSyncHandler }
*
* @return обновленная операция со статусом и кодом ошибки (если есть)
*/
@Secured(Roles.PREFIX+Roles.ROLE_WAREHOUSE_5_UPDATE)
DocumentSealOperation execute(DocumentSealOperation operation);
}
......@@ -5,6 +5,7 @@ import com.cdek.transport.model.document.DocumentRef;
import com.cdek.transport.model.document.DocumentType;
import com.cdek.transport.model.document.ReturnFormation;
import com.cdek.transport.model.operation.DocumentSealOperation;
import com.cdek.transport.model.operation.OperationError;
import com.cdek.transport.model.operation.OperationType;
import com.cdek.warehouse.common.Messages;
import com.cdek.warehouse.dao.operation.DocumentSealOperationDAO;
......@@ -21,6 +22,7 @@ import java.util.List;
/**
* Имплементация {@link DocumentSealService}
*
*/
@Transactional
public class DocumentSealServiceImpl extends DocumentOperationInterceptableService<DocumentSealOperation> implements DocumentSealService {
......@@ -99,13 +101,22 @@ public class DocumentSealServiceImpl extends DocumentOperationInterceptableServi
//дополнительные проверки
if(DocumentType.RETURN_FORMATION.equals(operation.getDocumentType())){
operationRuleValidator.documentHasNoSeal(document);
String returnListUuid = ((ReturnFormation)document).getReturnListUuid();
String returnListUuid = getReturnListUuid(operation);
List<String> returnListRelatedSeals = documentService.findReturnFormationSealsByReturnList(returnListUuid);
operationRuleValidator.sealIsUnique(returnListRelatedSeals, operation.getSealNumber());
}
}
@Required
private String getReturnListUuid(DocumentSealOperation operation) {
Document rf = documentService.getDocumentByUuid(operation.getDocumentUuid());
if(null == rf){
LOGGER.error("failed to get ReturnFormation document by operation :{}" , operation);
throw new OperationException(Messages.DOCUMENT_NOT_FOUND);
}
return ((ReturnFormation)rf).getReturnListUuid();
}
@Required
public void setEditSealDAO(DocumentSealOperationDAO editSealDAO) {
this.editSealDAO = editSealDAO;
}
......
......@@ -77,7 +77,7 @@ public interface OperationRuleValidator {
/**
* Плобма валидна
* по регулярному выражению "([2-9][0-9]|[1-9][1-9]){1}(\\d){8}"
* по регулярному выражению "([1-9][1-9]|[2-9][0-9]){1}(\\d){8}"
* Целое, 10 цифр, начинается не на “0” и не на “10”
* @param sealNumber
* @throws RuleException с кодом ошибки {@link OperationError#NOT_VALID_SEAL}
......
......@@ -237,7 +237,7 @@ public class OperationRuleValidatorImpl implements OperationRuleValidator {
@Override
public void documentSealIsValid(String sealNumber) throws RuleException {
String sealFormatMatcher = "([2-9][0-9]|[1-9][1-9]){1}(\\d){8}";
String sealFormatMatcher = "([1-9][1-9]|[2-9][0-9]){1}(\\d){8}";
if (null == sealNumber || !sealNumber.matches(sealFormatMatcher)) {
throw new RuleException(OperationError.NOT_VALID_SEAL);
}
......
package com.cdek.warehouse.services.integration.operation;
import com.cdek.transport.model.document.PrimeIncome;
import com.cdek.transport.model.operation.*;
import com.cdek.transport.model.operation.DocumentSealOperation;
import com.cdek.transport.model.operation.OperationError;
import com.cdek.transport.model.operation.OperationStatus;
import com.cdek.transport.model.operation.OperationType;
import com.cdek.transport.model.sked.Sked;
import com.cdek.warehouse.dao.document.PrimeIncomeDAO;
import com.cdek.warehouse.dao.document.ReturnFormationDAO;
import com.cdek.warehouse.dao.operation.DocumentSealOperationDAO;
import com.cdek.warehouse.services.SkedService;
import com.cdek.warehouse.services.document.DocumentService;
......@@ -13,26 +17,28 @@ import com.cdek.warehouse.services.operation.DocumentSealService;
import com.cdek.warehouse.services.sync.ek4.SyncDocumentService;
import com.github.springtestdbunit.annotation.DatabaseSetup;
import com.github.springtestdbunit.annotation.DatabaseTearDown;
import org.hamcrest.*;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import java.util.List;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.*;
/**
*
*/
@DatabaseSetup(value = {"/entries/prime-income-seals-test.xml", "/entries/users-catalog.xml"})
@DatabaseSetup(value = {"/entries/prime-income-seals-test.xml", "/entries/return-formation-seals-test.xml", "/entries/users-catalog.xml"})
@DatabaseTearDown("/entries/cleaning.xml")
@ContextConfiguration(locations = {"classpath:warehouse-services-test-sync-document-service-mock.xml"})
public class DocumentSealServiceIntTest extends BaseIntegrationTest {
......@@ -44,6 +50,8 @@ public class DocumentSealServiceIntTest extends BaseIntegrationTest {
private DocumentSealOperationDAO operationDAO;
@Autowired
private PrimeIncomeDAO primeIncomeDAO;
@Autowired
private ReturnFormationDAO returnFormationDAO;
@Autowired
private DocumentService documentService;
......@@ -191,4 +199,66 @@ public class DocumentSealServiceIntTest extends BaseIntegrationTest {
verify(syncDocumentServiceMock, times(1)).addToSyncSealOperation(operationArgumentCaptor.capture(), any(Sked.class), anyString());
}
/*
* Добавление пломб к документам ФВ
*
*/
/**
* Простое добавление
*/
@Test
public void testAddSealReturnFormationOk() {
DocumentSealOperation operation = operationDAO.findByUuid("df6d8dc9-fdaa-4126-b102-6ca9787aa6c4");
operationService.execute(operation);
DocumentSealOperation executedOperation = operationDAO.findByUuid(operation.getUuid());
List<String> seals= documentService.findSeals(operation.getDocumentUuid());
assertEquals(OperationStatus.EXECUTED, executedOperation.getStatus());
assertThat(seals, hasSize(1));
assertThat(seals, Matchers.contains(operation.getSealNumber()));
}
/**
* Неудачное добалвение, не прошла проверка
* К документу ФВ может быть добавлена только одна пломба
*/
@Test
public void tesAddSealReturnFormationSecondSealFailed() {
DocumentSealOperation operation = operationDAO.findByUuid("c0287848-6bb3-47c6-9550-c420bf7f9cda");
List<String> existingSeals = documentService.findSeals(operation.getDocumentUuid());
assertThat(existingSeals, hasSize(1));
operationService.execute(operation);
DocumentSealOperation failedOperation = operationDAO.findByUuid(operation.getUuid());
assertEquals(OperationStatus.FAILED, failedOperation.getStatus());
assertEquals(OperationError.DOCUMENT_IS_SEALED.getCode(), failedOperation.getErrorCode());
//пломба не добавлена
existingSeals = documentService.findSeals(operation.getDocumentUuid());
assertThat(existingSeals, hasSize(1));
}
/**
* Неудачное добалвение, не прошла проверка
* Внутри одной ВВ номер пломбы должен быть уникальным
*/
@Test
public void testAddSealReturnFormationNotUniqueFailed() {
DocumentSealOperation operation = operationDAO.findByUuid("f7d0080a-d832-4283-8b1b-b88c1f144e48");
List<String> existingSeals = documentService.findSeals(operation.getDocumentUuid());
assertThat(existingSeals, hasSize(0));
operationService.execute(operation);
DocumentSealOperation failedOperation = operationDAO.findByUuid(operation.getUuid());
assertEquals(OperationStatus.FAILED, failedOperation.getStatus());
assertEquals(OperationError.SEAL_IS_NOT_UNIQUE.getCode(), failedOperation.getErrorCode());
//пломба не добавлена
existingSeals = documentService.findSeals(operation.getDocumentUuid());
assertThat(existingSeals, hasSize(0));
}
}
<dataset>
<document uuid="053405af-b5ea-44ae-969d-5a9fb1796626" type="PRIME_INCOME" number="12373" date="2025-11-13" user_code="6nl515t08f6" date_created="2016-03-25 19:14:46.204" date_updated="2016-03-25 19:14:46.204" current_branch="nsk_branch" warehouse_code="3o53r2h9628" description="{&quot;eng&quot;:&quot;2bb3uf381m7jpltg2f4ogd05eg&quot;}" external_id="300" sked_number="2pc3hp8n72oq8" external_date_updated="2020-08-05 09:58:53.463"/>
<document uuid="053405af-b5ea-44ae-969d-5a9fb1796626" type="PRIME_INCOME" number="12373" date="2025-11-13" user_code="6nl515t08f6" date_created="2016-03-25 19:14:46.204" date_updated="2016-03-25 19:14:46.204" current_branch="nsk_branch" warehouse_code="3o53r2h9628" description="{&quot;eng&quot;:&quot;2bb3uf381m7jpltg2f4ogd05eg&quot;}"/>
<document_prime_income uuid="053405af-b5ea-44ae-969d-5a9fb1796626" employee_deliver="6sl2sr6oi6mi4j" employee_accept="4arfa4sqm2d6" />
<document_seal_lnk uuid="28769f5a-c9c3-42a7-bdaf-a530d2598688" document_uuid="053405af-b5ea-44ae-969d-5a9fb1796626" seal_number="2462180794" />
......
<dataset>
<!--документ ФВ RF/nsk_branch/1 -->
<document uuid="03e4b511-c8b1-4342-8964-59b73f137763" type="RETURN_FORMATION" number="RF/nsk_branch/1" user_code="user_code" current_branch="nsk_branch" warehouse_code="warehouse_1" description="{}" deleted="false" date="2017-09-09" date_created="2017-09-09 00:00:00" date_updated="2017-09-09 00:00:00" />
<document_return_formation uuid="03e4b511-c8b1-4342-8964-59b73f137763" return_list_uuid="a1c218e9-9b60-43b0-aa9d-e9dd43fc4f24" cargo_place_uuid="bf60d5b9-13cb-4d17-8c27-80c9736ccbf3" />
<!--документ ФВ RF/nsk_branch/2 -->
<document uuid="6918ec5b-654f-4148-bf90-490e93c2413b" type="RETURN_FORMATION" number="RF/nsk_branch/2" user_code="user_code" current_branch="nsk_branch" warehouse_code="warehouse_1" description="{}" deleted="false" date="2017-09-09" date_created="2017-09-09 00:00:00" date_updated="2017-09-09 00:00:00" />
<document_return_formation uuid="6918ec5b-654f-4148-bf90-490e93c2413b" return_list_uuid="a1c218e9-9b60-43b0-aa9d-e9dd43fc4f24" cargo_place_uuid="0d1caeef-2f89-404b-9c99-f7ede1a3b08c" />
<!--удачное добавление к документу RF/nsk_branch/1-->
<operation uuid="df6d8dc9-fdaa-4126-b102-6ca9787aa6c4" type="DOCUMENT_ADD_SEAL" document_type="RETURN_FORMATION" status="NEW" user_code="user_code" date_created="2016-04-08 14:27:48.365" date_updated="2016-04-08 14:27:48.366" />
<operation_document_seal uuid="df6d8dc9-fdaa-4126-b102-6ca9787aa6c4" document_uuid="03e4b511-c8b1-4342-8964-59b73f137763" seal_number="4444444444" />
<!--неудачное добавление, у документа RF/nsk_branch/2 уже есть пломба -->
<operation uuid="c0287848-6bb3-47c6-9550-c420bf7f9cda" type="DOCUMENT_ADD_SEAL" document_type="RETURN_FORMATION" status="NEW" user_code="user_code" date_created="2016-04-08 14:27:48.361" date_updated="2016-04-08 14:27:48.361" />
<operation_document_seal uuid="c0287848-6bb3-47c6-9550-c420bf7f9cda" document_uuid="6918ec5b-654f-4148-bf90-490e93c2413b" seal_number="4581730742" />
<!--неудачное добавление, плобма не уникальна, у документа RF/nsk_branch/2 уже есть такая пломба -->
<operation uuid="f7d0080a-d832-4283-8b1b-b88c1f144e48" type="DOCUMENT_ADD_SEAL" document_type="RETURN_FORMATION" status="NEW" user_code="user_code" date_created="2016-04-08 14:27:48.365" date_updated="2016-04-08 14:27:48.366" />
<operation_document_seal uuid="f7d0080a-d832-4283-8b1b-b88c1f144e48" document_uuid="03e4b511-c8b1-4342-8964-59b73f137763" seal_number="4412345678" />
<!--Пломбы документов -->
<document_seal_lnk uuid="4d9a989b-960d-44ee-ba45-d7b887351fda" document_uuid="6918ec5b-654f-4148-bf90-490e93c2413b" seal_number="4412345678" />
</dataset>
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment