Impl multivalue flow (#17)

* Impl multivalue flow

* Fixes
This commit is contained in:
Egor Cherniak 2023-07-04 18:37:01 +03:00 committed by GitHub
parent 577c60c239
commit de0faa7d10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 83 additions and 31 deletions

View File

@ -48,7 +48,7 @@
<dependency>
<groupId>dev.vality</groupId>
<artifactId>mayday-proto</artifactId>
<version>1.7-b2b2b3b</version>
<version>1.8-d79c25b</version>
</dependency>
<dependency>
<groupId>dev.vality</groupId>

View File

@ -0,0 +1,20 @@
package dev.vality.alert.tg.bot.config;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ObjectMapperConfig {
@Bean
public ObjectMapper jsonMapper() {
return new ObjectMapper()
.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
}
}

View File

@ -21,6 +21,7 @@ import org.telegram.telegrambots.meta.api.objects.inlinequery.result.InlineQuery
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import static dev.vality.alert.tg.bot.utils.StringSearchUtils.*;
@ -63,7 +64,7 @@ public class InlineHandler implements CommonHandler<AnswerInlineQuery> {
String alertId = substringAlertId(inlineQuery);
String paramId = substringParamId(inlineQuery);
ParametersData parametersData = parametersDao.getByAlertIdAndParamId(alertId, paramId);
List<String> options = jsonMapper.toList(parametersData.getOptionsValues());
Set<String> options = jsonMapper.toSet(parametersData.getOptionsValues());
options.forEach(optionValue -> {
if (isParamInList(optionValue, inlineQuery, alertId, paramId)) {
queryResultArticleList.add(fillInlineQueryResultArticle(

View File

@ -10,7 +10,7 @@ import org.apache.thrift.TException;
import org.springframework.stereotype.Component;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import java.util.Map;
import java.util.*;
import java.util.regex.Pattern;
@Component
@ -24,14 +24,22 @@ public class CreateParamsRequestMapper {
public SendMessage createRequest(Long userId, String paramName, String paramValue) throws TException {
StateData stateData = stateDataDao.getByUserId(userId);
Map<String, String> paramMap = jsonMapper.toMap(stateData.getMapParams());
Map<String, Set<String>> paramMap = jsonMapper.toMap(stateData.getMapParams());
ParametersData parametersData = parametersDao.getByAlertIdAndParamName(stateData.getAlertId(), paramName);
if (isParamValueMatchToProcess(parametersData, paramValue)) {
paramMap.put(paramName, paramValue);
if (isParamValueMatchToProcess(parametersData, paramValue, paramMap)) {
Set<String> values = new HashSet<>();
values.add(paramValue);
if (!paramMap.containsKey(paramName)) {
paramMap.put(paramName, values);
} else {
paramMap.get(paramName).addAll(values);
}
stateData.setMapParams(jsonMapper.toJson(paramMap));
stateDataDao.updateParams(userId, stateData.getMapParams());
}
String nextKey = getNextKeyForFill(paramMap);
String nextKey = getNextKeyForFill(paramMap, parametersData);
if (nextKey != null) {
return replyMessagesMapper.createNextParameterRequest(nextKey, stateData);
} else {
@ -39,12 +47,17 @@ public class CreateParamsRequestMapper {
}
}
private boolean isParamValueMatchToProcess(ParametersData parametersData, String paramValue) {
private boolean isParamValueMatchToProcess(ParametersData parametersData, String paramValue, Map<String,
Set<String>> providedParams) {
return (!parametersData.getMandatory()
&& (isValuePattern(paramValue, parametersData)
|| paramValue.equals(TextConstants.EMPTY_PARAM.getText())))
|| (parametersData.getMandatory() && !paramValue.equals(TextConstants.EMPTY_PARAM.getText())
&& isValuePattern(paramValue, parametersData));
|| (parametersData.getMandatory()
&& !paramValue.equals(TextConstants.EMPTY_PARAM.getText())
&& isValuePattern(paramValue, parametersData))
|| (parametersData.getMandatory()
&& paramValue.equals(TextConstants.EMPTY_PARAM.getText())
&& providedParams.containsKey(parametersData.getParamId()));
}
private boolean isValuePattern(String value, ParametersData parametersData) {
@ -55,9 +68,17 @@ public class CreateParamsRequestMapper {
return true;
}
private static String getNextKeyForFill(Map<String, String> map) {
private static String getNextKeyForFill(Map<String, Set<String>> map, ParametersData parametersData) {
return map.entrySet().stream()
.filter(entry -> null == entry.getValue())
// Если у параметра вообще нет значения
.filter(entry -> null == entry.getValue()
//Если у параметр может принимать несколько значений, а
// пользователь продолжает вводить новые значения
|| !entry.getValue().contains(TextConstants.EMPTY_PARAM.getText())
&& parametersData.getMultipleValues()
//Если параметр обязательный, но пользователь передал только пустое значение
|| entry.getValue().contains(TextConstants.EMPTY_PARAM.getText())
&& parametersData.getMandatory() && entry.getValue().size() == 1)
.findFirst().map(Map.Entry::getKey)
.orElse(null);
}

View File

@ -9,6 +9,7 @@ import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Component
@RequiredArgsConstructor
@ -22,13 +23,13 @@ public class JsonMapper {
}
@SneakyThrows(JsonProcessingException.class)
public Map<String, String> toMap(String json) {
public Map<String, Set<String>> toMap(String json) {
return objectMapper.readValue(json, new TypeReference<>() {
});
}
@SneakyThrows(JsonProcessingException.class)
public List<String> toList(String json) {
public Set<String> toSet(String json) {
return objectMapper.readValue(json, new TypeReference<>() {
});
}

View File

@ -44,8 +44,8 @@ public class ParametersCallbackMapper {
List<ParameterConfiguration> parameterConfigurations) {
StateData stateData = stateDataDao.getByUserId(userId);
stateData.setAlertId(alertId);
Map<String, String> mapParams = new HashMap<>();
parameterConfigurations.forEach(param -> mapParams.put(param.getName(), null));
Map<String, List<String>> mapParams = new HashMap<>();
parameterConfigurations.forEach(param -> mapParams.put(param.getName(), new ArrayList<>()));
stateData.setMapParams(jsonMapper.toJson(mapParams));
stateDataDao.save(stateData);
}
@ -55,12 +55,13 @@ public class ParametersCallbackMapper {
parametersData.setAlertId(alertId);
parametersData.setParamId(param.getId());
parametersData.setParamName(param.getName());
List<String> options = param.isSetOptions() ? new ArrayList<>(param.getOptions()) : null;
if (options != null && !param.isMandatory()) {
Set<String> options = param.isSetOptions() ? new HashSet<>(param.getOptions()) : null;
if (options != null && (!param.isMandatory() || param.isMultipleValues())) {
options.add(TextConstants.EMPTY_PARAM.getText());
}
String optionsValues = jsonMapper.toJson(options);
parametersData.setOptionsValues(optionsValues);
parametersData.setMultipleValues(param.isMultipleValues());
parametersData.setMandatory(param.isMandatory());
parametersData.setValueRegexp(param.getValueRegexp());
parametersDao.save(parametersData);

View File

@ -15,9 +15,9 @@ import org.apache.thrift.TException;
import org.springframework.stereotype.Component;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static dev.vality.alert.tg.bot.utils.MainMenuBuilder.buildMainInlineKeyboardMarkup;
@ -34,18 +34,23 @@ public class ReplyMessagesMapper {
public SendMessage createAlertRequest(long userId) throws TException {
StateData stateData = stateDataDao.getByUserId(userId);
log.info("Start create alert with stateData {}", stateData);
Map<String, String> paramMap = jsonMapper.toMap(stateData.getMapParams());
Map<String, Set<String>> paramMap = jsonMapper.toMap(stateData.getMapParams());
CreateAlertRequest createAlertRequest = new CreateAlertRequest();
createAlertRequest.setAlertId(stateData.getAlertId());
createAlertRequest.setUserId(String.valueOf(userId));
List<ParameterInfo> parameterInfos = new ArrayList<>();
for (String key : paramMap.keySet()) {
ParametersData parametersData = parametersDao.getByAlertIdAndParamName(stateData.getAlertId(), key);
ParameterInfo parameterInfo = new ParameterInfo();
parameterInfo.setId(parametersData.getParamId());
parameterInfo.setValue(paramMap.get(key));
parameterInfos.add(parameterInfo);
}
List<ParameterInfo> parameterInfos =
paramMap.entrySet().stream()
.flatMap(entry -> {
ParametersData parametersData =
parametersDao.getByAlertIdAndParamName(stateData.getAlertId(), entry.getKey());
return entry.getValue().stream()
.map(value -> {
ParameterInfo parameterInfo = new ParameterInfo();
parameterInfo.setId(parametersData.getParamId());
parameterInfo.setValue(value);
return parameterInfo;
}).toList().stream();
}).toList();
createAlertRequest.setParameters(parameterInfos);
mayDayService.createAlert(createAlertRequest);
SendMessage message = new SendMessage();

View File

@ -0,0 +1,2 @@
ALTER TABLE alert_tg_bot.parameters_data
ADD COLUMN IF NOT EXISTS multiple_values BOOL DEFAULT false;

View File

@ -15,7 +15,7 @@ public abstract class TestObjectFactory {
StateData stateData = new StateData();
stateData.setUserId(122233L);
stateData.setAlertId("45");
stateData.setMapParams("{\"Процент\":34,\"Имя Терминала\":56}");
stateData.setMapParams("{\"Процент\":[34],\"Имя Терминала\":[56]}");
return stateData;
}
@ -26,6 +26,7 @@ public abstract class TestObjectFactory {
params.setParamId("14");
params.setOptionsValues("[\"test1\",\"test2\"]");
params.setMandatory(false);
params.setMultipleValues(false);
return params;
}

View File

@ -45,12 +45,12 @@ class StateDaoImplTest {
@Test
void updateParams() {
StateData stateData = TestObjectFactory.testStateData();
stateData.setMapParams("{\"Процент\":56,\"Имя Терминала\":test}");
stateData.setMapParams("{\"Процент\":[56],\"Имя Терминала\":[test]}");
dslContext.insertInto(STATE_DATA)
.set(dslContext.newRecord(STATE_DATA, stateData))
.execute();
String newMapParams = "{\"Процент\":56,\"Имя Терминала\":new}";
String newMapParams = "{\"Процент\":[56],\"Имя Терминала\":[new]}";
stateDataDao.updateParams(stateData.getUserId(), newMapParams);
StateDataRecord stateDataRecord = dslContext.fetchAny(STATE_DATA);