Implemented spreadsheet logic
This commit is contained in:
@@ -141,6 +141,9 @@ public class GepafinConstant {
|
||||
public static final String UPDATING_FORM_VALUE_IMPACT_ON_FLOW = "updating.form.value.impact.on.flow";
|
||||
public static final String APPLICATION_IS_INCOMPLETE_MSG = "application.is.incomplete";
|
||||
public static final String AUTHORIZATION = "Authorization";
|
||||
public static final String BEARER_PREFIX = "Bearer ";
|
||||
public static final String SPREADSHEET = "spreadsheet";
|
||||
public static final String TEMPLATE = "template";
|
||||
public static final String CHECK_VATNUMBER_URL_V1 = "https://imprese.openapi.it/advance";
|
||||
public static final String CHECK_VATNUMBER_URL_V2 = "https://company.openapi.com/IT-advanced";
|
||||
public static final String VAT_CHECK_API_VERSION = "VAT_CHECK_API_VERSION";
|
||||
|
||||
@@ -20,8 +20,14 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.json.JSONObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.client.RestClientException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
@@ -157,6 +163,12 @@ public class ApplicationEvaluationDao {
|
||||
@Value("${default.hub.uuid}")
|
||||
private String defaultHubUuid;
|
||||
|
||||
@Value("${excel.fill.api.url}")
|
||||
private String excelFillApiUrl;
|
||||
|
||||
@Value("${excel.fill.api.token:}")
|
||||
private String excelFillApiToken;
|
||||
|
||||
@Autowired
|
||||
private ApplicationSignedDocumentRepository applicationSignedDocumentRepository;
|
||||
|
||||
@@ -762,6 +774,11 @@ public class ApplicationEvaluationDao {
|
||||
|
||||
// Map<String, String> placeHolders = notificationDao.sendNotificationToBeneficiary(application, NotificationTypeEnum.EVALUATION_CREATION);
|
||||
|
||||
// V2 only, idempotent: runs on every create/update of application evaluation (e.g. evaluation created at
|
||||
// instructor assignment). External fill API is called only for spreadsheet fields that still have no stored
|
||||
// value. If APPLICATION_EVALUATION_FORM / spreadsheet rows were created here earlier, later
|
||||
// createApplicationEvaluation and plain updates skip re-fill and leave existing flow unchanged.
|
||||
populateSpreadsheetEvaluationFormFieldsForV2(application, entity);
|
||||
Map<String, String> placeHolders = new HashMap<>();
|
||||
placeHolders.put("{{call_name}}", application.getCall().getName());
|
||||
String protocolNumber=application.getProtocol().getExternalProtocolNumber();
|
||||
@@ -2190,6 +2207,118 @@ public class ApplicationEvaluationDao {
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluation V2 only ({@link ApplicationEntity#getEvaluationVersion()}).
|
||||
* <p>
|
||||
* Ensures {@link ApplicationEvaluationFormEntity} exists for the call's evaluation form, then for each
|
||||
* {@code spreadsheet} field calls the external fill API and saves {@code APPLICATION_EVALUATION_FORM_FIELD}
|
||||
* only when that field has no stored value yet. Safe when this runs at assignment-time (first evaluation create)
|
||||
* and on later {@code createOrUpdateApplicationEvaluation} updates: no second API call and no overwrite once a
|
||||
* value is present. {@link #createApplicationEvaluation} continues to work: it reuses the same form row via
|
||||
* {@link #getApplicationEvaluationFormOrCreate}.
|
||||
*/
|
||||
private void populateSpreadsheetEvaluationFormFieldsForV2(ApplicationEntity application, ApplicationEvaluationEntity entity) {
|
||||
if (!EvaluationVersionEnum.V2.getValue().equals(application.getEvaluationVersion())) {
|
||||
return;
|
||||
}
|
||||
EvaluationFormEntity evaluationFormEntity = evaluationFormRepository.findByCallIdAndIsDeletedFalse(application.getCall().getId());
|
||||
if (evaluationFormEntity == null) {
|
||||
return;
|
||||
}
|
||||
ApplicationEvaluationFormEntity applicationEvaluationFormEntity = getApplicationEvaluationFormOrCreate(evaluationFormEntity, entity);
|
||||
List<ContentResponseBean> contentResponseBeans = evaluationFormDao
|
||||
.convertEvaluationFormEntityToEvaluationFormResponseBean(evaluationFormEntity)
|
||||
.getContent();
|
||||
if (CollectionUtils.isEmpty(contentResponseBeans)) {
|
||||
return;
|
||||
}
|
||||
List<ApplicationFormFieldRequestBean> spreadsheetUpdates = new ArrayList<>();
|
||||
for (ContentResponseBean contentResponseBean : contentResponseBeans) {
|
||||
if (!GepafinConstant.SPREADSHEET.equals(contentResponseBean.getName())) {
|
||||
continue;
|
||||
}
|
||||
String fieldId = contentResponseBean.getId();
|
||||
Optional<ApplicationEvaluationFormFieldEntity> existingSpreadsheetField = applicationEvaluationFormFieldRepository
|
||||
.findByApplicationEvaluationFormIdAndFieldIdAndIsDeletedFalse(applicationEvaluationFormEntity.getId(), fieldId);
|
||||
if (existingSpreadsheetField.isPresent()
|
||||
&& StringUtils.isNotBlank(existingSpreadsheetField.get().getFieldValue())) {
|
||||
continue;
|
||||
}
|
||||
Object populatedSpreadsheetValue = fetchSpreadsheetValueFromExternalApi(
|
||||
application.getCall().getId(),
|
||||
application.getId(),
|
||||
contentResponseBean
|
||||
);
|
||||
if (populatedSpreadsheetValue == null) {
|
||||
log.warn("Skipping spreadsheet field {}: external API did not return a template workbook value", fieldId);
|
||||
continue;
|
||||
}
|
||||
ApplicationFormFieldRequestBean spreadsheetFieldRequest = new ApplicationFormFieldRequestBean();
|
||||
spreadsheetFieldRequest.setFieldId(fieldId);
|
||||
spreadsheetFieldRequest.setFieldValue(populatedSpreadsheetValue);
|
||||
spreadsheetUpdates.add(spreadsheetFieldRequest);
|
||||
}
|
||||
if (!spreadsheetUpdates.isEmpty()) {
|
||||
createOrUpdateMultipleFormFields(spreadsheetUpdates, applicationEvaluationFormEntity, evaluationFormEntity);
|
||||
}
|
||||
}
|
||||
|
||||
private Object fetchSpreadsheetValueFromExternalApi(Long callId, Long applicationId, ContentResponseBean spreadsheetField) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
if (StringUtils.isNotBlank(excelFillApiToken)) {
|
||||
headers.set(GepafinConstant.AUTHORIZATION, GepafinConstant.BEARER_PREFIX + excelFillApiToken);
|
||||
}
|
||||
|
||||
Map<String, Object> requestBody = new LinkedHashMap<>();
|
||||
requestBody.put("call_id", callId);
|
||||
requestBody.put("application_id", applicationId);
|
||||
requestBody.put(GepafinConstant.TEMPLATE, spreadsheetField);
|
||||
|
||||
try {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
ResponseEntity<Object> response = restTemplate.postForEntity(
|
||||
excelFillApiUrl,
|
||||
new HttpEntity<>(requestBody, headers),
|
||||
Object.class
|
||||
);
|
||||
return resolveSpreadsheetFieldValueFromApiResponse(response.getBody());
|
||||
} catch (RestClientException exception) {
|
||||
log.error("Failed to populate spreadsheet field {} from external API", spreadsheetField.getId(), exception);
|
||||
throw new CustomValidationException(Status.BAD_REQUEST,
|
||||
"Failed to populate spreadsheet field from external API for fieldId: " + spreadsheetField.getId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* External fill API returns a spreadsheet field-shaped JSON (id, name, settings, …). Persist only the
|
||||
* workbook object: {@code settings[name=template].value}. If the response is already a bare workbook
|
||||
* ({@code sheets} / {@code sheetOrder}), it is stored as-is.
|
||||
*/
|
||||
private Object resolveSpreadsheetFieldValueFromApiResponse(Object apiResponseBody) {
|
||||
if (apiResponseBody == null) {
|
||||
return null;
|
||||
}
|
||||
if (!(apiResponseBody instanceof Map<?, ?> map)) {
|
||||
return apiResponseBody;
|
||||
}
|
||||
Object settingsObj = map.get("settings");
|
||||
if (settingsObj instanceof List<?> settingsList) {
|
||||
for (Object setting : settingsList) {
|
||||
if (!(setting instanceof Map<?, ?> settingMap)) {
|
||||
continue;
|
||||
}
|
||||
Object name = settingMap.get("name");
|
||||
if (GepafinConstant.TEMPLATE.equals(name != null ? name.toString() : null)) {
|
||||
return settingMap.get("value");
|
||||
}
|
||||
}
|
||||
log.warn("External spreadsheet API returned settings[] without a template entry");
|
||||
return null;
|
||||
}
|
||||
return apiResponseBody;
|
||||
}
|
||||
|
||||
private ApplicationEvaluationFormEntity getApplicationEvaluationFormOrCreate(EvaluationFormEntity evaluationFormEntity, ApplicationEvaluationEntity applicationEvaluationEntity) {
|
||||
|
||||
ApplicationEvaluationFormEntity applicationEvaluationFormEntity = applicationEvaluationFormRepository.findByEvaluationIdAndEvaluationFormId(applicationEvaluationEntity.getId(), evaluationFormEntity.getId());
|
||||
|
||||
@@ -77,6 +77,9 @@ spring.rabbitmq.connection-timeout=120000
|
||||
app.bandi.login.url.suffix=/loginadmin
|
||||
app.confidi.login.url.suffix=/confidi
|
||||
|
||||
excel.fill.api.url=https://excel-gepafin-dev-be.bflows.ai/excel/fill
|
||||
excel.fill.api.token=a3f8c2d1e4b5a6f7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1
|
||||
|
||||
#sviluppumbria protocol
|
||||
codAoo=SVILUMBRIA-01
|
||||
sviluppumbria.username=protocollatoresvilumbria
|
||||
|
||||
Reference in New Issue
Block a user