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 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 APPLICATION_IS_INCOMPLETE_MSG = "application.is.incomplete";
|
||||||
public static final String AUTHORIZATION = "Authorization";
|
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_V1 = "https://imprese.openapi.it/advance";
|
||||||
public static final String CHECK_VATNUMBER_URL_V2 = "https://company.openapi.com/IT-advanced";
|
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";
|
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.json.JSONObject;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
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.stereotype.Component;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
import org.springframework.web.client.RestClientException;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
@@ -157,6 +163,12 @@ public class ApplicationEvaluationDao {
|
|||||||
@Value("${default.hub.uuid}")
|
@Value("${default.hub.uuid}")
|
||||||
private String defaultHubUuid;
|
private String defaultHubUuid;
|
||||||
|
|
||||||
|
@Value("${excel.fill.api.url}")
|
||||||
|
private String excelFillApiUrl;
|
||||||
|
|
||||||
|
@Value("${excel.fill.api.token:}")
|
||||||
|
private String excelFillApiToken;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ApplicationSignedDocumentRepository applicationSignedDocumentRepository;
|
private ApplicationSignedDocumentRepository applicationSignedDocumentRepository;
|
||||||
|
|
||||||
@@ -762,6 +774,11 @@ public class ApplicationEvaluationDao {
|
|||||||
|
|
||||||
// Map<String, String> placeHolders = notificationDao.sendNotificationToBeneficiary(application, NotificationTypeEnum.EVALUATION_CREATION);
|
// 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<>();
|
Map<String, String> placeHolders = new HashMap<>();
|
||||||
placeHolders.put("{{call_name}}", application.getCall().getName());
|
placeHolders.put("{{call_name}}", application.getCall().getName());
|
||||||
String protocolNumber=application.getProtocol().getExternalProtocolNumber();
|
String protocolNumber=application.getProtocol().getExternalProtocolNumber();
|
||||||
@@ -2190,6 +2207,118 @@ public class ApplicationEvaluationDao {
|
|||||||
return response;
|
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) {
|
private ApplicationEvaluationFormEntity getApplicationEvaluationFormOrCreate(EvaluationFormEntity evaluationFormEntity, ApplicationEvaluationEntity applicationEvaluationEntity) {
|
||||||
|
|
||||||
ApplicationEvaluationFormEntity applicationEvaluationFormEntity = applicationEvaluationFormRepository.findByEvaluationIdAndEvaluationFormId(applicationEvaluationEntity.getId(), evaluationFormEntity.getId());
|
ApplicationEvaluationFormEntity applicationEvaluationFormEntity = applicationEvaluationFormRepository.findByEvaluationIdAndEvaluationFormId(applicationEvaluationEntity.getId(), evaluationFormEntity.getId());
|
||||||
|
|||||||
@@ -77,6 +77,9 @@ spring.rabbitmq.connection-timeout=120000
|
|||||||
app.bandi.login.url.suffix=/loginadmin
|
app.bandi.login.url.suffix=/loginadmin
|
||||||
app.confidi.login.url.suffix=/confidi
|
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
|
#sviluppumbria protocol
|
||||||
codAoo=SVILUMBRIA-01
|
codAoo=SVILUMBRIA-01
|
||||||
sviluppumbria.username=protocollatoresvilumbria
|
sviluppumbria.username=protocollatoresvilumbria
|
||||||
|
|||||||
Reference in New Issue
Block a user